summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-08-31 08:06:05 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-08-31 08:06:05 +0000
commitf078f28b88cc3c4a69b29ba2d8f0c15a73423466 (patch)
tree181ffbb0980ee9a1004cac179a8f90b1be94662c
parent8b23f4d001c24faf274800795d43ad45a18314ce (diff)
parent3ac6728f7a14714f5df47795b47f02d48c92503e (diff)
downloaddevice_google_contexthub-f078f28b88cc3c4a69b29ba2d8f0c15a73423466.tar.gz
device_google_contexthub-f078f28b88cc3c4a69b29ba2d8f0c15a73423466.tar.bz2
device_google_contexthub-f078f28b88cc3c4a69b29ba2d8f0c15a73423466.zip
release-request-48587b2e-b0d9-4e33-ae5f-05bd16bc9d6f-for-git_pi-release-4308806 snap-temp-L91400000098269614
Change-Id: I15daef50ec90023f8b2465b891f5120cb028b200
-rw-r--r--contexthubhal/nanohubhal.h6
-rw-r--r--contexthubhal/system_comms.cpp19
-rw-r--r--contexthubhal/system_comms.h2
-rw-r--r--firmware/app/chre/chre.mk5
-rw-r--r--firmware/app/chre/chre10.mk33
-rw-r--r--firmware/app/chre/chre_test0.app/main.c10
-rw-r--r--firmware/app/chre/chre_test1.app/main.cpp10
-rw-r--r--firmware/app/chre/chre_test2.app/Android.mk31
-rw-r--r--firmware/app/chre/chre_test2.app/Makefile38
-rw-r--r--firmware/app/chre/chre_test2.app/main.cpp139
-rw-r--r--firmware/app/chre/common/chre10_app.c295
-rw-r--r--firmware/app/chre/common/chre10_app_syscalls.c145
-rw-r--r--firmware/app/chre/common/chre_app.c45
-rw-r--r--firmware/app/chre/common/chre_app_syscalls.c111
-rw-r--r--firmware/build/app_chre_executable.mk4
-rw-r--r--firmware/build/app_config.mk2
-rw-r--r--firmware/build/config_internal.mk2
-rw-r--r--firmware/firmware.mk1
-rw-r--r--firmware/os/core/appSec.c14
-rw-r--r--firmware/os/core/nanohubCommand.c71
-rw-r--r--firmware/os/core/nanohub_chre.c289
-rw-r--r--firmware/os/core/osApi.c1
-rw-r--r--firmware/os/core/sensors.c14
-rw-r--r--firmware/os/core/seos.c171
-rw-r--r--firmware/os/core/timer.c32
-rw-r--r--firmware/os/drivers/bosch_bmi160/bosch_bmi160.c25
-rw-r--r--firmware/os/inc/chreApi.h48
-rw-r--r--firmware/os/inc/eventnums.h21
-rw-r--r--firmware/os/inc/nanohubCommand.h1
-rw-r--r--firmware/os/inc/osApi.h6
-rw-r--r--firmware/os/inc/sensors.h2
-rw-r--r--firmware/os/inc/seos.h14
-rw-r--r--firmware/os/inc/seos_priv.h17
-rw-r--r--inc/chre.h161
-rw-r--r--inc/chre/event.h273
-rw-r--r--inc/chre/nanoapp.h90
-rw-r--r--inc/chre/re.h329
-rw-r--r--inc/chre/sensor.h817
-rw-r--r--inc/chre/version.h129
-rw-r--r--lib/include/nanohub/nanohub.h15
-rw-r--r--util/nanoapp_postprocess/postprocess_elf.c22
41 files changed, 1489 insertions, 1971 deletions
diff --git a/contexthubhal/nanohubhal.h b/contexthubhal/nanohubhal.h
index 68446e46..6a0432c8 100644
--- a/contexthubhal/nanohubhal.h
+++ b/contexthubhal/nanohubhal.h
@@ -37,7 +37,7 @@ namespace nanohub {
void dumpBuffer(const char *pfx, const hub_app_name_t &appId, uint32_t evtId, const void *data, size_t len, int status = 0);
struct nano_message_chre {
- HostMsgHdrChre hdr;
+ HostMsgHdrChreV10 hdr;
uint8_t data[MAX_RX_PACKET];
} __attribute__((packed));
@@ -115,7 +115,7 @@ class NanoHub {
int doSubscribeMessages(uint32_t hub_id, context_hub_callback *cbk, void *cookie);
int doSendToNanohub(uint32_t hub_id, const hub_message_t *msg);
- int doSendToDevice(const hub_app_name_t name, const void *data, uint32_t len, uint32_t messageType);
+ int doSendToDevice(const hub_app_name_t name, const void *data, uint32_t len, uint32_t messageType = 0);
void doSendToApp(HubMessage &&msg);
static constexpr unsigned int FL_MESSAGE_TRACING = 1;
@@ -148,7 +148,7 @@ public:
}
// passes message to kernel driver directly
static int sendToDevice(const hub_app_name_t *name, const void *data, uint32_t len) {
- return hubInstance()->doSendToDevice(*name, data, len, 0);
+ return hubInstance()->doSendToDevice(*name, data, len);
}
// passes message to APP via callback
static void sendToApp(HubMessage &&msg) {
diff --git a/contexthubhal/system_comms.cpp b/contexthubhal/system_comms.cpp
index 4a67a669..b0e4bc9b 100644
--- a/contexthubhal/system_comms.cpp
+++ b/contexthubhal/system_comms.cpp
@@ -90,7 +90,10 @@ NanohubRsp::NanohubRsp(MessageBuf &buf, bool no_status)
} else if (no_status) {
status = 0;
} else {
- status = buf.readU32();
+ if (cmd == NANOHUB_START_UPLOAD || cmd == NANOHUB_CONT_UPLOAD || cmd == NANOHUB_FINISH_UPLOAD)
+ status = buf.readU8();
+ else
+ status = buf.readU32();
}
}
@@ -273,6 +276,8 @@ int SystemComm::AppMgmtSession::setup(const hub_message_t *appMsg)
mCmd = appMsg->message_type;
mLen = appMsg->message_len;
mPos = 0;
+ mNextPos = 0;
+ mErrCnt = 0;
switch (mCmd) {
case CONTEXT_HUB_APPS_ENABLE:
@@ -361,10 +366,20 @@ int SystemComm::AppMgmtSession::handleTransfer(NanohubRsp &rsp)
char data[MAX_RX_PACKET];
MessageBuf buf(data, sizeof(data));
+ const bool success = rsp.status != 0;
static_assert(NANOHUB_UPLOAD_CHUNK_SZ_MAX <= (MAX_RX_PACKET-5),
"Invalid chunk size");
+ if (success) {
+ mPos = mNextPos;
+ mErrCnt = 0;
+ } else if (mErrCnt > 5) {
+ mPos = mLen;
+ } else {
+ mErrCnt ++;
+ }
+
if (mPos < mLen) {
uint32_t chunkSize = mLen - mPos;
@@ -375,7 +390,7 @@ int SystemComm::AppMgmtSession::handleTransfer(NanohubRsp &rsp)
buf.writeU8(NANOHUB_CONT_UPLOAD);
buf.writeU32(mPos);
buf.writeRaw(&mData[mPos], chunkSize);
- mPos += chunkSize;
+ mNextPos = mPos + chunkSize;
} else {
buf.writeU8(NANOHUB_FINISH_UPLOAD);
setState(FINISH);
diff --git a/contexthubhal/system_comms.h b/contexthubhal/system_comms.h
index e1b08e3e..6991457e 100644
--- a/contexthubhal/system_comms.h
+++ b/contexthubhal/system_comms.h
@@ -204,6 +204,8 @@ private:
std::vector<uint8_t> mData;
uint32_t mLen;
uint32_t mPos;
+ uint32_t mNextPos;
+ uint32_t mErrCnt;
hub_app_name_t mAppName;
int setupMgmt(const hub_message_t *appMsg, uint32_t cmd);
diff --git a/firmware/app/chre/chre.mk b/firmware/app/chre/chre.mk
index a1476771..aed3ce78 100644
--- a/firmware/app/chre/chre.mk
+++ b/firmware/app/chre/chre.mk
@@ -21,12 +21,13 @@
SRCS += $(NANOHUB_DIR)/app/chre/common/chre_app.c
SRCS += $(NANOHUB_DIR)/app/chre/common/chre_app_syscalls.c
-CFLAGS += -I$(NANOHUB_DIR)/../inc
include $(NANOHUB_DIR)/firmware_conf.mk
CFLAGS += $(COMMON_FLAGS)
-BIN_POSTPROCESS_ARGS := -f 0x10
+# CHRE API 1.1
+BIN_POSTPROCESS_ARGS := -c 0x0101
+CFLAGS += -I$(NANOHUB_DIR)/../../../../system/chre/chre_api/include/chre_api
include $(NANOHUB_DIR)/app/app.mk
diff --git a/firmware/app/chre/chre10.mk b/firmware/app/chre/chre10.mk
new file mode 100644
index 00000000..f09d1849
--- /dev/null
+++ b/firmware/app/chre/chre10.mk
@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+#
+# NanoApp C/C++ Makefile Utils
+#
+################################################################################
+
+SRCS += $(NANOHUB_DIR)/app/chre/common/chre10_app.c
+SRCS += $(NANOHUB_DIR)/app/chre/common/chre10_app_syscalls.c
+
+include $(NANOHUB_DIR)/firmware_conf.mk
+
+CFLAGS += $(COMMON_FLAGS)
+
+# CHRE API 1.0
+BIN_POSTPROCESS_ARGS := -c 0x0100
+CFLAGS += -I$(NANOHUB_DIR)/../../../../system/chre/chre_api/legacy/v1_0
+
+include $(NANOHUB_DIR)/app/app.mk
diff --git a/firmware/app/chre/chre_test0.app/main.c b/firmware/app/chre/chre_test0.app/main.c
index acdba524..03e6d8d8 100644
--- a/firmware/app/chre/chre_test0.app/main.c
+++ b/firmware/app/chre/chre_test0.app/main.c
@@ -39,7 +39,7 @@ static const uint64_t kOneSecond = UINT64_C(1000000000); // in nanoseconds
static uint32_t mMyTid;
static uint64_t mMyAppId;
-static int cnt;
+static int mCnt;
static struct MyTimer mTimer;
static void nanoappFreeEvent(uint16_t eventType, void *data)
@@ -60,7 +60,7 @@ bool nanoappStart(void)
{
mMyAppId = chreGetAppId();
mMyTid = chreGetInstanceId();
- cnt = 3;
+ mCnt = 3;
chreSendEvent(EVT_LOCAL_SETUP, (void*)0x87654321, nanoappFreeEvent, mMyTid);
chreLog(CHRE_LOG_INFO, CHRE_APP_TAG "init\n");
return true;
@@ -86,11 +86,11 @@ void nanoappHandleEvent(uint32_t srcTid, uint16_t evtType, const void* evtData)
chreLog(CHRE_LOG_INFO, CHRE_APP_TAG "received timer %" PRIu32
" (TIME: %" PRIu64
- ") cnt: %d\n", t->timerId, chreGetTime(), cnt);
+ ") cnt: %d\n", t->timerId, chreGetTime(), mCnt);
extMsg->msg = 0x01;
- extMsg->val = cnt;
+ extMsg->val = mCnt;
chreSendMessageToHost(extMsg, sizeof(*extMsg), 0, nanoappFreeMessage);
- if (cnt-- <= 0)
+ if (mCnt-- <= 0)
chreTimerCancel(t->timerId);
break;
}
diff --git a/firmware/app/chre/chre_test1.app/main.cpp b/firmware/app/chre/chre_test1.app/main.cpp
index 22a33ce6..201448a9 100644
--- a/firmware/app/chre/chre_test1.app/main.cpp
+++ b/firmware/app/chre/chre_test1.app/main.cpp
@@ -39,7 +39,7 @@ static const uint64_t kOneSecond = UINT64_C(1000000000); // in nanoseconds
static uint32_t mMyTid;
static uint64_t mMyAppId;
-static int cnt;
+static int mCnt;
static struct MyTimer mTimer;
// Default implementation for message free
@@ -52,7 +52,7 @@ bool nanoappStart(void)
{
mMyAppId = chreGetAppId();
mMyTid = chreGetInstanceId();
- cnt = 3;
+ mCnt = 3;
chreSendEvent(EVT_LOCAL_SETUP, NULL, NULL, mMyTid);
chreLog(CHRE_LOG_INFO, APP_LABEL "init");
return true;
@@ -99,11 +99,11 @@ void nanoappHandleEvent(uint32_t srcTid, uint16_t evtType, const void* evtData)
chreLog(CHRE_LOG_INFO, APP_LABEL "received timer %" PRIu32
" (TIME: %" PRIu64
- ") cnt: %d\n", t->timerId, chreGetTime(), cnt);
+ ") cnt: %d\n", t->timerId, chreGetTime(), mCnt);
extMsg->msg = 0x01;
- extMsg->val = cnt;
+ extMsg->val = mCnt;
chreSendMessageToHost(extMsg, sizeof(*extMsg), 0, nanoappFreeMessage);
- if (cnt-- <= 0)
+ if (mCnt-- <= 0)
chreTimerCancel(t->timerId);
break;
}
diff --git a/firmware/app/chre/chre_test2.app/Android.mk b/firmware/app/chre/chre_test2.app/Android.mk
new file mode 100644
index 00000000..0a471f19
--- /dev/null
+++ b/firmware/app/chre/chre_test2.app/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_NANO_VARS)
+
+LOCAL_MODULE := chre_test2
+LOCAL_MODULE_TAGS := optional
+
+# Googl + T + 0x9002
+LOCAL_NANO_APP_ID := 476f6f676c549002
+LOCAL_NANO_APP_VERSION := 0
+
+LOCAL_SRC_FILES := \
+ main.cpp \
+
+include $(BUILD_NANOHUB_APP_CHRE_EXECUTABLE)
diff --git a/firmware/app/chre/chre_test2.app/Makefile b/firmware/app/chre/chre_test2.app/Makefile
new file mode 100644
index 00000000..45819ffa
--- /dev/null
+++ b/firmware/app/chre/chre_test2.app/Makefile
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+################################################################################
+#
+# test NanoApp Makefile
+#
+################################################################################
+
+
+SRCS := main.cpp
+BIN := chre_test2
+APP_ID := 476f6f676c549002
+APP_VERSION := 0
+
+# Nanohub relative path
+NANOHUB_DIR := ../../..
+
+# Device configuration #########################################################
+
+# select device variant for this app
+TARGET_PRODUCT ?= nucleo
+VARIANT := $(TARGET_PRODUCT)
+
+include $(NANOHUB_DIR)/app/chre/chre.mk
diff --git a/firmware/app/chre/chre_test2.app/main.cpp b/firmware/app/chre/chre_test2.app/main.cpp
new file mode 100644
index 00000000..427221fb
--- /dev/null
+++ b/firmware/app/chre/chre_test2.app/main.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <inttypes.h>
+#include <chre.h>
+
+#define APP_LABEL "CHRE App 2: "
+
+/* chre.h does not define printf format attribute for chreLog() */
+void chreLog(enum chreLogLevel level, const char *str, ...) __attribute__ ((__format__ (__printf__, 2, 3)));
+
+#define EVT_LOCAL_SETUP CHRE_EVENT_FIRST_USER_VALUE
+
+struct MyTimer {
+ uint64_t startTime;
+ uint32_t timerId;
+};
+
+struct ExtMsg
+{
+ uint8_t msg;
+ uint32_t val;
+} __attribute__((packed));
+
+static const uint64_t kOneSecond = UINT64_C(1000000000); // in nanoseconds
+
+static uint32_t mMyTid;
+static uint64_t mMyAppId;
+static int mCnt;
+static struct MyTimer mTimer;
+
+bool nanoappStart(void)
+{
+ mMyAppId = chreGetAppId();
+ mMyTid = chreGetInstanceId();
+ mCnt = 3;
+ chreSendEvent(EVT_LOCAL_SETUP, NULL, NULL, mMyTid);
+ chreLog(CHRE_LOG_INFO, APP_LABEL "init: offset: %" PRId64, chreGetEstimatedHostTimeOffset());
+ chreConfigureNanoappInfoEvents(true);
+ return true;
+}
+
+void nanoappEnd(void)
+{
+ chreLog(CHRE_LOG_INFO, APP_LABEL "terminating");
+}
+
+void nanoappHandleEvent(uint32_t srcTid, uint16_t evtType, const void* evtData)
+{
+ switch (evtType) {
+ case EVT_LOCAL_SETUP:
+ {
+ uint32_t instanceId = chreGetInstanceId();
+ uint64_t appId = chreGetAppId();
+ struct chreNanoappInfo info;
+
+ mTimer.startTime = chreGetTime();
+ mTimer.timerId = chreTimerSet(kOneSecond, &mTimer, false);
+ chreLog(CHRE_LOG_INFO, APP_LABEL "started with tid %04" PRIX32
+ " timerid %" PRIu32
+ "\n", mMyTid, mTimer.timerId);
+ chreLog(CHRE_LOG_INFO, APP_LABEL "appId=%016llx; instanceId=%ld",
+ appId, instanceId);
+ if (chreGetNanoappInfoByInstanceId(instanceId, &info)) {
+ chreLog(CHRE_LOG_INFO, APP_LABEL "info by instanceId; appId=%08llx; version=%ld; instanceId=%ld",
+ info.appId, info.version, info.instanceId);
+ } else {
+ chreLog(CHRE_LOG_INFO, APP_LABEL "error getting info by instance id");
+ }
+ if (chreGetNanoappInfoByAppId(appId, &info)) {
+ chreLog(CHRE_LOG_INFO, APP_LABEL "info by appId; appId=%08llx; version=%ld; instanceId=%ld",
+ info.appId, info.version, info.instanceId);
+ } else {
+ chreLog(CHRE_LOG_INFO, APP_LABEL "error getting info by app id");
+ }
+ break;
+ }
+ case CHRE_EVENT_TIMER:
+ {
+ const struct MyTimer *t = (const struct MyTimer *)evtData;
+
+ chreLog(CHRE_LOG_INFO, APP_LABEL "received timer %" PRIu32
+ " (START: %" PRIu64 " TIME: %" PRIu64 " OFFSET: %" PRId64
+ ") cnt: %d\n", t->timerId, t->startTime, chreGetTime(),
+ chreGetEstimatedHostTimeOffset(), mCnt);
+ if (mCnt-- <= 0) {
+ chreTimerCancel(t->timerId);
+ chreAbort(0x0001);
+ chreAbort(0x0002);
+ }
+ break;
+ }
+ case CHRE_EVENT_MESSAGE_FROM_HOST:
+ {
+ const struct chreMessageFromHostData *msg = (const struct chreMessageFromHostData *)evtData;
+ const uint8_t *data = (const uint8_t *)msg->message;
+ const size_t size = msg->messageSize;
+ const uint32_t type = msg->messageType;
+ const uint16_t endpoint = msg->hostEndpoint;
+ chreLog(CHRE_LOG_INFO, APP_LABEL "message=%p; code=%d; size=%zu; type=%ld; endpoint=%d",
+ data, (data && size) ? data[0] : 0, size, type, endpoint);
+ break;
+ }
+ case CHRE_EVENT_NANOAPP_STARTED:
+ {
+ const struct chreNanoappInfo *msg = (const struct chreNanoappInfo *)evtData;
+ const uint64_t appId = msg->appId;
+ const uint32_t version = msg->version;
+ const uint32_t instanceId = msg->instanceId;
+ chreLog(CHRE_LOG_INFO, APP_LABEL "app started; appId=%08llx; version=%ld; instanceId=%ld",
+ appId, version, instanceId);
+ break;
+ }
+ case CHRE_EVENT_NANOAPP_STOPPED:
+ {
+ const struct chreNanoappInfo *msg = (const struct chreNanoappInfo *)evtData;
+ const uint64_t appId = msg->appId;
+ const uint32_t version = msg->version;
+ const uint32_t instanceId = msg->instanceId;
+ chreLog(CHRE_LOG_INFO, APP_LABEL "app stopped; appId=%08llx; version=%ld; instanceId=%ld",
+ appId, version, instanceId);
+ break;
+ }
+ }
+}
diff --git a/firmware/app/chre/common/chre10_app.c b/firmware/app/chre/common/chre10_app.c
new file mode 100644
index 00000000..55bbdf2f
--- /dev/null
+++ b/firmware/app/chre/common/chre10_app.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <eventnums.h>
+#include <seos.h>
+#include <timer.h>
+#include <toolchain.h>
+#include <crt_priv.h>
+#include <string.h>
+
+#include <chre.h>
+#include <sensors.h>
+#include <syscallDo.h>
+#include <hostIntf.h>
+
+#define SENSOR_TYPE(x) ((x) & 0xFF)
+
+/*
+ * Common CHRE App support code
+ */
+
+static bool chreappStart(uint32_t tid)
+{
+ __crt_init();
+ return nanoappStart();
+}
+
+static void chreappEnd(void)
+{
+ nanoappEnd();
+ __crt_exit();
+}
+
+static void initDataHeader(struct chreSensorDataHeader *header, uint64_t timestamp, uint32_t sensorHandle) {
+ header->baseTimestamp = timestamp;
+ header->sensorHandle = sensorHandle;
+ header->readingCount = 1;
+ header->reserved[0] = header->reserved[1] = 0;
+}
+
+static void processTripleAxisData(const struct TripleAxisDataEvent *src, uint32_t sensorHandle, uint8_t sensorType)
+{
+ int i;
+ struct chreSensorThreeAxisData three;
+
+ initDataHeader(&three.header, src->referenceTime, sensorHandle);
+ three.readings[0].timestampDelta = 0;
+
+ for (i=0; i<src->samples[0].firstSample.numSamples; i++) {
+ if (i > 0)
+ three.header.baseTimestamp += src->samples[i].deltaTime;
+ three.readings[0].x = src->samples[i].x;
+ three.readings[0].y = src->samples[i].y;
+ three.readings[0].z = src->samples[i].z;
+
+ nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_DATA_EVENT_BASE | sensorType, &three);
+ }
+}
+
+static void processSingleAxisData(const struct SingleAxisDataEvent *src, uint32_t sensorHandle, uint8_t sensorType)
+{
+ int i;
+
+ switch (sensorType) {
+ case CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT:
+ case CHRE_SENSOR_TYPE_STATIONARY_DETECT: {
+ struct chreSensorOccurrenceData occ;
+
+ initDataHeader(&occ.header, src->referenceTime, sensorHandle);
+ occ.readings[0].timestampDelta = 0;
+
+ for (i=0; i<src->samples[0].firstSample.numSamples; i++) {
+ if (i > 0)
+ occ.header.baseTimestamp += src->samples[i].deltaTime;
+
+ nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_DATA_EVENT_BASE | sensorType, &occ);
+ }
+ break;
+ }
+ case CHRE_SENSOR_TYPE_LIGHT:
+ case CHRE_SENSOR_TYPE_PRESSURE: {
+ struct chreSensorFloatData flt;
+
+ initDataHeader(&flt.header, src->referenceTime, sensorHandle);
+ flt.readings[0].timestampDelta = 0;
+
+ for (i=0; i<src->samples[0].firstSample.numSamples; i++) {
+ if (i > 0)
+ flt.header.baseTimestamp += src->samples[i].deltaTime;
+ flt.readings[0].value = src->samples[i].fdata;
+
+ nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_DATA_EVENT_BASE | sensorType, &flt);
+ }
+ break;
+ }
+ case CHRE_SENSOR_TYPE_PROXIMITY: {
+ struct chreSensorByteData byte;
+
+ initDataHeader(&byte.header, src->referenceTime, sensorHandle);
+ byte.readings[0].timestampDelta = 0;
+
+ for (i=0; i<src->samples[0].firstSample.numSamples; i++) {
+ if (i > 0)
+ byte.header.baseTimestamp += src->samples[i].deltaTime;
+ byte.readings[0].isNear = src->samples[i].fdata == 0.0f;
+ byte.readings[0].invalid = false;
+ byte.readings[0].padding0 = 0;
+
+ nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_DATA_EVENT_BASE | sensorType, &byte);
+ }
+ break;
+ }
+ }
+}
+
+static void processEmbeddedData(const void *src, uint32_t sensorHandle, uint8_t sensorType)
+{
+ union EmbeddedDataPoint data = (union EmbeddedDataPoint)((void *)src);
+
+ switch (sensorType) {
+ case CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT:
+ case CHRE_SENSOR_TYPE_STATIONARY_DETECT: {
+ struct chreSensorOccurrenceData occ;
+
+ initDataHeader(&occ.header, eOsSensorGetTime(), sensorHandle);
+ occ.readings[0].timestampDelta = 0;
+
+ nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_DATA_EVENT_BASE | sensorType, &occ);
+ break;
+ }
+ case CHRE_SENSOR_TYPE_LIGHT:
+ case CHRE_SENSOR_TYPE_PRESSURE: {
+ struct chreSensorFloatData flt;
+
+ initDataHeader(&flt.header, eOsSensorGetTime(), sensorHandle);
+ flt.readings[0].timestampDelta = 0;
+ flt.readings[0].value = data.fdata;
+
+ nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_DATA_EVENT_BASE | sensorType, &flt);
+ break;
+ }
+ case CHRE_SENSOR_TYPE_PROXIMITY: {
+ struct chreSensorByteData byte;
+
+ initDataHeader(&byte.header, eOsSensorGetTime(), sensorHandle);
+ byte.readings[0].timestampDelta = 0;
+ byte.readings[0].isNear = data.fdata == 0.0f;
+ byte.readings[0].invalid = false;
+ byte.readings[0].padding0 = 0;
+
+ nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_DATA_EVENT_BASE | sensorType, &byte);
+ break;
+ }
+ }
+}
+
+static void chreappProcessSensorData(uint16_t evt, const void *eventData)
+{
+ const struct SensorInfo *si;
+ uint32_t sensorHandle;
+
+ if (eventData == SENSOR_DATA_EVENT_FLUSH)
+ return;
+
+ si = eOsSensorFind(SENSOR_TYPE(evt), 0, &sensorHandle);
+ if (si && eOsSensorGetReqRate(sensorHandle)) {
+ switch (si->numAxis) {
+ case NUM_AXIS_EMBEDDED:
+ processEmbeddedData(eventData, sensorHandle, SENSOR_TYPE(evt));
+ break;
+ case NUM_AXIS_ONE:
+ processSingleAxisData(eventData, sensorHandle, SENSOR_TYPE(evt));
+ break;
+ case NUM_AXIS_THREE:
+ processTripleAxisData(eventData, sensorHandle, SENSOR_TYPE(evt));
+ break;
+ }
+
+ if (SENSOR_TYPE(evt) == CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT
+ || SENSOR_TYPE(evt) == CHRE_SENSOR_TYPE_STATIONARY_DETECT) {
+ // one-shot, disable after receiving sample
+ chreSensorConfigure(sensorHandle, CHRE_SENSOR_CONFIGURE_MODE_DONE, CHRE_SENSOR_INTERVAL_DEFAULT, CHRE_SENSOR_LATENCY_DEFAULT);
+ }
+ }
+}
+
+static void chreappProcessConfigEvt(uint16_t evt, const void *eventData)
+{
+ const struct SensorRateChangeEvent *msg = eventData;
+ struct chreSensorSamplingStatusEvent change;
+
+ change.sensorHandle = msg->sensorHandle;
+ if (!msg->newRate) {
+ change.status.enabled = 0;
+ change.status.interval = 0;
+ change.status.latency = 0;
+ } else {
+ change.status.enabled = true;
+ if (msg->newRate == SENSOR_RATE_ONDEMAND
+ || msg->newRate == SENSOR_RATE_ONCHANGE
+ || msg->newRate == SENSOR_RATE_ONESHOT)
+ change.status.interval = CHRE_SENSOR_INTERVAL_DEFAULT;
+ else
+ change.status.interval = (UINT32_C(1024000000) / msg->newRate) * UINT64_C(1000);
+
+ if (msg->newLatency == SENSOR_LATENCY_NODATA)
+ change.status.latency = CHRE_SENSOR_INTERVAL_DEFAULT;
+ else
+ change.status.latency = msg->newLatency;
+ }
+
+ nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_SAMPLING_CHANGE, &change);
+}
+
+static void chreappHandle(uint32_t eventTypeAndTid, const void *eventData)
+{
+ uint16_t evt = eventTypeAndTid;
+ uint16_t srcTid = eventTypeAndTid >> 16;
+ const void *data = eventData;
+
+ union EventLocalData {
+ struct chreMessageFromHostData msg;
+ } u;
+
+ switch(evt) {
+ case EVT_APP_TIMER:
+ evt = CHRE_EVENT_TIMER;
+ data = ((struct TimerEvent *)eventData)->data;
+ break;
+ case EVT_APP_FROM_HOST:
+ srcTid = CHRE_INSTANCE_ID;
+ evt = CHRE_EVENT_MESSAGE_FROM_HOST;
+ data = &u.msg;
+ u.msg.message = (uint8_t*)eventData + 1;
+ u.msg.reservedMessageType = 0;
+ u.msg.messageSize = *(uint8_t*)eventData;
+ break;
+ case EVT_APP_FROM_HOST_CHRE:
+ {
+ const struct NanohubMsgChreHdr *hdr = eventData;
+ srcTid = CHRE_INSTANCE_ID;
+ evt = CHRE_EVENT_MESSAGE_FROM_HOST;
+ data = &u.msg;
+ u.msg.message = hdr + 1;
+ u.msg.reservedMessageType = hdr->appEvent;
+ u.msg.messageSize = hdr->size;
+ break;
+ }
+ case EVT_APP_SENSOR_SELF_TEST:
+ case EVT_APP_SENSOR_MARSHALL:
+ case EVT_APP_SENSOR_SEND_ONE_DIR_EVT:
+ case EVT_APP_SENSOR_CFG_DATA:
+ case EVT_APP_SENSOR_CALIBRATE:
+ case EVT_APP_SENSOR_TRIGGER:
+ case EVT_APP_SENSOR_FLUSH:
+ case EVT_APP_SENSOR_SET_RATE:
+ case EVT_APP_SENSOR_FW_UPLD:
+ case EVT_APP_SENSOR_POWER:
+ // sensor events; pass through
+ break;
+ default:
+ // ignore any other system events; OS may send them to any app
+ if (evt < EVT_NO_FIRST_USER_EVENT)
+ return;
+ else if (evt > EVT_NO_FIRST_SENSOR_EVENT && evt < EVT_NO_SENSOR_CONFIG_EVENT) {
+ return chreappProcessSensorData(evt, data);
+ } else if (evt > EVT_NO_SENSOR_CONFIG_EVENT && evt < EVT_APP_START) {
+ return chreappProcessConfigEvt(evt, data);
+ }
+ }
+ nanoappHandleEvent(srcTid, evt, data);
+}
+
+// Collect entry points
+const struct AppFuncs SET_EXTERNAL_APP_ATTRIBUTES(used, section (".app_init"),visibility("default")) _mAppFuncs = {
+ .init = chreappStart,
+ .end = chreappEnd,
+ .handle = chreappHandle,
+};
+
+// declare version for compatibility with current runtime
+const uint32_t SET_EXTERNAL_APP_VERSION(used, section (".app_version"), visibility("default")) _mAppVer = 0;
diff --git a/firmware/app/chre/common/chre10_app_syscalls.c b/firmware/app/chre/common/chre10_app_syscalls.c
new file mode 100644
index 00000000..666bdaed
--- /dev/null
+++ b/firmware/app/chre/common/chre10_app_syscalls.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdarg.h>
+
+#include <gpio.h>
+#include <osApi.h>
+#include <sensors.h>
+#include <seos.h>
+#include <util.h>
+
+/* CHRE syscalls */
+#include <chre.h>
+#include <chreApi.h>
+#include <syscall.h>
+#include <syscall_defs.h>
+
+#define SYSCALL_CHRE_API(name) \
+ SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_MAIN, SYSCALL_CHRE_MAIN_API, SYSCALL_CHRE_MAIN_API_ ## name)
+
+uint64_t chreGetAppId(void)
+{
+ uint64_t appId = 0;
+ (void)syscallDo1P(SYSCALL_CHRE_API(GET_APP_ID), &appId);
+ return appId;
+}
+
+uint32_t chreGetInstanceId(void)
+{
+ return syscallDo0P(SYSCALL_CHRE_API(GET_INST_ID));
+}
+
+uint64_t chreGetTime(void) {
+ uint64_t time_ns = 0;
+ (void)syscallDo1P(SYSCALL_CHRE_API(GET_TIME), &time_ns);
+ return time_ns;
+}
+
+void chreLog(enum chreLogLevel level, const char *str, ...)
+{
+ va_list vl;
+
+ va_start(vl, str);
+ (void)syscallDo3P(SYSCALL_CHRE_API(LOG), level, str, VA_LIST_TO_INTEGER(vl));
+ va_end(vl);
+}
+
+uint32_t chreTimerSet(uint64_t duration, const void* cookie, bool oneShot)
+{
+ uint32_t dur_lo = duration;
+ uint32_t dur_hi = duration >> 32;
+ return syscallDo4P(SYSCALL_CHRE_API(TIMER_SET), dur_lo, dur_hi, cookie, oneShot);
+}
+
+bool chreTimerCancel(uint32_t timerId)
+{
+ return syscallDo1P(SYSCALL_CHRE_API(TIMER_CANCEL), timerId);
+}
+
+void chreAbort(uint32_t abortCode)
+{
+ (void)syscallDo1P(SYSCALL_CHRE_API(ABORT), abortCode);
+}
+
+void* chreHeapAlloc(uint32_t bytes)
+{
+ return (void *)syscallDo1P(SYSCALL_CHRE_API(HEAP_ALLOC), bytes);
+}
+
+void chreHeapFree(void* ptr)
+{
+ (void)syscallDo1P(SYSCALL_CHRE_API(HEAP_FREE), ptr);
+}
+
+bool chreSensorFindDefault(uint8_t sensorType, uint32_t *handle)
+{
+ return syscallDo2P(SYSCALL_CHRE_API(SENSOR_FIND_DEFAULT), sensorType, handle);
+}
+
+bool chreGetSensorInfo(uint32_t sensorHandle, struct chreSensorInfo *info)
+{
+ return syscallDo2P(SYSCALL_CHRE_API(SENSOR_GET_INFO), sensorHandle, info);
+}
+
+bool chreGetSensorSamplingStatus(uint32_t sensorHandle,
+ struct chreSensorSamplingStatus *status)
+{
+ return syscallDo2P(SYSCALL_CHRE_API(SENSOR_GET_STATUS), sensorHandle, status);
+}
+
+bool chreSensorConfigure(uint32_t sensorHandle,
+ enum chreSensorConfigureMode mode,
+ uint64_t interval, uint64_t latency)
+{
+ uint32_t interval_lo = interval;
+ uint32_t interval_hi = interval >> 32;
+ uint32_t latency_lo = latency;
+ uint32_t latency_hi = latency >> 32;
+ return syscallDo6P(SYSCALL_CHRE_API(SENSOR_CONFIG), sensorHandle, mode,
+ interval_lo, interval_hi, latency_lo, latency_hi);
+}
+
+bool chreSendEvent(uint16_t eventType, void *eventData,
+ chreEventCompleteFunction *freeCallback,
+ uint32_t targetInstanceId)
+{
+ return syscallDo4P(SYSCALL_CHRE_API(SEND_EVENT), eventType, eventData, freeCallback, targetInstanceId);
+}
+
+bool chreSendMessageToHost(void *message, uint32_t messageSize,
+ uint32_t reservedMessageType,
+ chreMessageFreeFunction *freeCallback)
+{
+ return syscallDo4P(SYSCALL_CHRE_API(SEND_MSG), message, messageSize, reservedMessageType, freeCallback);
+}
+
+uint32_t chreGetApiVersion(void)
+{
+ return syscallDo0P(SYSCALL_CHRE_API(GET_OS_API_VERSION));
+}
+
+uint32_t chreGetVersion(void)
+{
+ return syscallDo0P(SYSCALL_CHRE_API(GET_OS_VERSION));
+}
+
+uint64_t chreGetPlatformId(void)
+{
+ uint64_t plat = 0;
+ (void)syscallDo1P(SYSCALL_CHRE_API(GET_PLATFORM_ID), &plat);
+ return plat;
+}
diff --git a/firmware/app/chre/common/chre_app.c b/firmware/app/chre/common/chre_app.c
index 55bbdf2f..0eba2394 100644
--- a/firmware/app/chre/common/chre_app.c
+++ b/firmware/app/chre/common/chre_app.c
@@ -232,7 +232,8 @@ static void chreappHandle(uint32_t eventTypeAndTid, const void *eventData)
const void *data = eventData;
union EventLocalData {
- struct chreMessageFromHostData msg;
+ struct chreMessageFromHostData msg;
+ struct chreNanoappInfo info;
} u;
switch(evt) {
@@ -245,18 +246,46 @@ static void chreappHandle(uint32_t eventTypeAndTid, const void *eventData)
evt = CHRE_EVENT_MESSAGE_FROM_HOST;
data = &u.msg;
u.msg.message = (uint8_t*)eventData + 1;
- u.msg.reservedMessageType = 0;
+ u.msg.messageType = 0;
u.msg.messageSize = *(uint8_t*)eventData;
+ u.msg.hostEndpoint = CHRE_HOST_ENDPOINT_UNSPECIFIED;
break;
case EVT_APP_FROM_HOST_CHRE:
{
- const struct NanohubMsgChreHdr *hdr = eventData;
+ if (chreGetApiVersion() == CHRE_API_VERSION_1_0) {
+ const struct NanohubMsgChreHdrV10 *hdr = eventData;
+ srcTid = CHRE_INSTANCE_ID;
+ evt = CHRE_EVENT_MESSAGE_FROM_HOST;
+ data = &u.msg;
+ u.msg.message = hdr + 1;
+ u.msg.messageType = hdr->appEvent;
+ u.msg.messageSize = hdr->size;
+ u.msg.hostEndpoint = CHRE_HOST_ENDPOINT_UNSPECIFIED;
+ } else {
+ const struct NanohubMsgChreHdr *hdr = eventData;
+ srcTid = CHRE_INSTANCE_ID;
+ evt = CHRE_EVENT_MESSAGE_FROM_HOST;
+ data = &u.msg;
+ u.msg.message = hdr + 1;
+ u.msg.messageType = hdr->appEvent;
+ u.msg.messageSize = hdr->size;
+ u.msg.hostEndpoint = hdr->endpoint;
+ }
+ break;
+ }
+ case EVT_APP_STARTED:
+ case EVT_APP_STOPPED:
+ {
+ const struct AppEventStartStop *msg = eventData;
srcTid = CHRE_INSTANCE_ID;
- evt = CHRE_EVENT_MESSAGE_FROM_HOST;
- data = &u.msg;
- u.msg.message = hdr + 1;
- u.msg.reservedMessageType = hdr->appEvent;
- u.msg.messageSize = hdr->size;
+ if (evt == EVT_APP_STARTED)
+ evt = CHRE_EVENT_NANOAPP_STARTED;
+ else
+ evt = CHRE_EVENT_NANOAPP_STOPPED;
+ data = &u.info;
+ u.info.appId = msg->appId;
+ u.info.version = msg->version;
+ u.info.instanceId = msg->tid;
break;
}
case EVT_APP_SENSOR_SELF_TEST:
diff --git a/firmware/app/chre/common/chre_app_syscalls.c b/firmware/app/chre/common/chre_app_syscalls.c
index 666bdaed..fc1bc8c3 100644
--- a/firmware/app/chre/common/chre_app_syscalls.c
+++ b/firmware/app/chre/common/chre_app_syscalls.c
@@ -49,6 +49,12 @@ uint64_t chreGetTime(void) {
return time_ns;
}
+int64_t chreGetEstimatedHostTimeOffset(void) {
+ int64_t time_ns = 0;
+ (void)syscallDo1P(SYSCALL_CHRE_API(GET_HOST_TIME_OFFSET), &time_ns);
+ return time_ns;
+}
+
void chreLog(enum chreLogLevel level, const char *str, ...)
{
va_list vl;
@@ -113,33 +119,116 @@ bool chreSensorConfigure(uint32_t sensorHandle,
interval_lo, interval_hi, latency_lo, latency_hi);
}
+uint32_t chreGetApiVersion(void)
+{
+ static uint32_t apiVersion = 0;
+ if (!apiVersion)
+ apiVersion = syscallDo0P(SYSCALL_CHRE_API(GET_OS_API_VERSION));
+ return apiVersion;
+}
+
+uint32_t chreGetVersion(void)
+{
+ return syscallDo0P(SYSCALL_CHRE_API(GET_OS_VERSION));
+}
+
+uint64_t chreGetPlatformId(void)
+{
+ uint64_t plat = 0;
+ (void)syscallDo1P(SYSCALL_CHRE_API(GET_PLATFORM_ID), &plat);
+ return plat;
+}
+
bool chreSendEvent(uint16_t eventType, void *eventData,
chreEventCompleteFunction *freeCallback,
uint32_t targetInstanceId)
{
- return syscallDo4P(SYSCALL_CHRE_API(SEND_EVENT), eventType, eventData, freeCallback, targetInstanceId);
+ if (chreGetApiVersion() == CHRE_API_VERSION_1_0)
+ return syscallDo4P(SYSCALL_CHRE_API(SEND_EVENT), eventType, eventData, freeCallback, targetInstanceId);
+ else
+ return syscallDo4P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_MAIN, SYSCALL_CHRE_MAIN_EVENT, SYSCALL_CHRE_MAIN_EVENT_SEND_EVENT), eventType, eventData, freeCallback, targetInstanceId);
}
bool chreSendMessageToHost(void *message, uint32_t messageSize,
- uint32_t reservedMessageType,
+ uint32_t messageType,
chreMessageFreeFunction *freeCallback)
{
- return syscallDo4P(SYSCALL_CHRE_API(SEND_MSG), message, messageSize, reservedMessageType, freeCallback);
+ if (chreGetApiVersion() == CHRE_API_VERSION_1_0)
+ return syscallDo4P(SYSCALL_CHRE_API(SEND_MSG), message, messageSize, messageType, freeCallback);
+ else
+ return syscallDo5P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_MAIN, SYSCALL_CHRE_MAIN_EVENT, SYSCALL_CHRE_MAIN_EVENT_SEND_MSG), message, messageSize, messageType, CHRE_HOST_ENDPOINT_BROADCAST, freeCallback);
}
-uint32_t chreGetApiVersion(void)
+bool chreSendMessageToHostEndpoint(void *message, size_t messageSize,
+ uint32_t messageType, uint16_t hostEndpoint,
+ chreMessageFreeFunction *freeCallback)
{
- return syscallDo0P(SYSCALL_CHRE_API(GET_OS_API_VERSION));
+ return syscallDo5P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_MAIN, SYSCALL_CHRE_MAIN_EVENT, SYSCALL_CHRE_MAIN_EVENT_SEND_MSG), message, messageSize, messageType, hostEndpoint, freeCallback);
}
-uint32_t chreGetVersion(void)
+bool chreGetNanoappInfoByAppId(uint64_t appId, struct chreNanoappInfo *info)
{
- return syscallDo0P(SYSCALL_CHRE_API(GET_OS_VERSION));
+ uint32_t app_lo = appId;
+ uint32_t app_hi = appId >> 32;
+ return syscallDo3P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_MAIN, SYSCALL_CHRE_MAIN_EVENT, SYSCALL_CHRE_MAIN_EVENT_INFO_BY_APP_ID), app_lo, app_hi, info);
}
-uint64_t chreGetPlatformId(void)
+bool chreGetNanoappInfoByInstanceId(uint32_t instanceId, struct chreNanoappInfo *info)
{
- uint64_t plat = 0;
- (void)syscallDo1P(SYSCALL_CHRE_API(GET_PLATFORM_ID), &plat);
- return plat;
+ return syscallDo2P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_MAIN, SYSCALL_CHRE_MAIN_EVENT, SYSCALL_CHRE_MAIN_EVENT_INFO_BY_INST_ID), instanceId, info);
+}
+
+void chreConfigureNanoappInfoEvents(bool enable)
+{
+ syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_MAIN, SYSCALL_CHRE_MAIN_EVENT, SYSCALL_CHRE_MAIN_EVENT_CFG_INFO), enable);
+}
+
+uint32_t chreGnssGetCapabilities(void)
+{
+ return syscallDo0P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_DRIVERS, SYSCALL_CHRE_DRV_GNSS, SYSCALL_CHRE_DRV_GNSS_GET_CAP));
+}
+
+bool chreGnssLocationSessionStartAsync(uint32_t minIntervalMs, uint32_t minTimeToNextFixMs, const void *cookie)
+{
+ return syscallDo3P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_DRIVERS, SYSCALL_CHRE_DRV_GNSS, SYSCALL_CHRE_DRV_GNSS_LOC_START_ASYNC), minIntervalMs, minTimeToNextFixMs, cookie);
+}
+
+bool chreGnssLocationSessionStopAsync(const void *cookie)
+{
+ return syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_DRIVERS, SYSCALL_CHRE_DRV_GNSS, SYSCALL_CHRE_DRV_GNSS_LOC_STOP_ASYNC), cookie);
+}
+
+bool chreGnssMeasurementSessionStartAsync(uint32_t minIntervalMs, const void *cookie)
+{
+ return syscallDo2P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_DRIVERS, SYSCALL_CHRE_DRV_GNSS, SYSCALL_CHRE_DRV_GNSS_MEAS_START_ASYNC), minIntervalMs, cookie);
+}
+
+bool chreGnssMeasurementSessionStopAsync(const void *cookie)
+{
+ return syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_DRIVERS, SYSCALL_CHRE_DRV_GNSS, SYSCALL_CHRE_DRV_GNSS_MEAS_STOP_ASYNC), cookie);
+}
+
+uint32_t chreWifiGetCapabilities(void)
+{
+ return syscallDo0P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_DRIVERS, SYSCALL_CHRE_DRV_WIFI, SYSCALL_CHRE_DRV_WIFI_GET_CAP));
+}
+
+bool chreWifiConfigureScanMonitorAsync(bool enable, const void *cookie)
+{
+ return syscallDo2P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_DRIVERS, SYSCALL_CHRE_DRV_WIFI, SYSCALL_CHRE_DRV_WIFI_CONF_SCAN_MON_ASYNC), enable, cookie);
+}
+
+bool chreWifiRequestScanAsync(const struct chreWifiScanParams *params, const void *cookie)
+{
+ return syscallDo2P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_DRIVERS, SYSCALL_CHRE_DRV_WIFI, SYSCALL_CHRE_DRV_WIFI_REQ_SCAN_ASYNC), params, cookie);
+}
+
+uint32_t chreWwanGetCapabilities(void)
+{
+ return syscallDo0P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_DRIVERS, SYSCALL_CHRE_DRV_WWAN, SYSCALL_CHRE_DRV_WWAN_GET_CAP));
+}
+
+bool chreWwanGetCellInfoAsync(const void *cookie)
+{
+ return syscallDo1P(SYSCALL_NO(SYSCALL_DOMAIN_CHRE, SYSCALL_CHRE_DRIVERS, SYSCALL_CHRE_DRV_WWAN, SYSCALL_CHRE_DRV_WWAN_GET_CELL_INFO_ASYNC), cookie);
}
diff --git a/firmware/build/app_chre_executable.mk b/firmware/build/app_chre_executable.mk
index 01696993..009dc15c 100644
--- a/firmware/build/app_chre_executable.mk
+++ b/firmware/build/app_chre_executable.mk
@@ -24,8 +24,8 @@ ifeq ($(strip $(my_variants)),)
my_variants := $(AUX_OS_VARIANT_LIST_$(NANO_OS))
endif
-# mark the app as CHRE nanoapp
-LOCAL_NANO_APP_POSTPROCESS_FLAGS += -f 0x10
+# mark the app as CHRE 1.1 nanoapp
+LOCAL_NANO_APP_POSTPROCESS_FLAGS += -c 0x0101
# add app-side CHRE implementation
LOCAL_WHOLE_STATIC_LIBRARIES += \
diff --git a/firmware/build/app_config.mk b/firmware/build/app_config.mk
index 1bb4177d..e7734cfc 100644
--- a/firmware/build/app_config.mk
+++ b/firmware/build/app_config.mk
@@ -27,7 +27,9 @@ LOCAL_OBJCOPY_SECT_cortexm4 := .flash .data .relocs .dynsym
LOCAL_FORCE_STATIC_EXECUTABLE := false
LOCAL_CFLAGS += \
+ -DNANOAPP_ID=0x$(LOCAL_NANO_APP_ID) \
-DAPP_ID=$(LOCAL_NANO_APP_ID) \
+ -DNANOAPP_VERSION=$(LOCAL_NANO_APP_VERSION) \
-DAPP_VERSION=$(LOCAL_NANO_APP_VERSION) \
-D__NANOHUB__ \
diff --git a/firmware/build/config_internal.mk b/firmware/build/config_internal.mk
index 533d38f5..3a015041 100644
--- a/firmware/build/config_internal.mk
+++ b/firmware/build/config_internal.mk
@@ -19,7 +19,7 @@ LOCAL_C_INCLUDES += \
$(NANOHUB_OS_PATH)/os/platform/$(AUX_ARCH)/inc \
$(NANOHUB_OS_PATH)/os/cpu/$(AUX_CPU)/inc \
$(NANOHUB_OS_PATH)/../lib/include \
- $(NANOHUB_OS_PATH)/../inc \
+ system/chre/chre_api/include/chre_api \
LOCAL_WHOLE_STATIC_LIBRARIES_BL += libnanohub_bl_$(AUX_CPU)
LOCAL_WHOLE_STATIC_LIBRARIES_BL += libnanohub_bl_$(AUX_ARCH)
diff --git a/firmware/firmware.mk b/firmware/firmware.mk
index eeda9b1a..246e03ec 100644
--- a/firmware/firmware.mk
+++ b/firmware/firmware.mk
@@ -56,7 +56,6 @@ FLAGS += -Ios/platform/$(PLATFORM)/inc
FLAGS += -I$(VARIANT_PATH)/inc
FLAGS += -Iexternal/freebsd/inc
FLAGS += -I../lib/include
-FLAGS += -I../inc
FLAGS += -Wall -Werror
#help avoid commmon embedded C mistakes
diff --git a/firmware/os/core/appSec.c b/firmware/os/core/appSec.c
index 94cfedac..b1974f0c 100644
--- a/firmware/os/core/appSec.c
+++ b/firmware/os/core/appSec.c
@@ -310,9 +310,21 @@ static AppSecErr appSecProcessIncomingHdr(struct AppSecState *state, uint32_t *n
.fwFlags = image->layout.flags,
.appVer = aosp->app_version,
.payInfoType = image->layout.payload,
- .rfu = { 0xFF, 0xFF },
+ .chreApiMajor = 0xFF,
+ .chreApiMinor = 0xFF,
};
+ if (image->layout.flags & FL_APP_HDR_CHRE) {
+ if (aosp->chre_api_major || aosp->chre_api_minor) {
+ common.chreApiMajor = aosp->chre_api_major;
+ common.chreApiMinor = aosp->chre_api_minor;
+ } else {
+ // fields not defined prior to CHRE 1.1
+ common.chreApiMajor = 0x01;
+ common.chreApiMinor = 0x00;
+ }
+ }
+
// check to see if this is special system types of payload
switch(image->layout.payload) {
case LAYOUT_APP:
diff --git a/firmware/os/core/nanohubCommand.c b/firmware/os/core/nanohubCommand.c
index 439f3dc6..b7611c34 100644
--- a/firmware/os/core/nanohubCommand.c
+++ b/firmware/os/core/nanohubCommand.c
@@ -50,6 +50,8 @@
#include <cpu/cpuMath.h>
#include <algos/ap_hub_sync.h>
+#include <chre.h>
+
#define NANOHUB_COMMAND(_reason, _fastHandler, _handler, _minReqType, _maxReqType) \
{ .reason = _reason, .fastHandler = _fastHandler, .handler = _handler, \
.minDataLen = sizeof(_minReqType), .maxDataLen = sizeof(_maxReqType) }
@@ -563,7 +565,7 @@ static uint32_t doFirmwareChunk(uint8_t *data, uint32_t offset, uint32_t len, vo
if (mDownloadState->erase == true) {
reply = NANOHUB_FIRMWARE_CHUNK_REPLY_WAIT;
if (!mDownloadState->eraseScheduled) {
- ret = osExtAppStopApps(APP_ID_ANY);
+ ret = osExtAppStopAppsByAppId(APP_ID_ANY);
osLog(LOG_INFO, "%s: unloaded apps, ret=%08lx\n", __func__, ret);
mDownloadState->eraseScheduled = osDefer(firmwareErase, NULL, false);
}
@@ -664,12 +666,26 @@ static uint32_t unmaskInterrupt(void *rx, uint8_t rx_len, void *tx, uint64_t tim
return sizeof(*resp);
}
+static void nanohubDelayStartApps(void *cookie)
+{
+ uint32_t status = 0;
+ status = osExtAppStartAppsDelayed();
+ osLog(LOG_DEBUG, "Started delayed apps; EXT status: %08" PRIX32 "\n", status);
+}
+
static void addDelta(struct ApHubSync *sync, uint64_t apTime, uint64_t hubTime)
{
+ static bool delayStart = false;
+
#if DEBUG_APHUB_TIME_SYNC
syncDebugAdd(apTime, hubTime);
#endif
apHubSyncAddDelta(sync, apTime, hubTime);
+
+ if (!delayStart) {
+ delayStart = true;
+ osDefer(nanohubDelayStartApps, NULL, false);
+ }
}
static int64_t getAvgDelta(struct ApHubSync *sync)
@@ -930,13 +946,23 @@ static uint32_t writeEvent(void *rx, uint8_t rx_len, void *tx, uint64_t timestam
}
} else if (event == EVT_APP_FROM_HOST_CHRE) {
// new version of HAL; full support for CHRE apps
+ struct HostMsgHdrChreV10 *hostPacketV10 = rx;
struct HostMsgHdrChre *hostPacket = rx;
if (rx_len >= sizeof(struct HostMsgHdrChre) &&
rx_len == sizeof(struct HostMsgHdrChre) + hostPacket->len &&
osTidById(&hostPacket->appId, &tid)) {
- if (osAppIsChre(tid)) {
+ if (osAppChreVersion(tid) == CHRE_API_VERSION_1_1) {
struct NanohubMsgChreHdr hdr = {
.size = hostPacket->len,
+ .endpoint = hostPacket->endpoint,
+ .appEvent = hostPacket->appEventId,
+ };
+ // CHRE app receives message in new format
+ resp->accepted = forwardPacket(event, hostPacket + 1, hostPacket->len,
+ &hdr, sizeof(hdr), tid);
+ } else if (osAppChreVersion(tid) == CHRE_API_VERSION_1_0) {
+ struct NanohubMsgChreHdrV10 hdr = {
+ .size = hostPacket->len,
.appEvent = hostPacket->appEventId,
};
// CHRE app receives message in new format
@@ -947,6 +973,31 @@ static uint32_t writeEvent(void *rx, uint8_t rx_len, void *tx, uint64_t timestam
resp->accepted = forwardPacket(EVT_APP_FROM_HOST, hostPacket + 1, hostPacket->len,
&hostPacket->len, sizeof(hostPacket->len), tid);
}
+ } else if (rx_len >= sizeof(struct HostMsgHdrChreV10) &&
+ rx_len == sizeof(struct HostMsgHdrChreV10) + hostPacketV10->len &&
+ osTidById(&hostPacketV10->appId, &tid)) {
+ if (osAppChreVersion(tid) == CHRE_API_VERSION_1_1) {
+ struct NanohubMsgChreHdr hdr = {
+ .size = hostPacketV10->len,
+ .endpoint = CHRE_HOST_ENDPOINT_UNSPECIFIED,
+ .appEvent = hostPacketV10->appEventId,
+ };
+ // CHRE app receives message in new format
+ resp->accepted = forwardPacket(event, hostPacketV10 + 1, hostPacketV10->len,
+ &hdr, sizeof(hdr), tid);
+ } else if (osAppChreVersion(tid) == CHRE_API_VERSION_1_0) {
+ struct NanohubMsgChreHdrV10 hdr = {
+ .size = hostPacketV10->len,
+ .appEvent = hostPacketV10->appEventId,
+ };
+ // CHRE app receives message in new format
+ resp->accepted = forwardPacket(event, hostPacketV10 + 1, hostPacketV10->len,
+ &hdr, sizeof(hdr), tid);
+ } else {
+ // legacy app receives message in old format
+ resp->accepted = forwardPacket(EVT_APP_FROM_HOST, hostPacketV10 + 1, hostPacketV10->len,
+ &hostPacketV10->len, sizeof(hostPacketV10->len), tid);
+ }
} else {
resp->accepted = false;
}
@@ -1049,21 +1100,21 @@ static void halExtAppsOn(void *rx, uint8_t rx_len)
{
struct NanohubHalMgmtRx *req = rx;
- halSendMgmtResponse(NANOHUB_HAL_EXT_APPS_ON, osExtAppStartApps(le64toh(unaligned_u64(&req->appId))));
+ halSendMgmtResponse(NANOHUB_HAL_EXT_APPS_ON, osExtAppStartAppsByAppId(le64toh(unaligned_u64(&req->appId))));
}
static void halExtAppsOff(void *rx, uint8_t rx_len)
{
struct NanohubHalMgmtRx *req = rx;
- halSendMgmtResponse(NANOHUB_HAL_EXT_APPS_OFF, osExtAppStopApps(le64toh(unaligned_u64(&req->appId))));
+ halSendMgmtResponse(NANOHUB_HAL_EXT_APPS_OFF, osExtAppStopAppsByAppId(le64toh(unaligned_u64(&req->appId))));
}
static void halExtAppDelete(void *rx, uint8_t rx_len)
{
struct NanohubHalMgmtRx *req = rx;
- halSendMgmtResponse(NANOHUB_HAL_EXT_APP_DELETE, osExtAppEraseApps(le64toh(unaligned_u64(&req->appId))));
+ halSendMgmtResponse(NANOHUB_HAL_EXT_APP_DELETE, osExtAppEraseAppsByAppId(le64toh(unaligned_u64(&req->appId))));
}
static void halQueryMemInfo(void *rx, uint8_t rx_len)
@@ -1238,6 +1289,16 @@ const struct NanohubHalCommand *nanohubHalFindCommand(uint8_t msg)
return NULL;
}
+int64_t hostGetTimeDelta(void)
+{
+ int64_t delta = getAvgDelta(&mTimeSync);
+
+ if (delta == INT64_MIN)
+ return 0ULL;
+ else
+ return delta;
+}
+
uint64_t hostGetTime(void)
{
int64_t delta = getAvgDelta(&mTimeSync);
diff --git a/firmware/os/core/nanohub_chre.c b/firmware/os/core/nanohub_chre.c
index f23f860d..5ed419b6 100644
--- a/firmware/os/core/nanohub_chre.c
+++ b/firmware/os/core/nanohub_chre.c
@@ -31,6 +31,7 @@
#include <timer.h>
#include <util.h>
#include <printf.h>
+#include <nanohubCommand.h>
#include <chre.h>
#include <chreApi.h>
@@ -105,6 +106,13 @@ static void osChreApiGetTime(uintptr_t *retValP, va_list args)
*timeNanos = sensorGetTime();
}
+static void osChreApiGetHostTimeOffset(uintptr_t *retValP, va_list args)
+{
+ uint64_t *timeNanos = va_arg(args, uint64_t *);
+ if (timeNanos)
+ *timeNanos = hostGetTimeDelta();
+}
+
static inline uint32_t osChreTimerSet(uint64_t duration, const void* cookie, bool oneShot)
{
uint32_t timId = timTimerSetNew(duration, cookie, oneShot);
@@ -132,9 +140,19 @@ static void osChreApiTimerCancel(uintptr_t *retValP, va_list args)
static inline void osChreAbort(uint32_t abortCode)
{
struct Task *task = osGetCurrentTask();
- osLog(LOG_ERROR, "APP ID=0x%" PRIX64 " TID=0x%" PRIX16 " aborted [code 0x%" PRIX32 "]",
- task->app->hdr.appId, task->tid, abortCode);
- osTaskAbort(task);
+ if (task) {
+ if (task->app) {
+ osLog(LOG_ERROR, "APP ID=0x%" PRIX64 " TID=0x%" PRIX16 " aborted [code 0x%" PRIX32 "]",
+ task->app->hdr.appId, task->tid, abortCode);
+ } else {
+ osLog(LOG_ERROR, "APP ID=NULL TID=0x%" PRIX16 " aborted [code 0x%" PRIX32 "]",
+ task->tid, abortCode);
+ }
+ osTaskAbort(task);
+ } else {
+ osLog(LOG_ERROR, "osChreAbort called with no current task [code 0x%" PRIX32 "]",
+ abortCode);
+ }
}
static void osChreApiAbort(uintptr_t *retValP, va_list args)
@@ -184,17 +202,8 @@ static bool osChreSendEvent(uint16_t evtType, void *evtData,
return osEnqueuePrivateEvtNew(evtType, evtData, evtFreeCallback, toTid);
}
-static void osChreApiSendEvent(uintptr_t *retValP, va_list args)
-{
- uint16_t evtType = va_arg(args, uint32_t); // stored as 32-bit
- void *evtData = va_arg(args, void *);
- chreEventCompleteFunction *freeCallback = va_arg(args, chreEventCompleteFunction *);
- uint32_t toTid = va_arg(args, uint32_t);
- *retValP = osChreSendEvent(evtType, evtData, freeCallback, toTid);
-}
-
static bool osChreSendMessageToHost(void *message, uint32_t messageSize,
- uint32_t reservedMessageType,
+ uint32_t messageType, uint16_t hostEndpoint,
chreMessageFreeFunction *freeCallback)
{
bool result = false;
@@ -224,10 +233,10 @@ static void osChreApiSendMessageToHost(uintptr_t *retValP, va_list args)
{
void *message = va_arg(args, void *);
uint32_t messageSize = va_arg(args, uint32_t);
- uint32_t reservedMessageType = va_arg(args, uint32_t);
+ uint32_t messageType = va_arg(args, uint32_t);
chreMessageFreeFunction *freeCallback = va_arg(args, chreMessageFreeFunction *);
- *retValP = osChreSendMessageToHost(message, messageSize, reservedMessageType, freeCallback);
+ *retValP = osChreSendMessageToHost(message, messageSize, messageType, CHRE_HOST_ENDPOINT_BROADCAST, freeCallback);
}
static bool osChreSensorFindDefault(uint8_t sensorType, uint32_t *pHandle)
@@ -247,9 +256,31 @@ static void osChreApiSensorFindDefault(uintptr_t *retValP, va_list args)
*retValP = osChreSensorFindDefault(sensorType, pHandle);
}
+static bool osChreSensorGetInfoOld(uint32_t sensorHandle, struct chreSensorInfo *info)
+{
+ struct Sensor *s = sensorFindByHandle(sensorHandle);
+ if (!s || !info)
+ return false;
+ const struct SensorInfo *si = s->si;
+ info->sensorName = si->sensorName;
+ info->sensorType = si->sensorType;
+ info->unusedFlags = 0;
+
+ if (si->sensorType == CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT
+ || si->sensorType == CHRE_SENSOR_TYPE_STATIONARY_DETECT)
+ info->isOneShot = true;
+ else
+ info->isOneShot = false;
+ info->isOnChange = s->hasOnchange;
+
+ return true;
+}
+
static bool osChreSensorGetInfo(uint32_t sensorHandle, struct chreSensorInfo *info)
{
struct Sensor *s = sensorFindByHandle(sensorHandle);
+ uint32_t max = 0;
+ int i;
if (!s || !info)
return false;
const struct SensorInfo *si = s->si;
@@ -263,10 +294,30 @@ static bool osChreSensorGetInfo(uint32_t sensorHandle, struct chreSensorInfo *in
else
info->isOneShot = false;
info->isOnChange = s->hasOnchange;
+ info->minInterval = CHRE_SENSOR_INTERVAL_DEFAULT;
+ if (si->supportedRates) {
+ for (i=0; si->supportedRates[i] != 0; i++) {
+ if (si->supportedRates[i] > max
+ && si->supportedRates[i] != SENSOR_RATE_ONDEMAND
+ && si->supportedRates[i] != SENSOR_RATE_ONCHANGE
+ && si->supportedRates[i] != SENSOR_RATE_ONESHOT) {
+ max = si->supportedRates[i];
+ }
+ }
+ if (max)
+ info->minInterval = (UINT32_C(1024000000) / max) * UINT64_C(1000);
+ }
return true;
}
+static void osChreApiSensorGetInfoOld(uintptr_t *retValP, va_list args)
+{
+ uint32_t sensorHandle = va_arg(args, uint32_t);
+ struct chreSensorInfo *info = va_arg(args, struct chreSensorInfo *);
+ *retValP = osChreSensorGetInfoOld(sensorHandle, info);
+}
+
static void osChreApiSensorGetInfo(uintptr_t *retValP, va_list args)
{
uint32_t sensorHandle = va_arg(args, uint32_t);
@@ -278,27 +329,32 @@ static bool osChreSensorGetSamplingStatus(uint32_t sensorHandle,
struct chreSensorSamplingStatus *status)
{
struct Sensor *s = sensorFindByHandle(sensorHandle);
+ uint32_t rate;
+ uint64_t latency;
+
if (!s || !status)
return false;
- if (s->currentRate == SENSOR_RATE_OFF
- || s->currentRate >= SENSOR_RATE_POWERING_ON) {
+ rate = sensorGetHwRate(sensorHandle);
+ latency = sensorGetHwLatency(sensorHandle);
+
+ if (rate == SENSOR_RATE_OFF) {
status->enabled = 0;
status->interval = 0;
status->latency = 0;
} else {
status->enabled = true;
- if (s->currentRate == SENSOR_RATE_ONDEMAND
- || s->currentRate == SENSOR_RATE_ONCHANGE
- || s->currentRate == SENSOR_RATE_ONESHOT)
+ if (rate == SENSOR_RATE_ONDEMAND
+ || rate == SENSOR_RATE_ONCHANGE
+ || rate == SENSOR_RATE_ONESHOT)
status->interval = CHRE_SENSOR_INTERVAL_DEFAULT;
else
- status->interval = (UINT32_C(1024000000) / s->currentRate) * UINT64_C(1000);
+ status->interval = (UINT32_C(1024000000) / rate) * UINT64_C(1000);
- if (s->currentLatency == SENSOR_LATENCY_NODATA)
+ if (latency == SENSOR_LATENCY_NODATA)
status->latency = CHRE_SENSOR_INTERVAL_DEFAULT;
else
- status->latency = s->currentLatency;
+ status->latency = latency;
}
return true;
@@ -355,10 +411,7 @@ static bool osChreSensorConfigure(uint32_t sensorHandle,
ret = sensorRequestRateChange(0, sensorHandle, rate, latency);
}
} else if (mode & (CHRE_SENSOR_CONFIGURE_RAW_REPORT_CONTINUOUS|CHRE_SENSOR_CONFIGURE_RAW_REPORT_ONE_SHOT)) {
- if (interval != CHRE_SENSOR_INTERVAL_DEFAULT
- || latency != CHRE_SENSOR_LATENCY_DEFAULT)
- ret = false;
- else if (sensorGetReqRate(sensorHandle) == SENSOR_RATE_OFF)
+ if (sensorGetReqRate(sensorHandle) == SENSOR_RATE_OFF)
ret = osEventsSubscribe(2, sensorGetMyEventType(s->si->sensorType), sensorGetMyCfgEventType(s->si->sensorType));
else
ret = true;
@@ -421,6 +474,132 @@ static void osChreApiPlatformId(uintptr_t *retValP, va_list args)
*pHwId = osChreGetPlatformId();
}
+static void osChreEventSendEvent(uintptr_t *retValP, va_list args)
+{
+ uint16_t evtType = va_arg(args, uint32_t); // stored as 32-bit
+ void *evtData = va_arg(args, void *);
+ chreEventCompleteFunction *freeCallback = va_arg(args, chreEventCompleteFunction *);
+ uint32_t toTid = va_arg(args, uint32_t);
+ *retValP = osChreSendEvent(evtType, evtData, freeCallback, toTid);
+}
+
+static void osChreEventSendMessageToHost(uintptr_t *retValP, va_list args)
+{
+ void *message = va_arg(args, void *);
+ uint32_t messageSize = va_arg(args, size_t);
+ uint32_t messageType = va_arg(args, uint32_t);
+ uint16_t hostEndpoint = va_arg(args, uint32_t);
+ chreMessageFreeFunction *freeCallback = va_arg(args, chreMessageFreeFunction *);
+
+ *retValP = osChreSendMessageToHost(message, messageSize, messageType, hostEndpoint, freeCallback);
+}
+
+static bool chreInfoByTid(uint32_t tid, struct chreNanoappInfo *info)
+{
+ struct Task *task = osTaskFindByTid(tid);
+ if (task) {
+ info->appId = task->app->hdr.appId;
+ info->version = task->app->hdr.appVer;
+ info->instanceId = tid;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static void osChreEventInfoByAppId(uintptr_t *retValP, va_list args)
+{
+ uint32_t app_lo = va_arg(args, uint32_t);
+ uint32_t app_hi = va_arg(args, uint32_t);
+ struct chreNanoappInfo *info = va_arg(args, struct chreNanoappInfo *);
+ uint64_t appId = (((uint64_t)app_hi) << 32) | app_lo;
+ uint32_t tid;
+
+ if (osTidById(&appId, &tid))
+ *retValP = chreInfoByTid(tid, info);
+ else
+ *retValP = false;
+}
+
+static void osChreEeventInfoByInstId(uintptr_t *retValP, va_list args)
+{
+ uint32_t tid = va_arg(args, uint32_t);
+ struct chreNanoappInfo *info = va_arg(args, struct chreNanoappInfo *);
+
+ *retValP = chreInfoByTid(tid, info);
+}
+
+static void osChreEventCfgInfo(uintptr_t *retValP, va_list args)
+{
+ bool enable = va_arg(args, int);
+ if (enable)
+ osEventsSubscribe(2, EVT_APP_STARTED, EVT_APP_STOPPED);
+ else
+ osEventsUnsubscribe(2, EVT_APP_STARTED, EVT_APP_STOPPED);
+}
+
+static void osChreDrvGnssGetCap(uintptr_t *retValP, va_list args)
+{
+ *retValP = CHRE_GNSS_CAPABILITIES_NONE;
+}
+
+static void osChreDrvGnssLocStartAsync(uintptr_t *retValP, va_list args)
+{
+ // uint32_t minIntervalMs = va_args(args, uint32_t);
+ // uint32_t minTimeToNextFixMs = va_args(args, uint32_t);
+ // const void *cookie = va_args(args, void *);
+ *retValP = false;
+}
+
+static void osChreDrvGnssLocStopAsync(uintptr_t *retValP, va_list args)
+{
+ // const void *cookie = va_args(args, void *);
+ *retValP = false;
+}
+
+static void osChreDrvGnssMeasStartAsync(uintptr_t *retValP, va_list args)
+{
+ // uint32_t minIntervalMs = va_args(args, uint32_t);
+ // const void *cookie = va_args(args, void *);
+ *retValP = false;
+}
+
+static void osChreDrvGnssMeasStopAsync(uintptr_t *retValP, va_list args)
+{
+ // const void *cookie = va_args(args, void *);
+ *retValP = false;
+}
+
+static void osChreDrvWifiGetCap(uintptr_t *retValP, va_list args)
+{
+ *retValP = CHRE_WIFI_CAPABILITIES_NONE;
+}
+
+static void osChreDrvWifiConfScanMonAsync(uintptr_t *retValP, va_list args)
+{
+ // bool enable = va_args(args, int);
+ // const void *cookie = va_args(args, void *);
+ *retValP = false;
+}
+
+static void osChreDrvWifiReqScanAsync(uintptr_t *retValP, va_list args)
+{
+ // const struct chreWifiScanParams *params = va_args(args, struct chreWifiScanParams *);
+ // const void *cookie = va_args(args, void *);
+ *retValP = false;
+}
+
+static void osChreDrvWwanGetCap(uintptr_t *retValP, va_list args)
+{
+ *retValP = CHRE_WWAN_CAPABILITIES_NONE;
+}
+
+static void osChreDrvWwanGetCallInfoAsync(uintptr_t *retValP, va_list args)
+{
+ // const void *cookie = va_args(args, void *);
+ *retValP = false;
+}
+
static const struct SyscallTable chreMainApiTable = {
.numEntries = SYSCALL_CHRE_MAIN_API_LAST,
.entry = {
@@ -429,15 +608,17 @@ static const struct SyscallTable chreMainApiTable = {
[SYSCALL_CHRE_MAIN_API_GET_APP_ID] = { .func = osChreApiGetAppId },
[SYSCALL_CHRE_MAIN_API_GET_INST_ID] = { .func = osChreApiGetInstanceId },
[SYSCALL_CHRE_MAIN_API_GET_TIME] = { .func = osChreApiGetTime },
+ [SYSCALL_CHRE_MAIN_API_GET_HOST_TIME_OFFSET] = { .func = osChreApiGetHostTimeOffset },
[SYSCALL_CHRE_MAIN_API_TIMER_SET] = { .func = osChreApiTimerSet },
[SYSCALL_CHRE_MAIN_API_TIMER_CANCEL] = { .func = osChreApiTimerCancel },
[SYSCALL_CHRE_MAIN_API_ABORT] = { .func = osChreApiAbort },
[SYSCALL_CHRE_MAIN_API_HEAP_ALLOC] = { .func = osChreApiHeapAlloc },
[SYSCALL_CHRE_MAIN_API_HEAP_FREE] = { .func = osChreApiHeapFree },
- [SYSCALL_CHRE_MAIN_API_SEND_EVENT] = { .func = osChreApiSendEvent },
+ [SYSCALL_CHRE_MAIN_API_SEND_EVENT] = { .func = osChreEventSendEvent },
[SYSCALL_CHRE_MAIN_API_SEND_MSG] = { .func = osChreApiSendMessageToHost },
[SYSCALL_CHRE_MAIN_API_SENSOR_FIND_DEFAULT] = { .func = osChreApiSensorFindDefault },
- [SYSCALL_CHRE_MAIN_API_SENSOR_GET_INFO] = { .func = osChreApiSensorGetInfo },
+ [SYSCALL_CHRE_MAIN_API_SENSOR_GET_INFO_OLD] = { .func = osChreApiSensorGetInfoOld },
+ [SYSCALL_CHRE_MAIN_API_SENSOR_GET_INFO] = { .func = osChreApiSensorGetInfo },
[SYSCALL_CHRE_MAIN_API_SENSOR_GET_STATUS] = { .func = osChreApiSensorGetStatus },
[SYSCALL_CHRE_MAIN_API_SENSOR_CONFIG] = { .func = osChreApiSensorConfig },
[SYSCALL_CHRE_MAIN_API_GET_OS_API_VERSION] = { .func = osChreApiChreApiVersion },
@@ -446,10 +627,59 @@ static const struct SyscallTable chreMainApiTable = {
},
};
+static const struct SyscallTable chreMainEventTable = {
+ .numEntries = SYSCALL_CHRE_MAIN_EVENT_LAST,
+ .entry = {
+ [SYSCALL_CHRE_MAIN_EVENT_SEND_EVENT] = { .func = osChreEventSendEvent },
+ [SYSCALL_CHRE_MAIN_EVENT_SEND_MSG] = { .func = osChreEventSendMessageToHost },
+ [SYSCALL_CHRE_MAIN_EVENT_INFO_BY_APP_ID] = { .func = osChreEventInfoByAppId },
+ [SYSCALL_CHRE_MAIN_EVENT_INFO_BY_INST_ID] = { .func = osChreEeventInfoByInstId },
+ [SYSCALL_CHRE_MAIN_EVENT_CFG_INFO] = { .func = osChreEventCfgInfo },
+ },
+};
+
static const struct SyscallTable chreMainTable = {
.numEntries = SYSCALL_CHRE_MAIN_LAST,
.entry = {
[SYSCALL_CHRE_MAIN_API] = { .subtable = (struct SyscallTable*)&chreMainApiTable, },
+ [SYSCALL_CHRE_MAIN_EVENT] = { .subtable = (struct SyscallTable*)&chreMainEventTable, },
+ },
+};
+
+static const struct SyscallTable chreDrvGnssTable = {
+ .numEntries = SYSCALL_CHRE_DRV_GNSS_LAST,
+ .entry = {
+ [SYSCALL_CHRE_DRV_GNSS_GET_CAP] = { .func = osChreDrvGnssGetCap },
+ [SYSCALL_CHRE_DRV_GNSS_LOC_START_ASYNC] = { .func = osChreDrvGnssLocStartAsync },
+ [SYSCALL_CHRE_DRV_GNSS_LOC_STOP_ASYNC] = { .func = osChreDrvGnssLocStopAsync },
+ [SYSCALL_CHRE_DRV_GNSS_MEAS_START_ASYNC] = { .func = osChreDrvGnssMeasStartAsync },
+ [SYSCALL_CHRE_DRV_GNSS_MEAS_STOP_ASYNC] = { .func = osChreDrvGnssMeasStopAsync },
+ },
+};
+
+static const struct SyscallTable chreDrvWifiTable = {
+ .numEntries = SYSCALL_CHRE_DRV_WIFI_LAST,
+ .entry = {
+ [SYSCALL_CHRE_DRV_WIFI_GET_CAP] = { .func = osChreDrvWifiGetCap },
+ [SYSCALL_CHRE_DRV_WIFI_CONF_SCAN_MON_ASYNC] = { .func = osChreDrvWifiConfScanMonAsync },
+ [SYSCALL_CHRE_DRV_WIFI_REQ_SCAN_ASYNC] = { .func = osChreDrvWifiReqScanAsync },
+ },
+};
+
+static const struct SyscallTable chreDrvWwanTable = {
+ .numEntries = SYSCALL_CHRE_DRV_WWAN_LAST,
+ .entry = {
+ [SYSCALL_CHRE_DRV_WWAN_GET_CAP] = { .func = osChreDrvWwanGetCap },
+ [SYSCALL_CHRE_DRV_WWAN_GET_CELL_INFO_ASYNC] = { .func = osChreDrvWwanGetCallInfoAsync },
+ },
+};
+
+static const struct SyscallTable chreDriversTable = {
+ .numEntries = SYSCALL_CHRE_DRV_LAST,
+ .entry = {
+ [SYSCALL_CHRE_DRV_GNSS] = { .subtable = (struct SyscallTable*)&chreDrvGnssTable, },
+ [SYSCALL_CHRE_DRV_WIFI] = { .subtable = (struct SyscallTable*)&chreDrvWifiTable, },
+ [SYSCALL_CHRE_DRV_WWAN] = { .subtable = (struct SyscallTable*)&chreDrvWwanTable, },
},
};
@@ -457,6 +687,7 @@ static const struct SyscallTable chreTable = {
.numEntries = SYSCALL_CHRE_LAST,
.entry = {
[SYSCALL_CHRE_MAIN] = { .subtable = (struct SyscallTable*)&chreMainTable, },
+ [SYSCALL_CHRE_DRIVERS] = { .subtable = (struct SyscallTable*)&chreDriversTable, },
},
};
diff --git a/firmware/os/core/osApi.c b/firmware/os/core/osApi.c
index 8361d9ae..098e2dc1 100644
--- a/firmware/os/core/osApi.c
+++ b/firmware/os/core/osApi.c
@@ -28,6 +28,7 @@
#include <heap.h>
#include <i2c.h>
#include <nanohubCommand.h>
+#include <seos_priv.h>
static struct SlabAllocator *mSlabAllocator;
diff --git a/firmware/os/core/sensors.c b/firmware/os/core/sensors.c
index d96fdc68..781afb88 100644
--- a/firmware/os/core/sensors.c
+++ b/firmware/os/core/sensors.c
@@ -816,6 +816,20 @@ uint64_t sensorGetCurLatency(uint32_t sensorHandle)
return s ? s->currentLatency : SENSOR_LATENCY_INVALID;
}
+uint32_t sensorGetHwRate(uint32_t sensorHandle)
+{
+ struct Sensor* s = sensorFindByHandle(sensorHandle);
+
+ return s ? sensorCalcHwRate(s, 0, 0) : SENSOR_RATE_OFF;
+}
+
+uint64_t sensorGetHwLatency(uint32_t sensorHandle)
+{
+ struct Sensor* s = sensorFindByHandle(sensorHandle);
+
+ return s ? sensorCalcHwLatency(s) : SENSOR_LATENCY_INVALID;
+}
+
uint32_t sensorGetReqRate(uint32_t sensorHandle)
{
struct SensorsClientRequest *req = sensorClientRequestFind(sensorHandle, osGetCurrentTid());
diff --git a/firmware/os/core/seos.c b/firmware/os/core/seos.c
index 8d100f56..98c05ea5 100644
--- a/firmware/os/core/seos.c
+++ b/firmware/os/core/seos.c
@@ -97,6 +97,16 @@ bool osAppIsChre(uint16_t tid)
return task && osTaskIsChre(task);
}
+uint32_t osAppChreVersion(uint16_t tid)
+{
+ struct Task *task = osTaskFindByTid(tid);
+
+ if (task)
+ return osTaskChreVersion(task);
+ else
+ return 0;
+}
+
static inline uint32_t osTaskClrSetFlags(struct Task *task, uint32_t clrMask, uint32_t setMask)
{
while (true) {
@@ -290,27 +300,26 @@ static inline bool osTaskInit(struct Task *task)
static void osTaskRelease(struct Task *task)
{
- uint16_t tid = task->tid;
-
- osSetCurrentTask(mSystemTask);
+ uint32_t task_tid = task->tid;
- platFreeResources(tid); // HW resources cleanup (IRQ, DMA etc)
- sensorFreeAll(tid);
- timTimerCancelAll(tid);
- heapFreeAll(tid);
+ platFreeResources(task_tid); // HW resources cleanup (IRQ, DMA etc)
+ sensorFreeAll(task_tid);
+ timTimerCancelAll(task_tid);
+ heapFreeAll(task_tid);
}
static inline void osTaskEnd(struct Task *task)
{
- struct Task *preempted = osSetCurrentTask(task);
-
- cpuAppEnd(task->app, &task->platInfo);
+ if (!osTaskTestFlags(task, FL_TASK_ABORTED)) {
+ struct Task *preempted = osSetCurrentTask(task);
+ cpuAppEnd(task->app, &task->platInfo);
+ osSetCurrentTask(preempted);
+ }
// task was supposed to release it's resources,
// but we do our cleanup anyway
- osTaskRelease(task);
// NOTE: we don't need to unsubscribe from events
- osSetCurrentTask(preempted);
+ osTaskRelease(task);
}
static inline void osTaskHandle(struct Task *task, uint16_t evtType, uint16_t fromTid, const void* evtData)
@@ -722,48 +731,79 @@ static bool osStartApp(const struct AppHdr *app)
osUnloadApp(task);
} else {
osAddTask(task);
+ (void)osEnqueueEvt(EVT_APP_BEGIN, task, NULL);
}
}
return done;
}
-static bool osStopTask(struct Task *task)
+static bool osStopTask(struct Task *task, bool abort)
{
+ struct Task *preempted;
+
if (!task)
return false;
+ if (osTaskTestFlags(task, FL_TASK_STOPPED))
+ return true;
+
+ preempted = osSetCurrentTask(mSystemTask);
osRemoveTask(task);
+ osTaskClrSetFlags(task, 0, FL_TASK_STOPPED);
- if (osTaskGetIoCount(task))
- {
+ if (abort)
+ osTaskClrSetFlags(task, 0, FL_TASK_ABORTED);
+ else if (osTaskGetIoCount(task))
osTaskHandle(task, EVT_APP_STOP, OS_SYSTEM_TID, NULL);
- osEnqueueEvt(EVT_APP_END, task, NULL);
- } else {
- osTaskEnd(task); // calls app END() and Release()
- osUnloadApp(task);
- }
+ osEnqueueEvt(EVT_APP_END, task, NULL);
+
+ osSetCurrentTask(preempted);
- osTaskClrSetFlags(task, 0, FL_TASK_STOPPED);
return true;
}
void osTaskAbort(struct Task *task)
{
- if (!task)
- return;
+ osStopTask(task, true);
+}
+
+static bool matchDelayStart(const void *cookie, const struct AppHdr *app)
+{
+ bool match = (bool)cookie;
- osRemoveTask(task); // remove from active task list
- // do not call app END()
- osTaskRelease(task); // release all system resources
- osUnloadApp(task); // destroy platform app object in RAM
+ if (app->hdr.fwFlags & FL_APP_HDR_CHRE) {
+ if (app->hdr.chreApiMajor == 0xFF && app->hdr.chreApiMinor == 0xFF)
+ return !match;
+ else if ((app->hdr.chreApiMajor < 0x01) ||
+ (app->hdr.chreApiMajor == 0x01 && app->hdr.chreApiMinor < 0x01))
+ return !match;
+ else
+ return match;
+ } else {
+ return !match;
+ }
}
-static bool osExtAppFind(struct SegmentIterator *it, uint64_t appId)
+static bool matchAppId(const void *data, const struct AppHdr *app)
+{
+ uint64_t appId, vendor, seqId, curAppId;
+
+ memcpy(&appId, data, sizeof(appId));
+ vendor = APP_ID_GET_VENDOR(appId);
+ seqId = APP_ID_GET_SEQ_ID(appId);
+ curAppId = app->hdr.appId;
+
+ if ((vendor == APP_VENDOR_ANY || vendor == APP_ID_GET_VENDOR(curAppId)) &&
+ (seqId == APP_SEQ_ID_ANY || seqId == APP_ID_GET_SEQ_ID(curAppId))) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static bool osExtAppFind(struct SegmentIterator *it, appMatchFunc func, const void *data)
{
- uint64_t vendor = APP_ID_GET_VENDOR(appId);
- uint64_t seqId = APP_ID_GET_SEQ_ID(appId);
- uint64_t curAppId;
const struct AppHdr *app;
const struct Segment *seg;
@@ -776,17 +816,14 @@ static bool osExtAppFind(struct SegmentIterator *it, uint64_t appId)
if (seg->state != SEG_ST_VALID)
continue;
app = osSegmentGetData(seg);
- curAppId = app->hdr.appId;
-
- if ((vendor == APP_VENDOR_ANY || vendor == APP_ID_GET_VENDOR(curAppId)) &&
- (seqId == APP_SEQ_ID_ANY || seqId == APP_ID_GET_SEQ_ID(curAppId)))
+ if (func(data, app))
return true;
}
return false;
}
-static uint32_t osExtAppStopEraseApps(uint64_t appId, bool doErase)
+static uint32_t osExtAppStopEraseApps(appMatchFunc func, const void *data, bool doErase)
{
const struct AppHdr *app;
int32_t len;
@@ -799,7 +836,7 @@ static uint32_t osExtAppStopEraseApps(uint64_t appId, bool doErase)
struct Task *task;
osSegmentIteratorInit(&it);
- while (osExtAppFind(&it, appId)) {
+ while (osExtAppFind(&it, func, data)) {
app = osSegmentGetData(it.seg);
len = osSegmentGetSize(it.seg);
if (!osExtAppIsValid(app, len))
@@ -813,7 +850,7 @@ static uint32_t osExtAppStopEraseApps(uint64_t appId, bool doErase)
task = osTaskFindByAppID(app->hdr.appId);
if (task) {
taskCount++;
- if (osStopTask(task))
+ if (osStopTask(task, false))
stopCount++;
}
}
@@ -825,14 +862,14 @@ static uint32_t osExtAppStopEraseApps(uint64_t appId, bool doErase)
return stat.value;
}
-uint32_t osExtAppStopApps(uint64_t appId)
+uint32_t osExtAppStopAppsByAppId(uint64_t appId)
{
- return osExtAppStopEraseApps(appId, false);
+ return osExtAppStopEraseApps(matchAppId, &appId, false);
}
-uint32_t osExtAppEraseApps(uint64_t appId)
+uint32_t osExtAppEraseAppsByAppId(uint64_t appId)
{
- return osExtAppStopEraseApps(appId, true);
+ return osExtAppStopEraseApps(matchAppId, &appId, true);
}
static void osScanExternal()
@@ -859,7 +896,7 @@ static void osScanExternal()
}
}
-uint32_t osExtAppStartApps(uint64_t appId)
+static uint32_t osExtAppStartApps(appMatchFunc func, void *data)
{
const struct AppHdr *app;
int32_t len;
@@ -874,7 +911,7 @@ uint32_t osExtAppStartApps(uint64_t appId)
osScanExternal();
osSegmentIteratorInit(&it);
- while (osExtAppFind(&it, appId)) {
+ while (osExtAppFind(&it, func, data)) {
app = osSegmentGetData(it.seg);
len = osSegmentGetSize(it.seg);
@@ -885,7 +922,7 @@ uint32_t osExtAppStartApps(uint64_t appId)
appCount++;
checkIt = it;
// find the most recent copy
- while (osExtAppFind(&checkIt, app->hdr.appId)) {
+ while (osExtAppFind(&checkIt, matchAppId, &app->hdr.appId)) {
if (osExtAppErase(app)) // erase the old one, so we skip it next time
eraseCount++;
app = osSegmentGetData(checkIt.seg);
@@ -909,6 +946,16 @@ uint32_t osExtAppStartApps(uint64_t appId)
return stat.value;
}
+uint32_t osExtAppStartAppsByAppId(uint64_t appId)
+{
+ return osExtAppStartApps(matchAppId, &appId);
+}
+
+uint32_t osExtAppStartAppsDelayed()
+{
+ return osExtAppStartApps(matchDelayStart, (void *)true);
+}
+
static void osStartTasks(void)
{
const struct AppHdr *app;
@@ -959,19 +1006,20 @@ static void osStartTasks(void)
}
osLog(LOG_DEBUG, "Starting external apps...\n");
- status = osExtAppStartApps(APP_ID_ANY);
+ status = osExtAppStartApps(matchDelayStart, (void *)false);
osLog(LOG_DEBUG, "Started %" PRIu32 " internal apps; EXT status: %08" PRIX32 "\n", taskCnt, status);
}
static void osInternalEvtHandle(uint32_t evtType, void *evtData)
{
union SeosInternalSlabData *da = (union SeosInternalSlabData*)evtData;
- struct Task *task;
+ struct Task *task, *ssTask;
uint32_t i, j;
uint16_t tid = EVENT_GET_ORIGIN(evtType);
- uint16_t evt = EVENT_GET_EVENT(evtType);
+ uint16_t evt = EVENT_GET_EVENT(evtType), newEvt;
struct Task *srcTask = osTaskFindByTid(tid);
struct Task *preempted = osSetCurrentTask(srcTask);
+ struct AppEventStartStop ssMsg;
switch (evt) {
case EVT_SUBSCRIBE_TO_EVT:
@@ -1008,10 +1056,31 @@ static void osInternalEvtHandle(uint32_t evtType, void *evtData)
}
break;
+ case EVT_APP_BEGIN:
case EVT_APP_END:
- task = evtData;
- osTaskEnd(task);
- osUnloadApp(task);
+ ssTask = evtData;
+ ssMsg.appId = ssTask->app->hdr.appId;
+ ssMsg.version = ssTask->app->hdr.appVer;
+ ssMsg.tid = ssTask->tid;
+ if (evt == EVT_APP_BEGIN) {
+ newEvt = EVT_APP_STARTED;
+ } else {
+ newEvt = EVT_APP_STOPPED;
+ osTaskEnd(ssTask);
+ osUnloadApp(ssTask);
+ }
+
+ /* send this event to all tasks who want it */
+ for_each_task(&mTasks, task) {
+ if (task != ssTask) {
+ for (i = 0; i < task->subbedEvtCount; i++) {
+ if (task->subbedEvents[i] == newEvt) {
+ osTaskHandle(task, newEvt, OS_SYSTEM_TID, &ssMsg);
+ break;
+ }
+ }
+ }
+ }
break;
case EVT_DEFERRED_CALLBACK:
diff --git a/firmware/os/core/timer.c b/firmware/os/core/timer.c
index 76df80bb..ace80723 100644
--- a/firmware/os/core/timer.c
+++ b/firmware/os/core/timer.c
@@ -31,6 +31,8 @@
#define MAX_INTERNAL_EVENTS 32 //also used for external app timer() calls
+#define MAX_TIMER_ID 0xFF
+
#define INFO_PRINT(fmt, ...) do { \
osLog(LOG_INFO, "%s " fmt, "[timer]", ##__VA_ARGS__); \
} while (0);
@@ -40,7 +42,8 @@
struct Timer {
uint64_t expires; /* time of next expiration */
uint64_t period; /* 0 for oneshot */
- uint16_t id; /* 0 for disabled */
+ uint8_t id; /* 0 for disabled */
+ uint8_t useRtc; /* 1 for rtc, 0 for tim */
uint16_t tid; /* we need TID always, for system management */
uint32_t jitterPpm;
uint32_t driftPpm;
@@ -102,7 +105,7 @@ static bool timFireAsNeededAndUpdateAlarms(void)
{
uint32_t maxDrift = 0, maxJitter = 0, maxErrTotal = 0;
bool somethingDone, totalSomethingDone = false;
- uint64_t nextTimer;
+ uint64_t nextTimer, expires;
uint32_t i;
struct Timer *tim;
@@ -118,7 +121,7 @@ static bool timFireAsNeededAndUpdateAlarms(void)
if (!tim->id)
continue;
- if (tim->expires <= timGetTime()) {
+ if ((!tim->useRtc && tim->expires <= timGetTime()) || (tim->useRtc && tim->expires <= rtcGetTime())) {
somethingDone = true;
if (tim->period) {
tim->expires += tim->period;
@@ -136,8 +139,12 @@ static bool timFireAsNeededAndUpdateAlarms(void)
maxDrift = tim->driftPpm;
if (tim->driftPpm + tim->jitterPpm > maxErrTotal)
maxErrTotal = tim->driftPpm + tim->jitterPpm;
- if (!nextTimer || nextTimer > tim->expires)
- nextTimer = tim->expires;
+ if (tim->useRtc)
+ expires = tim->expires - rtcGetTime() + timGetTime();
+ else
+ expires = tim->expires;
+ if (!nextTimer || nextTimer > expires)
+ nextTimer = expires;
}
}
@@ -155,9 +162,9 @@ static bool timFireAsNeededAndUpdateAlarms(void)
return totalSomethingDone;
}
-static uint32_t timTimerSetEx(uint64_t length, uint32_t jitterPpm, uint32_t driftPpm, TaggedPtr info, void* data, bool oneShot)
+static uint32_t timTimerSetEx(uint64_t length, uint32_t jitterPpm, uint32_t driftPpm, TaggedPtr info, void* data, bool oneShot, bool useRtc)
{
- uint64_t curTime = timGetTime();
+ uint64_t curTime = useRtc ? rtcGetTime() : timGetTime();
int32_t idx = atomicBitsetFindClearAndSet(mTimersValid);
struct Timer *t;
uint16_t timId;
@@ -169,7 +176,7 @@ static uint32_t timTimerSetEx(uint64_t length, uint32_t jitterPpm, uint32_t drif
/* generate next timer ID */
do {
- timId = atomicAdd32bits(&mNextTimerId, 1);
+ timId = atomicAdd32bits(&mNextTimerId, 1) & MAX_TIMER_ID;
} while (!timId || timFindTimerById(timId));
/* grab our struct & fill it in */
@@ -180,10 +187,11 @@ static uint32_t timTimerSetEx(uint64_t length, uint32_t jitterPpm, uint32_t drif
t->driftPpm = driftPpm;
t->callInfo = info;
t->callData = data;
+ t->useRtc = useRtc;
+ t->tid = osGetCurrentTid();
/* as soon as we write timer Id, it becomes valid and might fire */
t->id = timId;
- t->tid = osGetCurrentTid();
/* fire as needed & recalc alarms*/
timFireAsNeededAndUpdateAlarms();
@@ -194,17 +202,17 @@ static uint32_t timTimerSetEx(uint64_t length, uint32_t jitterPpm, uint32_t drif
uint32_t timTimerSet(uint64_t length, uint32_t jitterPpm, uint32_t driftPpm, TimTimerCbkF cbk, void* data, bool oneShot)
{
- return timTimerSetEx(length, jitterPpm, driftPpm, taggedPtrMakeFromPtr(cbk), data, oneShot);
+ return timTimerSetEx(length, jitterPpm, driftPpm, taggedPtrMakeFromPtr(cbk), data, oneShot, false);
}
uint32_t timTimerSetAsApp(uint64_t length, uint32_t jitterPpm, uint32_t driftPpm, uint32_t tid, void* data, bool oneShot)
{
- return timTimerSetEx(length, jitterPpm, driftPpm, taggedPtrMakeFromUint(0), data, oneShot);
+ return timTimerSetEx(length, jitterPpm, driftPpm, taggedPtrMakeFromUint(0), data, oneShot, false);
}
uint32_t timTimerSetNew(uint64_t length, const void* data, bool oneShot)
{
- return timTimerSetEx(length, 0, 0, taggedPtrMakeFromUint(0), (void *)data, oneShot);
+ return timTimerSetEx(length, 0, 50, taggedPtrMakeFromUint(0), (void *)data, oneShot, true);
}
static bool timerEventMatch(uint32_t evtType, const void *evtData, void *context)
diff --git a/firmware/os/drivers/bosch_bmi160/bosch_bmi160.c b/firmware/os/drivers/bosch_bmi160/bosch_bmi160.c
index e8d88422..054faa8c 100644
--- a/firmware/os/drivers/bosch_bmi160/bosch_bmi160.c
+++ b/firmware/os/drivers/bosch_bmi160/bosch_bmi160.c
@@ -258,6 +258,18 @@
#define MAX_NUM_COMMS_EVENT_SAMPLES 15
+#ifndef BMI160_ACC_SAMPLES
+#define BMI160_ACC_SAMPLES 3000
+#endif
+
+#ifndef BMI160_GYRO_SAMPLES
+#define BMI160_GYRO_SAMPLES 20
+#endif
+
+#ifndef BMI160_MAG_SAMPLES
+#define BMI160_MAG_SAMPLES 600
+#endif
+
// Default accel range is 8g
#ifndef BMI160_ACC_RANGE_G
#define BMI160_ACC_RANGE_G 8
@@ -748,18 +760,19 @@ static const struct SensorInfo mSensorInfo[NUM_OF_SENSOR] =
{
#ifdef ACCEL_CAL_ENABLED
{ DEC_INFO_RATE_RAW_BIAS("Accelerometer", AccRates, SENS_TYPE_ACCEL, NUM_AXIS_THREE,
- NANOHUB_INT_NONWAKEUP, 3000, SENS_TYPE_ACCEL_RAW, 1.0/kScale_acc,
- SENS_TYPE_ACCEL_BIAS) },
+ NANOHUB_INT_NONWAKEUP, BMI160_ACC_SAMPLES, SENS_TYPE_ACCEL_RAW,
+ 1.0/kScale_acc, SENS_TYPE_ACCEL_BIAS) },
#else
{ DEC_INFO_RATE_RAW("Accelerometer", AccRates, SENS_TYPE_ACCEL, NUM_AXIS_THREE,
- NANOHUB_INT_NONWAKEUP, 3000, SENS_TYPE_ACCEL_RAW, 1.0/kScale_acc) },
+ NANOHUB_INT_NONWAKEUP, BMI160_ACC_SAMPLES, SENS_TYPE_ACCEL_RAW,
+ 1.0/kScale_acc) },
#endif
{ DEC_INFO_RATE_BIAS("Gyroscope", GyrRates, SENS_TYPE_GYRO, NUM_AXIS_THREE,
- NANOHUB_INT_NONWAKEUP, 20, SENS_TYPE_GYRO_BIAS) },
+ NANOHUB_INT_NONWAKEUP, BMI160_GYRO_SAMPLES, SENS_TYPE_GYRO_BIAS) },
#ifdef MAG_SLAVE_PRESENT
{ DEC_INFO_RATE_RAW_BIAS("Magnetometer", MagRates, SENS_TYPE_MAG, NUM_AXIS_THREE,
- NANOHUB_INT_NONWAKEUP, 600, SENS_TYPE_MAG_RAW, 1.0/kScale_mag,
- SENS_TYPE_MAG_BIAS) },
+ NANOHUB_INT_NONWAKEUP, BMI160_MAG_SAMPLES, SENS_TYPE_MAG_RAW,
+ 1.0/kScale_mag, SENS_TYPE_MAG_BIAS) },
#endif
{ DEC_INFO("Step Detector", SENS_TYPE_STEP_DETECT, NUM_AXIS_EMBEDDED,
NANOHUB_INT_NONWAKEUP, 100) },
diff --git a/firmware/os/inc/chreApi.h b/firmware/os/inc/chreApi.h
index cf9bd499..e355ed5a 100644
--- a/firmware/os/inc/chreApi.h
+++ b/firmware/os/inc/chreApi.h
@@ -34,12 +34,17 @@ C_STATIC_ASSERT(va_list_size, sizeof(va_list) == sizeof(uint32_t));
C_STATIC_ASSERT(uintptr_size, sizeof(uintptr_t) >= sizeof(uint32_t));
//EXTERNAL API
+//level 1 indices in the CHRE table
#define SYSCALL_CHRE_MAIN 0
-#define SYSCALL_CHRE_LAST 1
+#define SYSCALL_CHRE_DRIVERS 1
+#define SYSCALL_CHRE_LAST 2 // always last. holes are allowed, but not immediately before this
+//level 2 indices in the CHRE.main table
#define SYSCALL_CHRE_MAIN_API 0
-#define SYSCALL_CHRE_MAIN_LAST 1
+#define SYSCALL_CHRE_MAIN_EVENT 1
+#define SYSCALL_CHRE_MAIN_LAST 2 // always last. holes are allowed, but not immediately before this
+//level 3 indices in the CHRE.main.api table
#define SYSCALL_CHRE_MAIN_API_GET_APP_ID 0 // (void) -> uint64_t
#define SYSCALL_CHRE_MAIN_API_GET_INST_ID 1 // (void) -> uint32_t
#define SYSCALL_CHRE_MAIN_API_LOG_OLD 2 // (enum LogLevel, const char *, uintptr_t) -> void
@@ -52,14 +57,49 @@ C_STATIC_ASSERT(uintptr_size, sizeof(uintptr_t) >= sizeof(uint32_t));
#define SYSCALL_CHRE_MAIN_API_SEND_EVENT 9 // (uint32_t, void *, chreEventCompleteFunction*, uint32_t) -> bool
#define SYSCALL_CHRE_MAIN_API_SEND_MSG 10 // (void *, uint32_t, uint32_t, chreMessageFreeFunction *) -> bool
#define SYSCALL_CHRE_MAIN_API_SENSOR_FIND_DEFAULT 11 //
-#define SYSCALL_CHRE_MAIN_API_SENSOR_GET_INFO 12 //
+#define SYSCALL_CHRE_MAIN_API_SENSOR_GET_INFO_OLD 12 //
#define SYSCALL_CHRE_MAIN_API_SENSOR_GET_STATUS 13 //
#define SYSCALL_CHRE_MAIN_API_SENSOR_CONFIG 14 //
#define SYSCALL_CHRE_MAIN_API_GET_OS_API_VERSION 15 //
#define SYSCALL_CHRE_MAIN_API_GET_OS_VERSION 16 //
#define SYSCALL_CHRE_MAIN_API_GET_PLATFORM_ID 17 //
#define SYSCALL_CHRE_MAIN_API_LOG 18 // (enum LogLevel, const char *, uintptr_t) -> void
-#define SYSCALL_CHRE_MAIN_API_LAST 19 // always last. holes are allowed, but not immediately before this
+#define SYSCALL_CHRE_MAIN_API_SENSOR_GET_INFO 19 //
+#define SYSCALL_CHRE_MAIN_API_GET_HOST_TIME_OFFSET 20 // (void) -> int64_t
+#define SYSCALL_CHRE_MAIN_API_LAST 21 // always last. holes are allowed, but not immediately before this
+
+//level 3 indices in the CHRE.main.event table
+#define SYSCALL_CHRE_MAIN_EVENT_SEND_EVENT 0 // (uint32_t, void *, chreEventCompleteFunction*, uint32_t) -> bool
+#define SYSCALL_CHRE_MAIN_EVENT_SEND_MSG 1 // (void *, size_t, uint32_t, uint16_t, chreMessageFreeFunction *) -> bool
+#define SYSCALL_CHRE_MAIN_EVENT_INFO_BY_APP_ID 2 // (uint64_t, struct chreNanoappInfo *) -> bool
+#define SYSCALL_CHRE_MAIN_EVENT_INFO_BY_INST_ID 3 // (uint32_t, struct chreNanoappInfo *) -> bool
+#define SYSCALL_CHRE_MAIN_EVENT_CFG_INFO 4 // (bool) -> void
+#define SYSCALL_CHRE_MAIN_EVENT_LAST 5 // always last. holes are allowed, but not immediately before this
+
+//level 2 indices in the CHRE.drivers table
+#define SYSCALL_CHRE_DRV_GNSS 0
+#define SYSCALL_CHRE_DRV_WIFI 1
+#define SYSCALL_CHRE_DRV_WWAN 2
+#define SYSCALL_CHRE_DRV_LAST 3 // always last. holes are allowed, but not immediately before this
+
+//level 3 indices in the CHRE.drivers.gnss table
+#define SYSCALL_CHRE_DRV_GNSS_GET_CAP 0 // (void) -> uint32_t
+#define SYSCALL_CHRE_DRV_GNSS_LOC_START_ASYNC 1 // (uint32_t, uint32_t const void *) -> bool
+#define SYSCALL_CHRE_DRV_GNSS_LOC_STOP_ASYNC 2 // (const void *) -> bool
+#define SYSCALL_CHRE_DRV_GNSS_MEAS_START_ASYNC 3 // (uint32_t, const void *) -> bool
+#define SYSCALL_CHRE_DRV_GNSS_MEAS_STOP_ASYNC 4 // (const void *) -> bool
+#define SYSCALL_CHRE_DRV_GNSS_LAST 5 // always last. holes are allowed, but not immediately before this
+
+//level 3 indices in the CHRE.drivers.wifi table
+#define SYSCALL_CHRE_DRV_WIFI_GET_CAP 0 // (void) -> uint32_t
+#define SYSCALL_CHRE_DRV_WIFI_CONF_SCAN_MON_ASYNC 1 // (bool, const void *) -> bool
+#define SYSCALL_CHRE_DRV_WIFI_REQ_SCAN_ASYNC 2 // (const struct chreWifiScanParams *, const void *) -> bool
+#define SYSCALL_CHRE_DRV_WIFI_LAST 3 // always last. holes are allowed, but not immediately before this
+
+//level 3 indices in the CHRE.drivers.wwan table
+#define SYSCALL_CHRE_DRV_WWAN_GET_CAP 0 // (void) -> uint32_t
+#define SYSCALL_CHRE_DRV_WWAN_GET_CELL_INFO_ASYNC 1 // (const void *cookie) -> bool
+#define SYSCALL_CHRE_DRV_WWAN_LAST 2 // always last. holes are allowed, but not immediately before this
//called by os entry point to export the api
void osChreApiExport(void);
diff --git a/firmware/os/inc/eventnums.h b/firmware/os/inc/eventnums.h
index 246587a3..5746433e 100644
--- a/firmware/os/inc/eventnums.h
+++ b/firmware/os/inc/eventnums.h
@@ -29,8 +29,10 @@
#define EVT_APP_TO_HOST 0x00000401 //app data to host. Type is struct HostHubRawPacket
#define EVT_MARSHALLED_SENSOR_DATA 0x00000402 //marshalled event data. Type is MarshalledUserEventData
#define EVT_RESET_REASON 0x00000403 //reset reason to host.
-#define EVT_APP_TO_SENSOR_HAL_DATA 0x00000404 // sensor driver out of band data update to sensor hal
-#define EVT_DEBUG_LOG 0x00007F01 // send message payload to Linux kernel log
+#define EVT_APP_TO_SENSOR_HAL_DATA 0x00000404 //sensor driver out of band data update to sensor hal
+#define EVT_APP_STARTED 0x00000405 //sent when a app has successfully started
+#define EVT_APP_STOPPED 0x00000406 //sent when a app has stopped
+#define EVT_DEBUG_LOG 0x00007F01 //send message payload to Linux kernel log
#define EVT_MASK 0x0000FFFF
// host-side events are 32-bit
@@ -54,9 +56,17 @@ struct HostHubRawPacket {
SET_PACKED_STRUCT_MODE_OFF
SET_PACKED_STRUCT_MODE_ON
+struct NanohubMsgChreHdrV10 {
+ uint8_t size;
+ uint32_t appEvent;
+}ATTRIBUTE_PACKED;
+SET_PACKED_STRUCT_MODE_OFF
+
+SET_PACKED_STRUCT_MODE_ON
struct NanohubMsgChreHdr {
uint8_t size;
uint32_t appEvent;
+ uint16_t endpoint;
}ATTRIBUTE_PACKED;
SET_PACKED_STRUCT_MODE_OFF
@@ -103,17 +113,18 @@ SET_PACKED_STRUCT_MODE_OFF
//for all apps
#define EVT_APP_FREE_EVT_DATA 0x000000FF //sent to an external app when its event has been marked for freeing. Data: struct AppEventFreeData
// this event is never enqueued; it goes directly to the app.
-// It notifies app that hav outstanding IO, that is is about to end;
+// It notifies app that have outstanding IO, that is is about to end;
// Expected app behavior is to not send any more events to system;
// any events sent after this point will be silently ignored by the system;
-// any outstading events will be allowed to proceed to completion. (this is SIG_STOP)
+// any outstanding events will be allowed to proceed to completion. (this is SIG_STOP)
#define EVT_APP_STOP 0x000000FE
// Internal event, with task pointer as event data;
// system ends the task unconditionally; no further checks performed (this is SIG_KILL)
#define EVT_APP_END 0x000000FD
+#define EVT_APP_BEGIN 0x000000FC
//for host comms
-#define EVT_APP_FROM_HOST 0x000000F8 //host data to an app. Type is struct HostMsgHdr
#define EVT_APP_FROM_HOST_CHRE 0x000000F9 //host data to an app. Type is struct HostMsgHdrChre
+#define EVT_APP_FROM_HOST 0x000000F8 //host data to an app. Type is struct HostMsgHdr
//for apps that use I2C
#define EVT_APP_I2C_CBK 0x000000F0 //data pointer points to struct I2cEventData
diff --git a/firmware/os/inc/nanohubCommand.h b/firmware/os/inc/nanohubCommand.h
index 0c4c5220..408cffdc 100644
--- a/firmware/os/inc/nanohubCommand.h
+++ b/firmware/os/inc/nanohubCommand.h
@@ -41,5 +41,6 @@ struct NanohubHalCommand {
const struct NanohubHalCommand *nanohubHalFindCommand(uint8_t msg);
uint64_t hostGetTime(void);
+int64_t hostGetTimeDelta(void);
#endif /* __NANOHUBCOMMAND_H */
diff --git a/firmware/os/inc/osApi.h b/firmware/os/inc/osApi.h
index 77cff48f..03f91264 100644
--- a/firmware/os/inc/osApi.h
+++ b/firmware/os/inc/osApi.h
@@ -17,11 +17,8 @@
#ifndef _OS_API_H_
#define _OS_API_H_
-#include <stdint.h>
#include <slab.h>
-#include <seos_priv.h>
-
//EXTERNAL API
//level 1 indices in the OS table
#define SYSCALL_OS_MAIN 0
@@ -127,8 +124,5 @@
//called by os entry point to export the api
void osApiExport(struct SlabAllocator *mainSlubAllocator);
-
-
-
#endif
diff --git a/firmware/os/inc/sensors.h b/firmware/os/inc/sensors.h
index 7074a258..19fd3ecc 100644
--- a/firmware/os/inc/sensors.h
+++ b/firmware/os/inc/sensors.h
@@ -281,6 +281,8 @@ bool sensorSelfTest(uint32_t sensorHandle);
bool sensorCfgData(uint32_t sensorHandle, void* cfgData);
uint32_t sensorGetCurRate(uint32_t sensorHandle);
uint64_t sensorGetCurLatency(uint32_t sensorHandle);
+uint32_t sensorGetHwRate(uint32_t sensorHandle);
+uint64_t sensorGetHwLatency(uint32_t sensorHandle);
uint32_t sensorGetReqRate(uint32_t sensorHandle);
uint64_t sensorGetReqLatency(uint32_t sensorHandle);
uint64_t sensorGetTime(void);
diff --git a/firmware/os/inc/seos.h b/firmware/os/inc/seos.h
index 7979d762..2b52b5c9 100644
--- a/firmware/os/inc/seos.h
+++ b/firmware/os/inc/seos.h
@@ -126,6 +126,12 @@ struct AppEventFreeData { //goes with EVT_APP_FREE_EVT_DATA
void* evtData;
};
+struct AppEventStartStop {
+ uint64_t appId;
+ uint32_t version;
+ uint16_t tid;
+};
+
typedef void (*OsDeferCbkF)(void *);
typedef void (*EventFreeF)(void* event);
@@ -262,11 +268,13 @@ bool osEraseShared();
bool osRetainCurrentEvent(TaggedPtr *evtFreeingInfoP); //called from any apps' event handling to retain current event. Only valid for first app that tries. evtFreeingInfoP filled by call and used to free evt later
void osFreeRetainedEvent(uint32_t evtType, void *evtData, TaggedPtr *evtFreeingInfoP);
-uint32_t osExtAppStopApps(uint64_t appId);
-uint32_t osExtAppEraseApps(uint64_t appId);
-uint32_t osExtAppStartApps(uint64_t appId);
+uint32_t osExtAppStopAppsByAppId(uint64_t appId);
+uint32_t osExtAppEraseAppsByAppId(uint64_t appId);
+uint32_t osExtAppStartAppsByAppId(uint64_t appId);
+uint32_t osExtAppStartAppsDelayed();
bool osAppIsChre(uint16_t tid);
+uint32_t osAppChreVersion(uint16_t tid);
/* Logging */
enum LogLevel {
diff --git a/firmware/os/inc/seos_priv.h b/firmware/os/inc/seos_priv.h
index e2dd7643..862d5224 100644
--- a/firmware/os/inc/seos_priv.h
+++ b/firmware/os/inc/seos_priv.h
@@ -19,6 +19,7 @@
#include <inttypes.h>
#include <seos.h>
+#include <chre.h>
#define NO_NODE (TaskIndex)(-1)
#define for_each_task(listHead, task) for (task = osTaskByIdx((listHead)->next); task; task = osTaskByIdx(task->list.next))
@@ -26,6 +27,7 @@
#define TID_TO_TASK_IDX(tid) (tid & TASK_TID_IDX_MASK)
#define FL_TASK_STOPPED 1
+#define FL_TASK_ABORTED 2
#define EVT_SUBSCRIBE_TO_EVT 0x00000000
#define EVT_UNSUBSCRIBE_TO_EVT 0x00000001
@@ -108,6 +110,8 @@ union SeosInternalSlabData {
union OsApiSlabItem osApiItem;
};
+typedef bool (*appMatchFunc)(const void *cookie, const struct AppHdr *);
+
uint8_t osTaskIndex(struct Task *task);
struct Task *osGetCurrentTask();
struct Task *osSetCurrentTask(struct Task *task);
@@ -122,6 +126,19 @@ static inline bool osTaskIsChre(const struct Task *task)
return task->app && (task->app->hdr.fwFlags & FL_APP_HDR_CHRE) != 0;
}
+static inline uint32_t osTaskChreVersion(const struct Task *task)
+{
+ if (osTaskIsChre(task)) {
+ // Apps loaded on 1.0 stored 0xFF in both rfu bytes
+ if (task->app->hdr.chreApiMajor == 0xFF && task->app->hdr.chreApiMinor == 0xFF)
+ return CHRE_API_VERSION_1_0;
+ else
+ return task->app->hdr.chreApiMajor << 24 | task->app->hdr.chreApiMinor << 16;
+ } else {
+ return 0;
+ }
+}
+
static inline void osTaskMakeNewTid(struct Task *task)
{
task->tid = ((task->tid + TASK_TID_INCREMENT) & TASK_TID_COUNTER_MASK) |
diff --git a/inc/chre.h b/inc/chre.h
deleted file mode 100644
index 5f454984..00000000
--- a/inc/chre.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CHRE_H_
-#define _CHRE_H_
-
-/**
- * This header file includes all the headers which combine to fully defined
- * the interface for the Context Hub Runtime Environment (CHRE). This is the
- * environment in which a nanoapp runs.
- *
- * This interface is of interest to both implementors of CHREs and
- * authors of nanoapps. The API documentation attempts to address concerns
- * of both.
- *
- * See individual header files for API specific, and general comments below
- * for overall platform information.
- */
-
-#include <chre/event.h>
-#include <chre/nanoapp.h>
-#include <chre/re.h>
-#include <chre/sensor.h>
-#include <chre/version.h>
-
-
-/**
- * Entry points.
- *
- * The following entry points are required to be handled by the CHRE
- * implementation, and the functions must all be implemented by nanoapps.
- * o nanoappStart function (see chre_nanoapp.h)
- * o nanoappHandleEvent function (see chre_nanoapp.h)
- * o nanoappEnd function (see chre_nanoapp.h)
- * o bss section zeroed out (prior to nanoappStart)
- * o static variables initialized (prior to nanoappStart)
- * o global C++ constructors called (prior to nanoappStart)
- * o global C++ destructors called (after nanoappEnd)
- */
-
-
-/**
- * Threading model.
- *
- * A CHRE implementation is free to chose among many different
- * threading models, including a single threaded system or a multi-threaded
- * system with preemption. The current platform definition is agnostic to this
- * underlying choice [1].
- *
- * However, the Platform does require that all nanoapps are treated as
- * non-reentrant. That is, any of the functions of the nanoapp, including
- * the entry points defined above and the memory freeing callbacks defined
- * below, cannot be invoked by the CHRE if a previous invocation
- * hasn't completed. Note this means no nanoapp function can be invoked
- * from an interrupt context.
- *
- * For example, if a nanoapp is currently in nanoappHandleEvent(), the CHRE is
- * not allowed to call nanoappHandleEvent() again, or to call a memory freeing
- * callback. Similarly, if a nanoapp is currently in a memory freeing
- * callback, the CHRE is not allowed to call nanoappHandleEvent(), or invoke
- * another memory freeing callback.
- *
- * There are two exceptions to this rule: If an invocation of chreSendEvent()
- * fails (returns 'false'), it is allowed to immediately invoke the memory
- * freeing callback passed into that function. This is a rare case, and one
- * where otherwise a CHRE implementation is likely to leak memory. Similarly,
- * chreSendMessageToHost() is allowed to invoke the memory freeing callback
- * directly, whether it returns 'true' or 'false'. This is because the CHRE
- * implementation may copy the message data to its own buffer, and therefore
- * wouldn't need the nanoapp-supplied buffer after chreSendMessageToHost()
- * returns.
- *
- * For a nanoapp author, this means no thought needs to be given to
- * synchronization issues with global objects, as they will, by definition,
- * only be accessed by a single thread at once.
- *
- *
- * [1] Note to CHRE implementors: A future version of the CHRE platform may
- * require multi-threading with preemption. This is mentioned as a heads up,
- * and to allow implementors deciding between implementation approaches to
- * make the most informed choice.
- */
-
-/**
- * Notes on timing.
- *
- * Nanoapps should expect to be running on a highly constrained system, with
- * little memory and little CPU. Any single nanoapp should expect to
- * be one of several nanoapps on the system, which also share the CPU with the
- * CHRE and possibly other services as well.
- *
- * Thus, a nanoapp needs to be efficient in its memory and CPU usage.
- * Also, as noted in the Threading Model section, a CHRE implementation may
- * be single threaded. As a result, all methods invoked in a nanoapp
- * (like nanoappStart, nanoappHandleEvent, memory free callbacks, etc.)
- * must run "quickly". "Quickly" is difficult to define, as there is a
- * diversity of Context Hub hardware. For Android N, there is no firm
- * definition of "quickly", but expect this term to gain definition in
- * future releases as we get feedback from partners.
- *
- * In order to write a nanoapp that will be able to adopt to future
- * stricter notions of "quickly", all nanoapp methods should be written so
- * they execute in a small amount of time. Some nanoapps may have the need
- * to occasionally perform a large block of calculations, which may seem
- * to violate this. The recommended approach in this case is to
- * split up the large block of calculations into smaller batches. In one
- * call into the nanoapp, the nanoapp can perform the first batch, and then
- * send an event (chreSendEvent()) to itself indicating which batch should be
- * done next. This will allow the nanoapp to perform the entire calculation
- * over time, without monopolizing system resources.
- */
-
-/**
- * Floating point support.
- *
- * The C type 'float' is used in this API, and thus a CHRE implementation
- * is required to support 'float's.
- *
- * Support of the C types 'double' and 'long double' is optional for a
- * CHRE implementation. Note that if a CHRE decides to support them, unlike
- * 'float' support, there is no requirement that this support is particularly
- * efficient. So nanoapp authors should be aware this may be inefficient.
- *
- * If a CHRE implementation choses not to support 'double' or
- * 'long double', then the build toolchain setup provided needs to set
- * the preprocessor define CHRE_NO_DOUBLE_SUPPORT.
- */
-
-/**
- * CHRE and Nanoapp compatibility.
- *
- * The Android N release introduces the first version of this API.
- * It is anticipated that there will be a lot of feedback from
- * Android partners on this initial API. To allow more flexibility
- * in addressing that feedback, there is no plan to assure
- * binary compatibility between the Android N and Android O CHRE
- * implementations and nanoapps.
- *
- * That is, a nanoapp built with the Android O version of this
- * API should not expect to run on a CHRE built with
- * the Android N API. Similarly, a nanoapp build with the
- * Android N API should not expect to run on a CHRE
- * build with the Android O API. Such a nanoapp will need to
- * recompiled with the appropriate API in order to work.
- */
-
-#endif /* _CHRE_H_ */
-
diff --git a/inc/chre/event.h b/inc/chre/event.h
deleted file mode 100644
index 0f088bb8..00000000
--- a/inc/chre/event.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CHRE_EVENT_H_
-#define _CHRE_EVENT_H_
-
-/**
- * Context Hub Runtime Environment API dealing with events and messages.
- */
-
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * The CHRE implementation is required to provide the following
- * preprocessor defines via the build system.
- *
- * CHRE_MESSAGE_TO_HOST_MAX_SIZE: The maximum size, in bytes, allowed for
- * a message sent to chreSendMessageToHost(). This must be at least
- * CHRE_MESSAGE_TO_HOST_MINIMUM_MAX_SIZE.
- */
-
-#ifndef CHRE_MESSAGE_TO_HOST_MAX_SIZE
-#error CHRE_MESSAGE_TO_HOST_MAX_SIZE must be defined by the Context Hub Runtime Environment implementation
-#endif
-
-/**
- * The minimum size, in bytes, any CHRE implementation will
- * use for CHRE_MESSAGE_TO_HOST_MAX_SIZE.
- */
-#define CHRE_MESSAGE_TO_HOST_MINIMUM_MAX_SIZE 128
-
-#if CHRE_MESSAGE_TO_HOST_MAX_SIZE < CHRE_MESSAGE_TO_HOST_MINIMUM_MAX_SIZE
-#error CHRE_MESSAGE_TO_HOST_MAX_SIZE is too small.
-#endif
-
-/**
- * The lowest numerical value legal for a user-defined event.
- *
- * The system reserves all event values from 0 to 0x7FFF, inclusive.
- * User events may use any value in the range 0x8000 to 0xFFFF, inclusive.
- *
- * Note that the same event values might be used by different nanoapps
- * for different meanings. This is not a concern, as these values only
- * have meaning when paired with the originating nanoapp.
- */
-#define CHRE_EVENT_FIRST_USER_VALUE UINT16_C(0x8000)
-
-/**
- * nanoappHandleEvent argument: struct chreMessageFromHostData
- *
- * The format of the 'message' part of this structure is left undefined,
- * and it's up to the nanoapp and host to have an established protocol
- * beforehand.
- */
-#define CHRE_EVENT_MESSAGE_FROM_HOST UINT16_C(0x0001)
-
-/**
- * nanoappHandleEvent argument: 'cookie' given to chreTimerSet() method.
- *
- * Indicates that a timer has elapsed, in accordance with how chreTimerSet() was
- * invoked.
- */
-#define CHRE_EVENT_TIMER UINT16_C(0x0002)
-
-/**
- * First possible value for CHRE_EVENT_SENSOR events.
- *
- * This allows us to separately define our CHRE_EVENT_SENSOR_* events in
- * chre_sensor.h, without fear of collision with other event values.
- */
-#define CHRE_EVENT_SENSOR_FIRST_EVENT UINT16_C(0x0100)
-
-/**
- * Last possible value for CHRE_EVENT_SENSOR events.
- *
- * This allows us to separately define our CHRE_EVENT_SENSOR_* events in
- * chre_sensor.h, without fear of collision with other event values.
- */
-#define CHRE_EVENT_SENSOR_LAST_EVENT UINT16_C(0x02FF)
-
-/**
- * First in a range of values dedicated for internal CHRE implementation usage.
- *
- * If a CHRE wishes to use events internally, any values within this range
- * are assured not to be taken by future CHRE API additions.
- */
-#define CHRE_EVENT_INTERNAL_FIRST_EVENT UINT16_C(0x7E00)
-
-/**
- * Last in a range of values dedicated for internal CHRE implementation usage.
- *
- * If a CHRE wishes to use events internally, any values within this range
- * are assured not to be taken by future CHRE API additions.
- */
-#define CHRE_EVENT_INTERNAL_LAST_EVENT UINT16_C(0x7FFF)
-
-
-/**
- * CHRE_EVENT_MESSAGE_FROM_HOST
- */
-struct chreMessageFromHostData {
- /**
- * Message type (NOTE: not implemented correctly in the Android N release).
- *
- * In future releases, this will be a message type provided by the host.
- */
- uint32_t reservedMessageType;
-
- /**
- * The size, in bytes of the following 'message'.
- *
- * This can be 0.
- */
- uint32_t messageSize;
-
- /**
- * The message from the host.
- *
- * These contents are of a format that the host and nanoapp must have
- * established beforehand.
- *
- * This data is 'messageSize' bytes in length. Note that if 'messageSize'
- * is 0, this might be NULL.
- */
- const void *message;
-};
-
-/**
- * Callback which frees data associated with an event.
- *
- * This callback is (optionally) provided to the chreSendEvent() method as
- * a means for freeing the event data and performing any other cleanup
- * necessary when the event is completed. When this callback is invoked,
- * 'eventData' is no longer needed and can be released.
- *
- * @param eventType The 'eventType' argument from chreSendEvent().
- * @param eventData The 'eventData' argument from chreSendEvent().
- *
- * @see chreSendEvent
- */
-typedef void (chreEventCompleteFunction)(uint16_t eventType, void *eventData);
-
-/**
- * Callback which frees a message.
- *
- * This callback is (optionally) provided to the chreSendMessageToHost() method
- * as a means for freeing the message. When this callback is invoked,
- * 'message' is no longer needed and can be released. Note that this in
- * no way assures that said message did or did not make it to the host, simply
- * that this memory is no longer needed.
- *
- * @param message The 'message' argument from chreSendMessageToHost().
- * @param messageSize The 'messageSize' argument from chreSendMessageToHost().
- *
- * @see chreSendMessageToHost
- */
-typedef void (chreMessageFreeFunction)(void *message, size_t messageSize);
-
-
-
-/**
- * Enqueue an event to be sent to another nanoapp.
- *
- * Note: This version of the API does not give an easy means to discover
- * another nanoapp's instance ID. For now, events will need to be sent to/from
- * the host to initially discover these IDs.
- *
- * @param eventType This is a user-defined event type, of at least the
- * value CHRE_EVENT_FIRST_USER_VALUE. It is illegal to attempt to use any
- * of the CHRE_EVENT_* values reserved for the CHRE.
- * @param eventData A pointer value that will be understood by the receiving
- * app. Note that NULL is perfectly acceptable. It also is not required
- * that this be a valid pointer, although if this nanoapp is intended to
- * work on arbitrary CHRE implementations, then the size of a
- * pointer cannot be assumed to be a certain size. Note that the caller
- * no longer owns this memory after the call.
- * @param freeCallback A pointer to a callback function. After the lifetime
- * of 'eventData' is over (either through successful delivery or the event
- * being dropped), this callback will be invoked. This argument is allowed
- * to be NULL, in which case no callback will be invoked.
- * @param targetInstanceId The ID of the instance we're delivering this event
- * to. Note that this is allowed to be our own instance.
- * @returns true if the event was enqueued, false otherwise. Note that even
- * if this method returns 'false', the 'freeCallback' will be invoked,
- * if non-NULL. Note in the 'false' case, the 'freeCallback' may be
- * invoked directly from within chreSendEvent(), so it's necessary
- * for nanoapp authors to avoid possible recursion with this.
- *
- * @see chreEventDataFreeFunction
- */
-bool chreSendEvent(uint16_t eventType, void *eventData,
- chreEventCompleteFunction *freeCallback,
- uint32_t targetInstanceId);
-
-/**
- * Send a message to the host.
- *
- * This message is by definition arbitrarily defined. Since we're not
- * just a passing a pointer to memory around the system, but need to copy
- * this into various buffers to send it to the host, the CHRE
- * implementation cannot be asked to support an arbitrarily large message
- * size. As a result, we have the CHRE implementation define
- * CHRE_MESSAGE_TO_HOST_MAX_SIZE.
- *
- * CHRE_MESSAGE_TO_HOST_MAX_SIZE is not given a value by the Platform API. The
- * Platform API does define CHRE_MESSAGE_TO_HOST_MINIMUM_MAX_SIZE, and requires
- * that CHRE_MESSAGE_TO_HOST_MAX_SIZE is at least that value.
- *
- * As a result, if your message sizes are all less than
- * CHRE_MESSAGE_TO_HOST_MINIMUM_MAX_SIZE, then you have no concerns on any
- * CHRE implementation. If your message sizes are larger, you'll need to
- * come up with a strategy for splitting your message across several calls
- * to this method. As long as that strategy works for
- * CHRE_MESSAGE_TO_HOST_MINIMUM_MAX_SIZE, it will work across all CHRE
- * implementations (although on some implementations less calls to this
- * method may be necessary).
- *
- * @param message Pointer to a block of memory to send to the host.
- * NULL is acceptable only if messageSize is 0. If non-NULL, this
- * must be a legitimate pointer (that is, unlike chreSendEvent(), a small
- * integral value cannot be cast to a pointer for this). Note that the
- * caller no longer owns this memory after the call.
- * @param messageSize The size, in bytes, of the given message.
- * This cannot exceed CHRE_MESSAGE_TO_HOST_MAX_SIZE.
- * @param reservedMessageType Message type sent to the app on the host.
- * NOTE: In the N release, there is a bug in some HAL implementations
- * where this data does not make it to the app running on the host.
- * Nanoapps cannot trust this across all platforms for N, but that
- * will be fixed in O.
- * @param freeCallback A pointer to a callback function. After the lifetime
- * of 'message' is over (which does not assure that 'message' made it to
- * the host, just that the transport layer no longer needs this memory),
- * this callback will be invoked. This argument is allowed
- * to be NULL, in which case no callback will be invoked.
- * @returns true if the message was accepted for transmission, false otherwise.
- * Note that even if this method returns 'false', the 'freeCallback' will
- * be invoked, if non-NULL. In either case, the 'freeCallback' may be
- * invoked directly from within chreSendMessageToHost(), so it's necessary
- * for nanoapp authors to avoid possible recursion with this.
- *
- * @see chreMessageFreeFunction
- */
-bool chreSendMessageToHost(void *message, uint32_t messageSize,
- uint32_t reservedMessageType,
- chreMessageFreeFunction *freeCallback);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CHRE_EVENT_H_ */
-
diff --git a/inc/chre/nanoapp.h b/inc/chre/nanoapp.h
deleted file mode 100644
index 78a8accd..00000000
--- a/inc/chre/nanoapp.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CHRE_NANOAPP_H_
-#define _CHRE_NANOAPP_H_
-
-/**
- * Methods in the Context Hub Runtime Environment which must be implemented
- * by the nanoapp.
- */
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Method invoked by the CHRE when loading the nanoapp.
- *
- * Every CHRE method is legal to call from this method.
- *
- * @returns 'true' if the nanoapp successfully started. 'false' if the nanoapp
- * failed to properly initialize itself (for example, could not obtain
- * sufficient memory from the heap). If this method returns 'false', the
- * nanoapp will be unloaded by the CHRE (and nanoappEnd will
- * _not_ be invoked in that case).
- * @see nanoappEnd
- */
-bool nanoappStart(void);
-
-/**
- * Method invoked by the CHRE when there is an event for this nanoapp.
- *
- * Every CHRE method is legal to call from this method.
- *
- * @param senderInstanceId The Instance ID for the source of this event.
- * Note that this may be CHRE_INSTANCE_ID, indicating that the event
- * was generated by the CHRE.
- * @param eventType The event type. This might be one of the CHRE_EVENT_*
- * types defined in this API. But it might also be a user-defined event.
- * @param eventData The associated data, if any, for this specific type of
- * event. From the nanoapp's perspective, this eventData's lifetime ends
- * when this method returns, and thus any data the nanoapp wishes to
- * retain must be copied. Note that interpretation of event data is
- * given by the event type, and for some events may not be a valid
- * pointer. See documentation of the specific CHRE_EVENT_* types for how to
- * interpret this data for those. Note that for user events, you will
- * need to establish what this data means.
- */
-void nanoappHandleEvent(uint32_t senderInstanceId, uint16_t eventType,
- const void* eventData);
-
-/**
- * Method invoked by the CHRE when unloading the nanoapp.
- *
- * It is not valid to attempt to send events or messages, or to invoke functions
- * which will generate events to this app, within the nanoapp implementation of
- * this function. That means it is illegal for the nanoapp invoke any of the
- * following:
- * - chreSendEvent()
- * - chreSendMessageToHost()
- * - chreSensorConfigure()
- * - chreSensorConfigureModeOnly()
- * - chreTimerSet()
- *
- * @see nanoappStart
- */
-void nanoappEnd(void);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CHRE_NANOAPP_H_ */
diff --git a/inc/chre/re.h b/inc/chre/re.h
deleted file mode 100644
index 31b0ed7c..00000000
--- a/inc/chre/re.h
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CHRE_RE_H_
-#define _CHRE_RE_H_
-
-/**
- * Some of the core Runtime Environment utilities of the Context Hub
- * Runtime Environment.
- *
- * This includes functions for memory allocation, logging, and timers.
- */
-
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * The instance ID for the CHRE.
- *
- * This ID is used to identify events generated by the CHRE (as
- * opposed to events generated by another nanoapp).
- */
-#define CHRE_INSTANCE_ID UINT32_C(0)
-
-/**
- * A timer ID representing an invalid timer.
- *
- * This valid is returned by chreTimerSet() if a timer cannot be
- * started.
- */
-#define CHRE_TIMER_INVALID UINT32_C(-1)
-
-
-
-/**
- * Logging levels used to indicate severity level of logging messages.
- *
- * CHRE_LOG_ERROR: Something fatal has happened, i.e. something that will have
- * user-visible consequences and won't be recoverable without explicitly
- * deleting some data, uninstalling applications, wiping the data
- * partitions or reflashing the entire phone (or worse).
- * CHRE_LOG_WARN: Something that will have user-visible consequences but is
- * likely to be recoverable without data loss by performing some explicit
- * action, ranging from waiting or restarting an app all the way to
- * re-downloading a new version of an application or rebooting the device.
- * CHRE_LOG_INFO: Something interesting to most people happened, i.e. when a
- * situation is detected that is likely to have widespread impact, though
- * isn't necessarily an error.
- * CHRE_LOG_DEBUG: Used to further note what is happening on the device that
- * could be relevant to investigate and debug unexpected behaviors. You
- * should log only what is needed to gather enough information about what
- * is going on about your component.
- *
- * There is currently no API to turn on/off logging by level, but we anticipate
- * adding such in future releases.
- *
- * @see chreLog
- */
-enum chreLogLevel {
- CHRE_LOG_ERROR,
- CHRE_LOG_WARN,
- CHRE_LOG_INFO,
- CHRE_LOG_DEBUG
-};
-
-
-
-/**
- * Get the application ID.
- *
- * The application ID is set by the loader of the nanoapp. This is not
- * assured to be unique among all nanoapps running in the system.
- *
- * @returns The application ID.
- */
-uint64_t chreGetAppId(void);
-
-/**
- * Get the instance ID.
- *
- * The instance ID is the CHRE handle to this nanoapp. This is assured
- * to be unique among all nanoapps running in the system, and to be
- * different from the CHRE_INSTANCE_ID. This is the ID used to communicate
- * between nanoapps.
- *
- * @returns The instance ID
- */
-uint32_t chreGetInstanceId(void);
-
-/**
- * A method for logging information about the system.
- *
- * A log entry can have a variety of levels (@see LogLevel). This function
- * allows a variable number of arguments, in a printf-style format.
- *
- * A nanoapp needs to be able to rely upon consistent printf format
- * recognition across any platform, and thus we establish formats which
- * are required to be handled by every CHRE implementation. Some of the
- * integral formats may seem obscure, but this API heavily uses types like
- * uint32_t and uint16_t. The platform independent macros for those printf
- * formats, like PRId32 or PRIx16, end up using some of these "obscure"
- * formats on some platforms, and thus are required.
- *
- * For the initial N release, our emphasis is on correctly getting information
- * into the log, and minimizing the requirements for CHRE implementations
- * beyond that. We're not as concerned about how the information is visually
- * displayed. As a result, there are a number of format sub-specifiers which
- * are "OPTIONAL" for the N implementation. "OPTIONAL" in this context means
- * that a CHRE implementation is allowed to essentially ignore the specifier,
- * but it must understand the specifier enough in order to properly skip it.
- *
- * For a nanoapp author, an OPTIONAL format means you might not get exactly
- * what you want on every CHRE implementation, but you will always get
- * something sane.
- *
- * To be clearer, here's an example with the OPTIONAL 0-padding for integers
- * for different hypothetical CHRE implementations.
- * Compliant, chose to implement OPTIONAL format:
- * chreLog(level, "%04x", 20) ==> "0014"
- * Compliant, chose not to implement OPTIONAL format:
- * chreLog(level, "%04x", 20) ==> "14"
- * Non-compliant, discarded format because the '0' was assumed to be incorrect:
- * chreLog(level, "%04x", 20) ==> ""
- *
- * Note that some of the OPTIONAL specifiers will probably become
- * required in future APIs.
- *
- * We also have NOT_SUPPORTED specifiers. Nanoapp authors should not use any
- * NOT_SUPPORTED specifiers, as unexpected things could happen on any given
- * CHRE implementation. A CHRE implementation is allowed to support this
- * (for example, when using shared code which already supports this), but
- * nanoapp authors need to avoid these.
- *
- *
- * Unless specifically noted as OPTIONAL or NOT_SUPPORTED, format
- * (sub-)specifiers listed below are required.
- *
- * OPTIONAL format sub-specifiers:
- * - '-' (left-justify within the given field width)
- * - '+' (preceed the result with a '+' sign if it is positive)
- * - ' ' (preceed the result with a blank space if no sign is going to be
- * output)
- * - '#' (For 'o', 'x' or 'X', preceed output with "0", "0x" or "0X",
- * respectively. For floating point, unconditionally output a decimal
- * point.)
- * - '0' (left pad the number with zeroes instead of spaces when <width>
- * needs padding)
- * - <width> (A number representing the minimum number of characters to be
- * output, left-padding with blank spaces if needed to meet the
- * minimum)
- * - '.'<precision> (A number which has different meaning depending on context.)
- * - Integer context: Minimum number of digits to output, padding with
- * leading zeros if needed to meet the minimum.
- * - 'f' context: Number of digits to output after the decimal
- * point (to the right of it).
- * - 's' context: Maximum number of characters to output.
- *
- * Integral format specifiers:
- * - 'd' (signed)
- * - 'u' (unsigned)
- * - 'o' (octal)
- * - 'x' (hexadecimal, lower case)
- * - 'X' (hexadecimal, upper case)
- *
- * Integral format sub-specifiers (as prefixes to an above integral format):
- * - 'hh' (char)
- * - 'h' (short)
- * - 'l' (long)
- * - 'll' (long long)
- * - 'z' (size_t)
- * - 't' (ptrdiff_t)
- *
- * Other format specifiers:
- * - 'f' (floating point)
- * - 'c' (character)
- * - 's' (character string, terminated by '\0')
- * - 'p' (pointer)
- * - '%' (escaping the percent sign (i.e. "%%" becomes "%"))
- *
- * NOT_SUPPORTED specifiers:
- * - 'n' (output nothing, but fill in a given pointer with the number
- * of characters written so far)
- * - '*' (indicates that the width/precision value comes from one of the
- * arguments to the function)
- * - 'e', 'E' (scientific notation output)
- * - 'g', 'G' (Shortest floating point representation)
- *
- * @param level The severity level for this message.
- * @param formatStr Either the entirety of the message, or a printf-style
- * format string of the format documented above.
- * @param ... A variable number of arguments necessary for the given
- * 'formatStr' (there may be no additional arguments for some 'formatStr's).
- */
-void chreLog(enum chreLogLevel level, const char *formatStr, ...);
-
-/**
- * Get the system time.
- *
- * This returns a time in nanoseconds in reference to some arbitrary
- * time in the past. This method is only useful for determining timing
- * between events on the system, and is not useful for determining
- * any sort of absolute time.
- *
- * This value must always increase (and must never roll over). This
- * value has no meaning across CHRE reboots.
- *
- * @returns The system time, in nanoseconds.
- */
-uint64_t chreGetTime(void);
-
-/**
- * Set a timer.
- *
- * When the timer fires, nanoappHandleEvent will be invoked with
- * CHRE_EVENT_TIMER and with the given 'cookie'.
- *
- * A CHRE implementation is required to provide at least 32
- * timers. However, there's no assurance there will be any available
- * for any given nanoapp (if it's loaded late, etc).
- *
- * @param duration Time, in nanoseconds, before the timer fires.
- * @param cookie Argument that will be sent to nanoappHandleEvent upon the
- * timer firing. This is allowed to be NULL and does not need to be
- * a valid pointer (assuming the nanoappHandleEvent code is expecting such).
- * @param oneShot If true, the timer will just fire once. If false, the
- * timer will continue to refire every 'duration', until this timer is
- * canceled (@see chreTimerCancel).
- *
- * @returns The timer ID. If the system is unable to set a timer
- * (no more available timers, etc.) then CHRE_TIMER_INVALID will
- * be returned.
- *
- * @see nanoappHandleEvent
- */
-uint32_t chreTimerSet(uint64_t duration, const void* cookie, bool oneShot);
-
-/**
- * Cancel a timer.
- *
- * After this method returns, the CHRE assures there will be no more
- * events sent from this timer, and any enqueued events from this timer
- * will need to be evicted from the queue by the CHRE.
- *
- * @param timerId A timer ID obtained by this nanoapp via chreTimerSet().
- * @returns true if the timer was cancelled, false otherwise. We may
- * fail to cancel the timer if it's a one shot which (just) fired,
- * or if the given timer ID is not owned by the calling app.
- */
-bool chreTimerCancel(uint32_t timerId);
-
-/**
- * Terminate this nanoapp.
- *
- * This takes effect immediately.
- *
- * The CHRE will no longer execute this nanoapp. The CHRE will not invoke
- * nanoappEnd(), nor will it call any memory free callbacks in the nanoapp.
- *
- * The CHRE will unload/evict this nanoapp's code.
- *
- * @param abortCode A value indicating the reason for aborting. (Note that
- * in this version of the API, there is no way for anyone to access this
- * code, but future APIs may expose it.)
- * @returns Never. This method does not return, as the CHRE stops nanoapp
- * execution immediately.
- */
-void chreAbort(uint32_t abortCode);
-
-/**
- * Allocate a given number of bytes from the system heap.
- *
- * The nanoapp is required to free this memory via chreHeapFree() prior to
- * the nanoapp ending.
- *
- * While the CHRE implementation is required to free up heap resources of
- * a nanoapp when unloading it, future requirements and tests focused on
- * nanoapps themselves may check for memory leaks, and will require nanoapps
- * to properly manage their heap resources.
- *
- * @param bytes The number of bytes requested.
- * @returns A pointer to 'bytes' contiguous bytes of heap memory, or NULL
- * if the allocation could not be performed. This pointer must be suitably
- * aligned for any kind of variable.
- *
- * @see chreHeapFree.
- */
-void* chreHeapAlloc(uint32_t bytes);
-
-/**
- * Free a heap allocation.
- *
- * This allocation must be from a value returned from a chreHeapAlloc() call
- * made by this nanoapp. In other words, it is illegal to free memory
- * allocated by another nanoapp (or the CHRE).
- *
- * @param ptr 'ptr' is required to be a value returned from chreHeapAlloc().
- * Note that since chreHeapAlloc can return NULL, CHRE
- * implementations must safely handle 'ptr' being NULL.
- *
- * @see chreHeapAlloc.
- */
-void chreHeapFree(void* ptr);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CHRE_RE_H_ */
-
diff --git a/inc/chre/sensor.h b/inc/chre/sensor.h
deleted file mode 100644
index 9e743363..00000000
--- a/inc/chre/sensor.h
+++ /dev/null
@@ -1,817 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CHRE_SENSOR_H_
-#define _CHRE_SENSOR_H_
-
-/**
- * API dealing with sensor interaction in the Context Hub Runtime
- * Environment.
- *
- * This includes the definition of our sensor types and the ability to
- * configure them for receiving events.
- */
-
-#include <stdbool.h>
-#include <stdint.h>
-
-// For CHRE_EVENT_SENSOR_FIRST_EVENT and CHRE_EVENT_SENSOR_LAST_EVENT
-#include <chre/event.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * The CHRE_SENSOR_TYPE_* defines are the sensor types supported.
- *
- * Unless otherwise noted, each of these sensor types is based off of a
- * corresponding sensor type in the Android API's sensors.h interface.
- * For a given CHRE_SENSOR_TYPE_FOO, it corresponds to the SENSOR_TYPE_FOO in
- * hardware/libhardware/include/hardware/sensors.h of the Android code base.
- *
- * Unless otherwise noted below, a CHRE_SENSOR_TYPE_FOO should be assumed
- * to work the same as the Android SENSOR_TYPE_FOO, as documented in the
- * sensors.h documentation and as detailed within the Android Compatibility
- * Definition Document.
- *
- * Note that every sensor will generate CHRE_EVENT_SENSOR_SAMPLING_CHANGE
- * events, so it is not listed with each individual sensor.
- */
-
-/**
- * Accelerometer.
- *
- * Generates: CHRE_EVENT_SENSOR_ACCELEROMETER_DATA
- *
- * @see CHRE_EVENT_SENSOR_ACCELEROMETER_DATA
- */
-#define CHRE_SENSOR_TYPE_ACCELEROMETER UINT8_C(1)
-
-/**
- * Instantaneous motion detection.
- *
- * Generates: CHRE_EVENT_SENSOR_INSTANT_MOTION_DETECT_DATA
- *
- * This is a one-shot sensor.
- *
- * This does not have a direct analogy within sensors.h. This is similar
- * to SENSOR_TYPE_MOTION_DETECT, but this triggers instantly upon any
- * motion, instead of waiting for a period of continuous motion.
- */
-#define CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT UINT8_C(2)
-
-/**
- * Stationary detection.
- *
- * Generates: CHRE_EVENT_SENSOR_STATIONARY_DETECT_DATA
- *
- * This is a one-shot sensor.
- */
-#define CHRE_SENSOR_TYPE_STATIONARY_DETECT UINT8_C(3)
-
-/**
- * Gyroscope.
- *
- * Generates: CHRE_EVENT_SENSOR_GYROSCOPE_DATA and
- * CHRE_EVENT_SENSOR_GYROSCOPE_BIAS_INFO
- *
- * Note that the GYROSCOPE_DATA is always the calibrated data, and not
- * raw data.
- */
-#define CHRE_SENSOR_TYPE_GYROSCOPE UINT8_C(6)
-
-/**
- * Magnetometer.
- *
- * Generates: CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_DATA and
- * CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_BIAS_INFO
- *
- * Note that the GEOMAGNETIC_FIELD_DATA is always the calibrated data, and not
- * raw data.
- */
-#define CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD UINT8_C(8)
-
-/**
- * Barometric pressure sensor.
- *
- * Generates: CHRE_EVENT_SENSOR_PRESSURE_DATA
- */
-#define CHRE_SENSOR_TYPE_PRESSURE UINT8_C(10)
-
-/**
- * Ambient light sensor.
- *
- * Generates: CHRE_EVENT_SENSOR_LIGHT_DATA
- */
-#define CHRE_SENSOR_TYPE_LIGHT UINT8_C(12)
-
-/**
- * Proximity detection.
- *
- * Generates: CHRE_EVENT_SENSOR_PROXIMITY_DATA
- *
- * This is an on-change sensor.
- */
-#define CHRE_SENSOR_TYPE_PROXIMITY UINT8_C(13)
-
-/**
- * Base value for all of the data events for sensors.
- *
- * The value for a data event FOO is
- * CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_FOO
- *
- * This allows for easy mapping, and also explains why there are gaps
- * in our values since we don't have all possible sensor types assigned.
- */
-#define CHRE_EVENT_SENSOR_DATA_EVENT_BASE CHRE_EVENT_SENSOR_FIRST_EVENT
-
-/**
- * nanoappHandleEvent argument: struct chreSensorThreeAxisData
- *
- * The data can be interpreted using the 'x', 'y', and 'z' fields within
- * 'readings', or by the 3D array 'v' (v[0] == x; v[1] == y; v[2] == z).
- *
- * All values are in SI units (m/s^2) and measure the acceleration of the
- * device minus the force of gravity.
- */
-#define CHRE_EVENT_SENSOR_ACCELEROMETER_DATA \
- (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_ACCELEROMETER)
-
-/**
- * nanoappHandleEvent argument: struct chreSensorOccurrenceData
- *
- * Since this is a one-shot sensor, after this event is delivered to the
- * nanoapp, the sensor automatically goes into DONE mode. Sensors of this
- * type must be configured with a ONE_SHOT mode.
- */
-#define CHRE_EVENT_SENSOR_INSTANT_MOTION_DETECT_DATA \
- (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT)
-
-/**
- * nanoappHandleEvent argument: struct chreSensorOccurrenceData
- *
- * Since this is a one-shot sensor, after this event is delivered to the
- * nanoapp, the sensor automatically goes into DONE mode. Sensors of this
- * type must be configured with a ONE_SHOT mode.
- */
-#define CHRE_EVENT_SENSOR_STATIONARY_DETECT_DATA \
- (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_STATIONARY_DETECT)
-
-/**
- * nanoappHandleEvent argument: struct chreSensorThreeAxisData
- *
- * The data can be interpreted using the 'x', 'y', and 'z' fields within
- * 'readings', or by the 3D array 'v' (v[0] == x; v[1] == y; v[2] == z).
- *
- * All values are in radians/second and measure the rate of rotation
- * around the X, Y and Z axis.
- */
-#define CHRE_EVENT_SENSOR_GYROSCOPE_DATA \
- (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_GYROSCOPE)
-
-/**
- * nanoappHandleEvent argument: struct chreSensorThreeAxisData
- *
- * The data can be interpreted using the 'x', 'y', and 'z' fields within
- * 'readings', or by the 3D array 'v' (v[0] == x; v[1] == y; v[2] == z).
- *
- * All values are in micro-Tesla (uT) and measure the geomagnetic
- * field in the X, Y and Z axis.
- */
-#define CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_DATA \
- (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD)
-
-/**
- * nanoappHandleEvent argument: struct chreSensorFloatData
- *
- * The data can be interpreted using the 'pressure' field within 'readings'.
- * This value is in hectopascals (hPa).
- */
-#define CHRE_EVENT_SENSOR_PRESSURE_DATA \
- (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_PRESSURE)
-
-/**
- * nanoappHandleEvent argument: struct chreSensorFloatData
- *
- * The data can be interpreted using the 'light' field within 'readings'.
- * This value is in SI lux units.
- */
-#define CHRE_EVENT_SENSOR_LIGHT_DATA \
- (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_LIGHT)
-
-/**
- * nanoappHandleEvent argument: struct chreSensorByteData
- *
- * The data is interpreted from the following fields in 'readings':
- * o 'isNear': If set to 1, we are nearby (on the order of centimeters);
- * if set to 0, we are far.
- * o 'invalid': If set to 1, this is not a valid reading of this data.
- *
- * As an on-change sensor, there is an event generated upon configuring
- * this sensor. This is when we might get an 'invalid' reading. Thus,
- * this field must be checked on the first event before interpreting 'isNear'.
- */
-#define CHRE_EVENT_SENSOR_PROXIMITY_DATA \
- (CHRE_EVENT_SENSOR_DATA_EVENT_BASE + CHRE_SENSOR_TYPE_PROXIMITY)
-
-
-/**
- * First value for sensor events which are not data from the sensor.
- *
- * Unlike the data event values, these other event values don't have any
- * mapping to sensor types.
- */
-#define CHRE_EVENT_SENSOR_OTHER_EVENTS_BASE \
- (CHRE_EVENT_SENSOR_FIRST_EVENT + 0x0100)
-
-/**
- * nanoappHandleEvent argument: struct chreSensorSamplingStatusEvent
- *
- * Indicates that the interval and/or the latency which this sensor is
- * sampling at has changed.
- */
-#define CHRE_EVENT_SENSOR_SAMPLING_CHANGE \
- (CHRE_EVENT_SENSOR_OTHER_EVENTS_BASE + 0)
-
-/**
- * nanoappHandleEvent argument: struct chreSensorThreeAxisData
- *
- * The data can be interpreted using the 'x_bias', 'y_bias', and 'z_bias'
- * field within 'readings', or by the 3D array 'bias' (bias[0] == x_bias;
- * bias[1] == y_bias; bias[2] == z_bias).
- *
- * All values are in radians/second and measure the rate of rotation
- * around the X, Y and Z axis.
- */
-#define CHRE_EVENT_SENSOR_GYROSCOPE_BIAS_INFO \
- (CHRE_EVENT_SENSOR_OTHER_EVENTS_BASE + 1)
-
-/**
- * nanoappHandleEvent argument: struct chreSensorThreeAxisData
- *
- * The data can be interpreted using the 'x_bias', 'y_bias', and 'z_bias'
- * field within 'readings', or by the 3D array 'bias' (bias[0] == x_bias;
- * bias[1] == y_bias; bias[2] == z_bias).
- *
- * All values are in micro-Tesla (uT) and measure the geomagnetic
- * field in the X, Y and Z axis.
- */
-#define CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_BIAS_INFO \
- (CHRE_EVENT_SENSOR_OTHER_EVENTS_BASE + 2)
-
-
-#if CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_BIAS_INFO > CHRE_EVENT_SENSOR_LAST_EVENT
-#error Too many sensor events.
-#endif
-
-
-/**
- * Value indicating we want the smallest possible latency for a sensor.
- *
- * This literally translates to 0 nanoseconds for the chreSensorConfigure()
- * argument. While we won't get exactly 0 nanoseconds, the CHRE will
- * queue up this event As Soon As Possible.
- */
-#define CHRE_SENSOR_LATENCY_ASAP UINT64_C(0)
-
-/**
- * Special value indicating non-importance of the interval.
- *
- * @see chreSensorConfigure
- * @see chreSensorSamplingStatus
- */
-#define CHRE_SENSOR_INTERVAL_DEFAULT UINT64_C(-1)
-
-/**
- * Special value indicating non-importance of the latency.
- *
- * @see chreSensorConfigure
- * @see chreSensorSamplingStatus
- */
-#define CHRE_SENSOR_LATENCY_DEFAULT UINT64_C(-1)
-
-
-// This is used to define elements of enum chreSensorConfigureMode.
-#define CHRE_SENSOR_CONFIGURE_RAW_POWER_ON (1 << 0)
-
-// This is used to define elements of enum chreSensorConfigureMode.
-#define CHRE_SENSOR_CONFIGURE_RAW_REPORT_CONTINUOUS (1 << 1)
-
-// This is used to define elements of enum chreSensorConfigureMode.
-#define CHRE_SENSOR_CONFIGURE_RAW_REPORT_ONE_SHOT (2 << 1)
-
-
-
-/**
- * Modes we can configure a sensor to use.
- *
- * Our mode will affect not only how/if we receive events, but
- * also whether or not the sensor will be powered on our behalf.
- *
- * @see chreSensorConfigure
- */
-enum chreSensorConfigureMode {
- /**
- * Get events from the sensor.
- *
- * Power: Turn on if not already on.
- * Reporting: Continuous. Send each new event as it comes (subject to
- * batching and latency).
- */
- CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS =
- (CHRE_SENSOR_CONFIGURE_RAW_POWER_ON |
- CHRE_SENSOR_CONFIGURE_RAW_REPORT_CONTINUOUS),
-
- /**
- * Get a single event from the sensor and then become DONE.
- *
- * Once the event is sent, the sensor automatically
- * changes to CHRE_SENSOR_CONFIGURE_MODE_DONE mode.
- *
- * Power: Turn on if not already on.
- * Reporting: One shot. Send the next event and then be DONE.
- */
- CHRE_SENSOR_CONFIGURE_MODE_ONE_SHOT =
- (CHRE_SENSOR_CONFIGURE_RAW_POWER_ON |
- CHRE_SENSOR_CONFIGURE_RAW_REPORT_ONE_SHOT),
-
- /**
- * Get events from a sensor that are generated for other apps.
- *
- * This is considered passive because the sensor will not be powered
- * on for the sake of our nanoapp. If and only if another app in
- * the system has requested this sensor power on will we get events.
- *
- * This can be useful for something which is interested in seeing data,
- * but not interested enough to be responsible for powering on the sensor.
- *
- * Power: Do not power the sensor on our behalf.
- * Reporting: Continuous. Send each event as it comes.
- */
- CHRE_SENSOR_CONFIGURE_MODE_PASSIVE_CONTINUOUS =
- CHRE_SENSOR_CONFIGURE_RAW_REPORT_CONTINUOUS,
-
- /**
- * Get a single event from a sensor that is generated for other apps.
- *
- * See CHRE_SENSOR_CONFIGURE_MODE_PASSIVE_CONTINUOUS for more details
- * on what be "passive" means.
- *
- * Power: Do not power the sensor on our behalf.
- * Reporting: One shot. Send only the next event and then be DONE.
- */
- CHRE_SENSOR_CONFIGURE_MODE_PASSIVE_ONE_SHOT =
- CHRE_SENSOR_CONFIGURE_RAW_REPORT_ONE_SHOT,
-
- /**
- * Indicate we are done using this sensor and no longer interested in it.
- *
- * See chreSensorConfigure for more details on expressing interest or
- * lack of interest in a sensor.
- *
- * Power: Do not power the sensor on our behalf.
- * Reporting: None.
- */
- CHRE_SENSOR_CONFIGURE_MODE_DONE = 0,
-};
-
-/**
- * A structure containing information about a Sensor.
- *
- * See documentation of individual fields below.
- */
-struct chreSensorInfo {
- /**
- * The name of the sensor.
- *
- * A text name, useful for logging/debugging, describing the Sensor. This
- * is not assured to be unique (i.e. there could be multiple sensors with
- * the name "Temperature").
- *
- * CHRE implementations may not set this as NULL. An empty
- * string, while discouraged, is legal.
- */
- const char *sensorName;
-
- /**
- * One of the CHRE_SENSOR_TYPE_* defines above.
- */
- uint8_t sensorType;
-
- /**
- * Flag indicating if this sensor is on-change.
- *
- * An on-change sensor only generates events when underlying state
- * changes. This has the same meaning as on-change does in the Android
- * Sensors HAL. See sensors.h for much more details.
- *
- * A value of 1 indicates this is on-change. 0 indicates this is not
- * on-change.
- */
- uint8_t isOnChange : 1;
-
- /**
- * Flag indicating if this sensor is one-shot.
- *
- * A one-shot sensor only triggers a single event, and then automatically
- * disables itself.
- *
- * A value of 1 indicates this is on-change. 0 indicates this is not
- * on-change.
- */
- uint8_t isOneShot : 1;
- uint8_t unusedFlags : 6;
-};
-
-/**
- * Header used in every structure containing batchable data from a sensor.
- *
- * The typical structure for sensor data looks like:
- *
- * struct chreSensorTypeData {
- * struct chreSensorDataHeader header;
- * struct chreSensorTypeSampleData {
- * uint32_t timestampDelta;
- * union {
- * <type> value;
- * <type> interpretation0;
- * <type> interpretation1;
- * };
- * } readings[1];
- * };
- *
- * Despite 'readings' being declared as an array of 1 element,
- * an instance of the struct will actually have 'readings' as
- * an array of header.readingCount elements (which may be 1).
- * The 'timestampDelta' is in relation to the previous 'readings' (or
- * the baseTimestamp for readings[0]. So,
- * Timestamp for readings[0] == header.baseTimestamp +
- * readings[0].timestampDelta.
- * Timestamp for readings[1] == timestamp for readings[0] +
- * readings[1].timestampDelta.
- * And thus, in order to determine the timestamp for readings[N], it's
- * necessary to process through all of the N-1 readings. The advantage,
- * though, is that our entire readings can span an arbitrary length of time,
- * just as long as any two consecutive readings differ by no more than
- * 4.295 seconds (timestampDelta, like all time in the CHRE, is in
- * nanoseconds).
- *
- * If a sensor has batched readings where two consecutive readings differ by
- * more than 4.295 seconds, the CHRE will split them across multiple
- * instances of the struct, and send multiple events.
- *
- * The value from the sensor is typically expressed in a union,
- * allowing a generic access to the data ('value'), along with
- * differently named access giving a more natural interpretation
- * of the data for the specific sensor types which use this
- * structure. This allows, for example, barometer code to
- * reference readings[N].pressure, and an ambient light sensor
- * to reference readings[N].light, while both use the same
- * structure.
- */
-struct chreSensorDataHeader {
- /**
- * The base timestamp, in nanoseconds.
- */
- uint64_t baseTimestamp;
-
- /**
- * The handle of the sensor producing this event.
- */
- uint32_t sensorHandle;
-
- /**
- * The number elements in the 'readings' array.
- *
- * This must be at least 1.
- */
- uint16_t readingCount;
-
- /**
- * Reserved bytes.
- *
- * These must be 0.
- */
- uint8_t reserved[2];
-};
-
-/**
- * Data for a sensor which reports on three axes.
- *
- * This is used by CHRE_EVENT_SENSOR_ACCELEROMETER_DATA,
- * CHRE_EVENT_SENSOR_GYROSCOPE_DATA,
- * CHRE_EVENT_SENSOR_GYROSCOPE_BIAS_INFO,
- * CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_DATA, and
- * CHRE_EVENT_SENSOR_GEOMAGNETIC_FIELD_BIAS_INFO.
- */
-struct chreSensorThreeAxisData {
- /**
- * @see chreSensorDataHeader
- */
- struct chreSensorDataHeader header;
- struct chreSensorThreeAxisSampleData {
- /**
- * @see chreSensorDataHeader
- */
- uint32_t timestampDelta;
- union {
- float values[3];
- float v[3];
- struct {
- float x;
- float y;
- float z;
- };
- float bias[3];
- struct {
- float x_bias;
- float y_bias;
- float z_bias;
- };
- };
- } readings[1];
-};
-
-/**
- * Data from a sensor where we only care about a event occurring.
- *
- * This is a bit unusual in that our readings have no data in addition
- * to the timestamp. But since we only care about the occurrence, we
- * don't need to know anything else.
- *
- * Used by: CHRE_EVENT_SENSOR_INSTANT_MOTION_DETECT_DATA and
- * CHRE_EVENT_SENSOR_STATIONARY_DETECT_DATA.
- */
-struct chreSensorOccurrenceData {
- struct chreSensorDataHeader header;
- struct chreSensorOccurenceSampleData {
- uint32_t timestampDelta;
- // This space intentionally left blank.
- // Only the timestamp is meaningful here, there
- // is no additional data.
- } readings[1];
-};
-
-/**
- * CHRE_EVENT_SENSOR_LIGHT_DATA and CHRE_EVENT_SENSOR_PRESSURE_DATA.
- */
-struct chreSensorFloatData {
- struct chreSensorDataHeader header;
- struct chreSensorFloatSampleData {
- uint32_t timestampDelta;
- union {
- float value;
- float light; // lux
- float pressure; // hectopascals (hPa)
- };
- } readings[1];
-};
-
-/**
- * CHRE_EVENT_SENSOR_PROXIMITY_DATA.
- */
-struct chreSensorByteData {
- struct chreSensorDataHeader header;
- struct chreSensorByteSampleData {
- uint32_t timestampDelta;
- union {
- uint8_t value;
- struct {
- uint8_t isNear : 1;
- uint8_t invalid : 1;
- uint8_t padding0 : 6;
- };
- };
- } readings[1];
-};
-
-/**
- * The status of a sensor's sampling configuration.
- */
-struct chreSensorSamplingStatus {
- /**
- * The interval, in nanoseconds, at which the sensor is now sampling.
- *
- * If this is CHRE_SENSOR_INTERVAL_DEFAULT, then a sampling interval
- * isn't meaningful for this sensor.
- *
- * Note that if 'enabled' is false, this value is not meaningful.
- */
- uint64_t interval;
-
- /**
- * The latency, in nanoseconds, at which the senor is now reporting.
- *
- * If this is CHRE_SENSOR_LATENCY_DEFAULT, then a latency
- * isn't meaningful for this sensor.
- *
- * Note that if 'enabled' is false, this value is not meaningful.
- */
- uint64_t latency;
-
- /**
- * True if the sensor is actively powered and sampling; false otherwise.
- */
- bool enabled;
-};
-
-/**
- * The nanoappHandleEvent argument for CHRE_EVENT_SENSOR_SAMPLING_CHANGE.
- *
- * Note that only at least one of 'interval' or 'latency' must be
- * different than it was prior to this event. Thus, one of these
- * fields may be (but doesn't need to be) the same as before.
- */
-struct chreSensorSamplingStatusEvent {
- /**
- * The handle of the sensor which has experienced a change in sampling.
- */
- uint32_t sensorHandle;
-
- /**
- * The new sampling status.
- *
- * At least one of the field in this struct will be different from
- * the previous sampling status event.
- */
- struct chreSensorSamplingStatus status;
-};
-
-
-
-/**
- * Find the default sensor for a given sensor type.
- *
- * @param sensorType One of the CHRE_SENSOR_TYPE_* constants.
- * @param handle If a sensor is found, then the memory will be filled with
- * the value for the sensor's handle. This argument must be non-NULL.
- * @returns true if a sensor was found, false otherwise.
- */
-bool chreSensorFindDefault(uint8_t sensorType, uint32_t *handle);
-
-/**
- * Get the chreSensorInfo struct for a given sensor.
- *
- * @param sensorHandle The sensor handle, as obtained from
- * chreSensorFindDefault() or passed to nanoappHandleEvent().
- * @param info If the sensor is valid, then this memory will be filled with
- * the SensorInfo contents for this sensor. This argument must be
- * non-NULL.
- * @returns true if the senor handle is valid and 'info' was filled in;
- * false otherwise.
- */
-bool chreGetSensorInfo(uint32_t sensorHandle, struct chreSensorInfo *info);
-
-/**
- * Get the chreSensorSamplingStatus struct for a given sensor.
- *
- * Note that this may be different from what was requested in
- * chreSensorConfigure(), for multiple reasons. It's possible that the sensor
- * does not exactly support the interval requested in chreSensorConfigure(), so
- * a faster one was chosen.
- *
- * It's also possible that there is another user of this sensor who has
- * requested a faster interval and/or lower latency. This latter scenario
- * should be noted, because it means the sensor rate can change due to no
- * interaction from this nanoapp. Note that the
- * CHRE_EVENT_SENSOR_SAMPLING_CHANGE event will trigger in this case, so it's
- * not necessary to poll for such a change.
- *
- * @param sensorHandle The sensor handle, as obtained from
- * chreSensorFindDefault() or passed to nanoappHandleEvent().
- * @param status If the sensor is valid, then this memory will be filled with
- * the sampling status contents for this sensor. This argument must be
- * non-NULL.
- * @returns true if the senor handle is valid and 'status' was filled in;
- * false otherwise.
- */
-bool chreGetSensorSamplingStatus(uint32_t sensorHandle,
- struct chreSensorSamplingStatus *status);
-
-/**
- * Configures a given sensor at a specific interval and latency and mode.
- *
- * If this sensor's chreSensorInfo has isOneShot set to 1,
- * then the mode must be one of the ONE_SHOT modes, or this method will fail.
- *
- * The CHRE wants to power as few sensors as possible, in keeping with its
- * low power design. As such, it only turns on sensors when there are clients
- * actively interested in that sensor data, and turns off sensors as soon as
- * there are no clients interested in them. Calling this method generally
- * indicates an interest, and using CHRE_SENSOR_CONFIGURE_MODE_DONE shows
- * when we are no longer interested.
- *
- * Thus, each initial Configure of a sensor (per nanoapp) needs to eventually
- * have a DONE call made, either directly or on its behalf. Subsequent calls
- * to a Configure method within the same nanoapp, when there has been no DONE
- * in between, still only require a single DONE call.
- *
- * For example, the following is valid usage:
- * <code>
- * chreSensorConfigure(myHandle, mode, interval0, latency0);
- * [...]
- * chreSensorConfigure(myHandle, mode, interval1, latency0);
- * [...]
- * chreSensorConfigure(myHandle, mode, interval1, latency1);
- * [...]
- * chreSensorConfigureModeOnly(myHandle, CHRE_SENSOR_CONFIGURE_MODE_DONE);
- * </code>
- *
- * The first call to Configure is the one which creates the requirement
- * to eventually call with DONE. The subsequent calls are just changing the
- * interval/latency. They have not changed the fact that this nanoapp is
- * still interested in output from the sensor 'myHandle'. Thus, only one
- * single call for DONE is needed.
- *
- * There is a special case. One-shot sensors, sensors which
- * just trigger a single event and never trigger again, implicitly go into
- * DONE mode after that single event triggers. Thus, the
- * following are legitimate usages:
- * <code>
- * chreSensorConfigure(myHandle, MODE_ONE_SHOT, rate, latency);
- * [...]
- * [myHandle triggers an event]
- * [no need to configure to DONE].
- * </code>
- *
- * And:
- * <code>
- * chreSensorConfigure(myHandle, MODE_ONE_SHOT, rate, latency);
- * [...]
- * chreSensorConfigureModeOnly(myHandle, MODE_DONE);
- * [we cancelled myHandle before it ever triggered an event]
- * </code>
- *
- * Note that while PASSIVE modes, by definition, don't express
- * an interest in powering the sensor, DONE is still necessary
- * to silence the event reporting.
- *
- * @param sensorHandle The handle to the sensor, as obtained from
- * chreSensorFindDefault().
- * @param mode The mode to use. See descriptions within the
- * chreSensorConfigureMode enum.
- * @param interval The interval, in nanoseconds, at which we want events from
- * the sensor. On success, the sensor will be set to 'interval', or a value
- * less than 'interval'. There is a special value
- * CHRE_SENSOR_INTERVAL_DEFAULT, in which we don't express a preference for
- * the interval, and allow the sensor to chose what it wants. Note that
- * due to batching, we may receive events less frequently than
- * 'interval'.
- * @param latency The maximum latency, in nanoseconds, allowed before the
- * CHRE begins delivery of an event. This will control how many events
- * can be queued by the sensor before requiring a delivery event.
- * Latency is defined as the "timestamp when event is queued by the CHRE"
- * minus "timestamp of oldest unsent data reading".
- * There is a special value CHRE_SENSOR_LATENCY_DEFAULT, in which we don't
- * express a preference for the latency, and allow the sensor to chose what
- * it wants.
- * Note that there is no assurance of how long it will take an event to
- * get through a CHRE's queueing system, and thus there is no ability to
- * request a minimum time from the occurrence of a phenomenon to when the
- * nanoapp receives the information. The current CHRE API has no
- * real-time elements, although future versions may introduce some to
- * help with this issue.
- * @returns true if the configuration succeeded, false otherwise.
- *
- * @see chreSensorConfigureMode
- * @see chreSensorFindDefault
- * @see chreSensorInfo
- */
-bool chreSensorConfigure(uint32_t sensorHandle,
- enum chreSensorConfigureMode mode,
- uint64_t interval, uint64_t latency);
-
-/**
- * Short cut for chreSensorConfigure where we only want to change the mode.
- *
- * @see chreSensorConfigure
- */
-static inline bool chreSensorConfigureModeOnly(
- uint32_t sensorHandle, enum chreSensorConfigureMode mode) {
- return chreSensorConfigure(sensorHandle,
- mode,
- CHRE_SENSOR_INTERVAL_DEFAULT,
- CHRE_SENSOR_LATENCY_DEFAULT);
-}
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CHRE_SENSOR_H_ */
-
diff --git a/inc/chre/version.h b/inc/chre/version.h
deleted file mode 100644
index ae6b14ca..00000000
--- a/inc/chre/version.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CHRE_VERSION_H_
-#define _CHRE_VERSION_H_
-
-/**
- * Definitions and methods for the versioning of the Context Hub Runtime
- * Environment.
- *
- * The CHRE API versioning pertains to all the chre_*.h files and chre.h.
- */
-
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/**
- * Value for version 0.1 of the Context Hub Runtime Environment API interface.
- *
- * This is a legacy version. Version 1.0 is considered the first official
- * version of the API.
- *
- * @see CHRE_API_VERSION
- */
-#define CHRE_API_VERSION_0_1 UINT32_C(0x00010000)
-
-/**
- * Value for version 1.0 of the Context Hub Runtime Environment API interface.
- *
- * The version of the CHRE API which shipped with the Android Nougat release.
- *
- * @see CHRE_API_VERSION
- */
-#define CHRE_API_VERSION_1_0 UINT32_C(0x01000000)
-
-/**
- * Major and Minor Version of this Context Hub Runtime Environment API.
- *
- * The major version changes when there is an incompatible API change.
- *
- * The minor version changes when there is an addition in functionality
- * in a backwards-compatible manner.
- *
- * We define the version number as an unsigned 32-bit value. The most
- * significant byte is the Major Version. The second-most significant byte
- * is the Minor Version. The two least significant bytes are the Patch
- * Version. The Patch Version is not defined by this header API, but
- * is provided by a specific CHRE implementation (see chreGetVersion()).
- *
- * Note that version numbers can always be numerically compared with
- * expected results, so 1.0.0 < 1.0.4 < 1.1.0 < 2.0.300 < 3.5.0.
- */
-#define CHRE_API_VERSION CHRE_API_VERSION_1_0
-
-
-/**
- * Get the API version the CHRE implementation was compiled against.
- *
- * This is not necessarily the CHRE_API_VERSION in the header the nanoapp was
- * built against, and indeed may not have even appeared in the context_hub_os.h
- * header which this nanoapp was built against.
- *
- * By definition, this will have the two least significant bytes set to 0,
- * and only contain the major and minor version number.
- *
- * @returns The API version.
- */
-uint32_t chreGetApiVersion(void);
-
-/**
- * Get the version of this CHRE implementation.
- *
- * By definition, ((chreGetApiVersion() & UINT32_C(0xFFFF0000)) ==
- * (chreGetVersion() & UINT32_C(0xFFFF0000))).
- *
- * The Patch Version, in the lower two bytes, only have meaning in context
- * of this specific platform ID. It is increased by the platform every time
- * a backwards-compatible bug fix is released.
- *
- * @returns The version.
- *
- * @see chreGetPlatformId()
- */
-uint32_t chreGetVersion(void);
-
-/**
- * Get the Platform ID of this CHRE.
- *
- * The most significant five bytes are the vendor ID as set out by the
- * NANOAPP_VENDOR convention in context_hub.h, as used by nanoapp IDs.
- *
- * The least significant three bytes are set by the vendor, but must be
- * unique for each different CHRE implementation/hardware that the vendor
- * supplies.
- *
- * The idea is that in the case of known bugs in the field, a new nanoapp could
- * be shipped with a workaround that would use this value, and chreGetVersion(),
- * to have code that can conditionally work around the bug on a buggy version.
- * Thus, we require this uniqueness to allow such a setup to work.
- *
- * @returns The platform ID.
- */
-uint64_t chreGetPlatformId(void);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CHRE_VERSION_H_ */
-
diff --git a/lib/include/nanohub/nanohub.h b/lib/include/nanohub/nanohub.h
index 451df9dd..61d1dc85 100644
--- a/lib/include/nanohub/nanohub.h
+++ b/lib/include/nanohub/nanohub.h
@@ -55,7 +55,9 @@ struct nano_app_binary_t {
uint32_t app_version; // Version of the app
uint32_t flags; // Signed, encrypted
uint64_t hw_hub_type; // which hub type is this compiled for
- uint32_t reserved[2]; // Should be all zeroes
+ uint8_t chre_api_major; // Which CHRE API version this is compiled for
+ uint8_t chre_api_minor;
+ uint8_t reserved[6]; // Should be all zeroes
uint8_t custom_binary[0]; // start of custom binary data
};
@@ -67,11 +69,19 @@ struct HostMsgHdr {
uint8_t len;
} __attribute__((packed));
+struct HostMsgHdrChreV10 {
+ uint32_t eventId;
+ uint64_t appId;
+ uint8_t len;
+ uint32_t appEventId;
+} __attribute__((packed));
+
struct HostMsgHdrChre {
uint32_t eventId;
uint64_t appId;
uint8_t len;
uint32_t appEventId;
+ uint16_t endpoint;
} __attribute__((packed));
// we translate AOSP header into FW header: this header is in LE format
@@ -84,7 +94,8 @@ struct FwCommonHdr {
uint32_t appVer; // external: copy from AOSP header; internal: defined locally
uint8_t payInfoType; // external: copy ImageLayout::payload; internal: LAYOUT_APP
uint8_t payInfoSize; // sizeof(PayloadInfo) for this payload type
- uint8_t rfu[2]; // filled with 0xFF
+ uint8_t chreApiMajor; // Chre Api Major Version (or 0xFF for non-chre nanoapps)
+ uint8_t chreApiMinor; // Chre Api Minor Version (or 0xFF for non-chre nanoapps)
};
struct SectInfo {
diff --git a/util/nanoapp_postprocess/postprocess_elf.c b/util/nanoapp_postprocess/postprocess_elf.c
index aa0b2ba3..b5bf0c07 100644
--- a/util/nanoapp_postprocess/postprocess_elf.c
+++ b/util/nanoapp_postprocess/postprocess_elf.c
@@ -109,6 +109,7 @@ static void fatalUsage(const char *name, const char *msg, const char *arg)
" -n <layout name> : app, os, key\n"
" -i <layout id> : 1 (app), 2 (key), 3 (os)\n"
" -f <layout flags>: 16-bit hex value, stored as layout-specific flags\n"
+ " -c <chre api> : 16-bit hex value, stored as chre-major + chre-minor\n"
" -a <app ID> : 64-bit hex number != 0\n"
" -e <app version> : 32-bit hex number\n"
" -k <key ID> : 64-bit hex number != 0\n"
@@ -225,7 +226,7 @@ static uint8_t *packNanoRelocs(struct NanoRelocEntry *nanoRelocs, uint32_t outNu
return packedNanoRelocs;
}
-static int finalizeAndWrite(uint8_t *buf, uint32_t bufUsed, uint32_t bufSz, FILE *out, uint32_t layoutFlags, uint64_t appId)
+static int finalizeAndWrite(uint8_t *buf, uint32_t bufUsed, uint32_t bufSz, FILE *out, uint32_t layoutFlags, uint64_t appId, uint32_t chreApi)
{
int ret;
struct AppInfo app;
@@ -238,12 +239,14 @@ static int finalizeAndWrite(uint8_t *buf, uint32_t bufUsed, uint32_t bufSz, FILE
.app_id = appId,
.app_version = bin->hdr.appVer,
.flags = 0, // encrypted (1), signed (2) (will be set by other tools)
+ .chre_api_major = chreApi >> 8,
+ .chre_api_minor = chreApi & 0xFF,
},
.layout = (struct ImageLayout) {
.magic = GOOGLE_LAYOUT_MAGIC,
.version = 1,
.payload = LAYOUT_APP,
- .flags = layoutFlags,
+ .flags = layoutFlags | (chreApi ? 0x0010 : 0x0000),
},
};
uint32_t dataOffset = sizeof(outHeader) + sizeof(app);
@@ -285,7 +288,7 @@ static int finalizeAndWrite(uint8_t *buf, uint32_t bufUsed, uint32_t bufSz, FILE
return ret;
}
-static int handleApp(uint8_t **pbuf, uint32_t bufUsed, FILE *out, uint32_t layoutFlags, uint64_t appId, uint32_t appVer, bool verbose)
+static int handleApp(uint8_t **pbuf, uint32_t bufUsed, FILE *out, uint32_t layoutFlags, uint64_t appId, uint32_t appVer, uint32_t chreApi, bool verbose)
{
uint32_t i, numRelocs, numSyms, outNumRelocs = 0, packedNanoRelocSz;
struct NanoRelocEntry *nanoRelocs = NULL;
@@ -529,7 +532,7 @@ static int handleApp(uint8_t **pbuf, uint32_t bufUsed, FILE *out, uint32_t layou
sect->rel_start -= FLASH_BASE + BINARY_RELOC_OFFSET;
sect->rel_end -= FLASH_BASE + BINARY_RELOC_OFFSET;
- ret = finalizeAndWrite(buf, bufUsed, bufSz, out, layoutFlags, appId);
+ ret = finalizeAndWrite(buf, bufUsed, bufSz, out, layoutFlags, appId, chreApi);
out:
free(nanoRelocs);
return ret;
@@ -786,7 +789,7 @@ out:
return success;
}
-static int handleAppStatic(const char *fileName, FILE *out, uint32_t layoutFlags, uint64_t appId, uint32_t appVer, bool verbose)
+static int handleAppStatic(const char *fileName, FILE *out, uint32_t layoutFlags, uint64_t appId, uint32_t appVer, uint32_t chreApi, bool verbose)
{
struct ElfNanoApp app;
@@ -823,7 +826,7 @@ static int handleAppStatic(const char *fileName, FILE *out, uint32_t layoutFlags
hdr->sect.rel_end = hdr->sect.rel_start + app.packedNanoRelocs.size;
hdr->hdr.appVer = appVer;
- return finalizeAndWrite(buf, offset, bufSize, out, layoutFlags, appId);
+ return finalizeAndWrite(buf, offset, bufSize, out, layoutFlags, appId, chreApi);
// TODO: should free all memory we allocated... just letting the OS handle
// it for now
}
@@ -896,6 +899,7 @@ int main(int argc, char **argv)
uint64_t appId = 0;
uint64_t keyId = 0;
uint32_t appVer = 0;
+ uint32_t chreApi = 0;
uint32_t layoutId = 0;
uint32_t layoutFlags = 0;
int ret = -1;
@@ -923,6 +927,8 @@ int main(int argc, char **argv)
staticElf = true;
else if (!strcmp(argv[i], "-a"))
u64Arg = &appId;
+ else if (!strcmp(argv[i], "-c"))
+ u32Arg = &chreApi;
else if (!strcmp(argv[i], "-e"))
u32Arg = &appVer;
else if (!strcmp(argv[i], "-k"))
@@ -1000,9 +1006,9 @@ int main(int argc, char **argv)
switch(layoutId) {
case LAYOUT_APP:
if (staticElf) {
- ret = handleAppStatic(posArg[0], out, layoutFlags, appId, appVer, verbose);
+ ret = handleAppStatic(posArg[0], out, layoutFlags, appId, appVer, chreApi, verbose);
} else {
- ret = handleApp(&buf, bufUsed, out, layoutFlags, appId, appVer, verbose);
+ ret = handleApp(&buf, bufUsed, out, layoutFlags, appId, appVer, chreApi, verbose);
}
break;
case LAYOUT_KEY: