aboutsummaryrefslogtreecommitdiff
path: root/pw_chre
diff options
context:
space:
mode:
authorDavid Gilhooley <dgilhooley@google.com>2023-09-12 14:36:00 +0000
committerCQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-09-12 14:36:00 +0000
commitf210a064bf6d67fe0d58074f4e3a6eed1e9851bd (patch)
tree8215f9431976c9519907c6fd4822c20c5b7da00d /pw_chre
parentef447ae6f95cab0d4f6f74f4e356c14f212cb0bb (diff)
downloadpigweed-f210a064bf6d67fe0d58074f4e3a6eed1e9851bd.tar.gz
pw_chre: Add barebones CHRE
NOTE: This is a very work-in-progress implementation. Add GN rules for the CHRE codebase into //third_party/CHRE. This also adds a pw_chre_PLATFORM_BACKEND gn argument for the platform backend for CHRE. Add a pw_chre directory that includes all of the class and function definitions required to compile CHRE. Some of this connects to pigweed functionality, some of it is stubbed out. //pw_chre:chre_simulator uses pw_system to run CHRE on pigweed on the host, and it compiles in a number of CHRE's example nanoapps. There is enough functionality that these nanoapps are able to run. Bug: 294106526 Change-Id: I73ab1a83ccefbe4a7d0f9ba7a5421c3f3391a937 Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/162510 Reviewed-by: Kayce Basques <kayce@google.com> Reviewed-by: Armando Montanez <amontanez@google.com> Commit-Queue: David Gilhooley <dgilhooley@google.com> Reviewed-by: Aaron Green <aarongreen@google.com>
Diffstat (limited to 'pw_chre')
-rw-r--r--pw_chre/BUILD.bazel60
-rw-r--r--pw_chre/BUILD.gn135
-rw-r--r--pw_chre/chre.cc64
-rw-r--r--pw_chre/chre_api_re.cc48
-rw-r--r--pw_chre/chre_empty_host_link.cc25
-rw-r--r--pw_chre/context.cc21
-rw-r--r--pw_chre/docs.rst138
-rw-r--r--pw_chre/example_init.cc39
-rw-r--r--pw_chre/host_link.cc44
-rw-r--r--pw_chre/include/chre/target_platform/atomic_base.h30
-rw-r--r--pw_chre/include/chre/target_platform/atomic_base_impl.h63
-rw-r--r--pw_chre/include/chre/target_platform/condition_variable_base.h26
-rw-r--r--pw_chre/include/chre/target_platform/condition_variable_impl.h42
-rw-r--r--pw_chre/include/chre/target_platform/fatal_error.h21
-rw-r--r--pw_chre/include/chre/target_platform/host_link_base.h25
-rw-r--r--pw_chre/include/chre/target_platform/log.h24
-rw-r--r--pw_chre/include/chre/target_platform/mutex_base.h20
-rw-r--r--pw_chre/include/chre/target_platform/mutex_base_impl.h31
-rw-r--r--pw_chre/include/chre/target_platform/platform_nanoapp_base.h29
-rw-r--r--pw_chre/include/chre/target_platform/platform_sensor_base.h43
-rw-r--r--pw_chre/include/chre/target_platform/platform_sensor_manager_base.h38
-rw-r--r--pw_chre/include/chre/target_platform/platform_sensor_type_helpers_base.h20
-rw-r--r--pw_chre/include/chre/target_platform/power_control_manager_base.h21
-rw-r--r--pw_chre/include/chre/target_platform/static_nanoapp_init.h50
-rw-r--r--pw_chre/include/chre/target_platform/system_timer_base.h38
-rw-r--r--pw_chre/memory.cc31
-rw-r--r--pw_chre/memory_manager.cc27
-rw-r--r--pw_chre/platform_debug_dump_manager.cc27
-rw-r--r--pw_chre/platform_nanoapp.cc77
-rw-r--r--pw_chre/platform_pal.cc22
-rw-r--r--pw_chre/power_control_manager.cc25
-rw-r--r--pw_chre/public/pw_chre/chre.h71
-rw-r--r--pw_chre/public/pw_chre/host_link.h67
-rw-r--r--pw_chre/static_nanoapps.cc34
-rw-r--r--pw_chre/system_time.cc45
-rw-r--r--pw_chre/system_timer.cc67
36 files changed, 1588 insertions, 0 deletions
diff --git a/pw_chre/BUILD.bazel b/pw_chre/BUILD.bazel
new file mode 100644
index 000000000..e42001451
--- /dev/null
+++ b/pw_chre/BUILD.bazel
@@ -0,0 +1,60 @@
+# Copyright 2023 The Pigweed Authors
+#
+# 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
+#
+# https://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.
+
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"])
+
+# TODO(b/298660977): Add bazel support for CHRE.
+filegroup(
+ name = "chre",
+ srcs = [
+ "chre.cc",
+ "chre_api_re.cc",
+ "chre_empty_host_link.cc",
+ "context.cc",
+ "docs.rst",
+ "example_init.cc",
+ "host_link.cc",
+ "include",
+ "include/chre/target_platform/atomic_base.h",
+ "include/chre/target_platform/atomic_base_impl.h",
+ "include/chre/target_platform/condition_variable_base.h",
+ "include/chre/target_platform/condition_variable_impl.h",
+ "include/chre/target_platform/fatal_error.h",
+ "include/chre/target_platform/host_link_base.h",
+ "include/chre/target_platform/log.h",
+ "include/chre/target_platform/mutex_base.h",
+ "include/chre/target_platform/mutex_base_impl.h",
+ "include/chre/target_platform/platform_nanoapp_base.h",
+ "include/chre/target_platform/platform_sensor_base.h",
+ "include/chre/target_platform/platform_sensor_manager_base.h",
+ "include/chre/target_platform/platform_sensor_type_helpers_base.h",
+ "include/chre/target_platform/power_control_manager_base.h",
+ "include/chre/target_platform/static_nanoapp_init.h",
+ "include/chre/target_platform/system_timer_base.h",
+ "memory.cc",
+ "memory_manager.cc",
+ "platform_debug_dump_manager.cc",
+ "platform_nanoapp.cc",
+ "platform_pal.cc",
+ "power_control_manager.cc",
+ "public",
+ "public/pw_chre/chre.h",
+ "public/pw_chre/host_link.h",
+ "static_nanoapps.cc",
+ "system_time.cc",
+ "system_timer.cc",
+ ],
+)
diff --git a/pw_chre/BUILD.gn b/pw_chre/BUILD.gn
new file mode 100644
index 000000000..aab25a9aa
--- /dev/null
+++ b/pw_chre/BUILD.gn
@@ -0,0 +1,135 @@
+# Copyright 2023 The Pigweed Authors
+#
+# 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
+#
+# https://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.
+
+import("//build_overrides/pigweed.gni")
+
+import("$dir_pw_build/module_config.gni")
+import("$dir_pw_build/target_types.gni")
+import("$dir_pw_docgen/docs.gni")
+import("$dir_pw_third_party/chre/chre.gni")
+import("$dir_pw_unit_test/test.gni")
+
+config("disable_warnings") {
+ cflags = [
+ "-Wno-nested-anon-types",
+ "-Wno-gnu-anonymous-struct",
+ "-Wno-thread-safety-analysis",
+ ]
+ visibility = [ ":*" ]
+}
+
+config("public_overrides") {
+ include_dirs = [ "include" ]
+}
+
+pw_source_set("chre_empty_host_link") {
+ sources = [ "chre_empty_host_link.cc" ]
+ deps = [ ":chre" ]
+}
+
+pw_source_set("chre_backend") {
+ sources = [
+ "chre_api_re.cc",
+ "context.cc",
+ "host_link.cc",
+ "memory.cc",
+ "memory_manager.cc",
+ "platform_debug_dump_manager.cc",
+ "platform_nanoapp.cc",
+ "platform_pal.cc",
+ "power_control_manager.cc",
+ "system_time.cc",
+ "system_timer.cc",
+ ]
+ public = [
+ "include/chre/target_platform/atomic_base.h",
+ "include/chre/target_platform/atomic_base_impl.h",
+ "include/chre/target_platform/condition_variable_base.h",
+ "include/chre/target_platform/condition_variable_impl.h",
+ "include/chre/target_platform/fatal_error.h",
+ "include/chre/target_platform/host_link_base.h",
+ "include/chre/target_platform/log.h",
+ "include/chre/target_platform/mutex_base.h",
+ "include/chre/target_platform/mutex_base_impl.h",
+ "include/chre/target_platform/platform_nanoapp_base.h",
+ "include/chre/target_platform/platform_sensor_base.h",
+ "include/chre/target_platform/platform_sensor_manager_base.h",
+ "include/chre/target_platform/platform_sensor_type_helpers_base.h",
+ "include/chre/target_platform/power_control_manager_base.h",
+ "include/chre/target_platform/static_nanoapp_init.h",
+ "include/chre/target_platform/system_timer_base.h",
+ ]
+ deps = [
+ "$dir_pw_string:format",
+ "$dir_pw_third_party/chre:chre_headers",
+ ]
+ public_deps = [
+ "$dir_pw_chrono:system_timer",
+ "$dir_pw_log",
+ "$dir_pw_sync:mutex",
+ "$dir_pw_sync:timed_thread_notification",
+ ]
+
+ public_configs = [
+ ":public_include_path",
+ ":public_overrides",
+ ":disable_warnings",
+ ]
+ remove_configs = [ "$dir_pw_build:internal_strict_warnings" ]
+}
+
+config("public_include_path") {
+ include_dirs = [ "public" ]
+ visibility = [ ":*" ]
+}
+
+pw_source_set("chre") {
+ public_configs = [ ":public_include_path" ]
+ public = [
+ "public/pw_chre/chre.h",
+ "public/pw_chre/host_link.h",
+ ]
+ sources = [ "chre.cc" ]
+ deps = [ "$dir_pw_third_party/chre" ]
+}
+
+pw_executable("chre_example") {
+ sources = [
+ "example_init.cc",
+ "static_nanoapps.cc",
+ ]
+
+ deps = [
+ ":chre",
+ ":chre_empty_host_link",
+ "$dir_pw_system",
+ "$dir_pw_third_party/chre:example_apps",
+ ]
+}
+
+group("host_example") {
+ deps = [ ":chre_example($dir_pigweed/targets/host_device_simulator:host_device_simulator.speed_optimized)" ]
+}
+
+pw_test_group("tests") {
+ enable_if = dir_pw_third_party_chre != ""
+ tests = [
+ "//third_party/chre:unit_tests",
+ "//third_party/chre:integration_tests",
+ ]
+}
+
+pw_doc_group("docs") {
+ sources = [ "docs.rst" ]
+}
diff --git a/pw_chre/chre.cc b/pw_chre/chre.cc
new file mode 100644
index 000000000..7ed7ea1cf
--- /dev/null
+++ b/pw_chre/chre.cc
@@ -0,0 +1,64 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "pw_chre/chre.h"
+
+#include "chre/core/event_loop.h"
+#include "chre/core/event_loop_manager.h"
+#include "chre/core/host_comms_manager.h"
+#include "chre/core/init.h"
+#include "chre/core/static_nanoapps.h"
+
+namespace pw::chre {
+
+void Init() {
+ ::chre::init();
+ ::chre::EventLoopManagerSingleton::get()->lateInit();
+ ::chre::loadStaticNanoapps();
+ ::chre::EventLoopManagerSingleton::get()->getEventLoop().run();
+}
+
+void Deinit() { ::chre::deinit(); }
+
+void RunEventLoop() {
+ ::chre::EventLoopManagerSingleton::get()->getEventLoop().run();
+}
+
+void StopEventLoop() {
+ ::chre::EventLoopManagerSingleton::get()->getEventLoop().stop();
+}
+
+void SendMessageToNanoapp(uint64_t nano_app_id,
+ uint32_t message_type,
+ uint16_t host_endpoint,
+ const uint8_t* data,
+ size_t len) {
+ ::chre::HostCommsManager& manager =
+ ::chre::EventLoopManagerSingleton::get()->getHostCommsManager();
+ manager.sendMessageToNanoappFromHost(
+ nano_app_id, message_type, host_endpoint, data, len);
+}
+
+void FreeMessageToAp(MessageToApContext context) {
+ auto& hostCommsManager =
+ ::chre::EventLoopManagerSingleton::get()->getHostCommsManager();
+ hostCommsManager.onMessageToHostComplete(
+ static_cast<const ::chre::MessageToHost*>(context));
+}
+
+void SetEstimatedHostTimeOffset(int64_t offset) {
+ ::chre::SystemTime::setEstimatedHostTimeOffset(offset);
+}
+
+} // namespace pw::chre
diff --git a/pw_chre/chre_api_re.cc b/pw_chre/chre_api_re.cc
new file mode 100644
index 000000000..5e1ff8410
--- /dev/null
+++ b/pw_chre/chre_api_re.cc
@@ -0,0 +1,48 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "chre/platform/log.h"
+#include "chre/util/macros.h"
+#include "chre_api/chre/re.h"
+#include "pw_log/log.h"
+#include "pw_string/format.h"
+
+namespace {
+int ToPigweedLogLevel(enum chreLogLevel level) {
+ switch (level) {
+ case CHRE_LOG_ERROR:
+ return PW_LOG_LEVEL_ERROR;
+ case CHRE_LOG_WARN:
+ return PW_LOG_LEVEL_WARN;
+ case CHRE_LOG_INFO:
+ return PW_LOG_LEVEL_INFO;
+ case CHRE_LOG_DEBUG:
+ return PW_LOG_LEVEL_DEBUG;
+ }
+}
+} // namespace
+
+DLL_EXPORT void chreLog(enum chreLogLevel level,
+ const char* format_string,
+ ...) {
+ char log[512];
+
+ va_list args;
+ va_start(args, format_string);
+ pw::StatusWithSize status = pw::string::Format(log, format_string, args);
+ PW_ASSERT(status.ok());
+ va_end(args);
+
+ PW_LOG(ToPigweedLogLevel(level), "CHRE", PW_LOG_FLAGS, "%s", log);
+}
diff --git a/pw_chre/chre_empty_host_link.cc b/pw_chre/chre_empty_host_link.cc
new file mode 100644
index 000000000..31a967626
--- /dev/null
+++ b/pw_chre/chre_empty_host_link.cc
@@ -0,0 +1,25 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "pw_chre/chre.h"
+#include "pw_chre/host_link.h"
+
+namespace pw::chre {
+
+bool SendMessageToAp(MessageToAp message) {
+ FreeMessageToAp(message.chre_context);
+ return true;
+}
+
+} // namespace pw::chre
diff --git a/pw_chre/context.cc b/pw_chre/context.cc
new file mode 100644
index 000000000..aeaf7b95a
--- /dev/null
+++ b/pw_chre/context.cc
@@ -0,0 +1,21 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "chre/platform/context.h"
+
+namespace chre {
+
+bool inEventLoopThread() { return true; }
+
+} // namespace chre
diff --git a/pw_chre/docs.rst b/pw_chre/docs.rst
new file mode 100644
index 000000000..0fe2af30f
--- /dev/null
+++ b/pw_chre/docs.rst
@@ -0,0 +1,138 @@
+.. _module-pw_chre:
+
+=======
+pw_chre
+=======
+
+.. warning::
+
+ This module is extremely experimental. Parts of this module might be broken,
+ and the module does not provide a stable API.
+
+The `Context Hub Runtime Environment <https://source.android.com/docs/core/interaction/contexthub>`_
+(CHRE) is Android's platform for developing always-on applications called
+nanoapps. These nanoapps run on a vendor-specific processor which is more power
+efficient. Nanoapps use the CHRE API, which is standardized across platforms,
+allowing them to be code-compatible across devices.
+
+This module implements a Pigweed backend to CHRE. In order to use this module,
+``dir_pw_third_party_chre`` must point to the directory to the CHRE library.
+
+-----------
+Get started
+-----------
+
+To integrate ``pw_chre`` with your project:
+
+- Call the initialization functions and start the event loop.
+- Handle messages from the application processor and connect them through to
+ the CHRE runtime.
+- Implement the functions in ``pw_chre/host_link``. This is how CHRE sends
+ messages to the application processor.
+
+
+``$pw_chre:chre_example`` runs the CHRE environment using ``pw_system``.
+This also loads several static example nanoapps from the CHRE codebase by
+compiling them into the executable. This can be a helpful reference.
+
+CHRE is implemented using the following Pigweed modules for functionality:
+
+- ``pw_chrono:system_timer``: implements getting monotonic time
+- ``pw_log``: implements logging to the application processor
+- ``pw_assert``: implements crash handling
+- ``pw_sync``: implements mutual exclusion primitives
+- ``malloc/free``: implements virtual memory allocation
+ (This may be eventually replaced with a pigweed module)
+
+----------------------
+Current implementation
+----------------------
+
+As mentioned at the top of this document, ``pw_chre`` is extremely experimental.
+Only a few parts of CHRE have been tested. There are likely to be bugs and
+unimplemented behavior. The lists below track the current state and will
+be updated as things change.
+
+Supported and tested behavior:
+
+- Loading static nanoapps.
+- The following sample nanoapps have been run:
+ - hello_world
+ - debug_dump_world
+ - timer_world
+ - unload_tester
+ - message_world
+ - spammer
+- Logging from a nanoapp.
+- Allocating memory (although it uses malloc/free).
+- Sending messages to/from the AP.
+
+Features not implemented, but likely to be implemented in the future:
+
+- Context Hub Qualification Test Suite (CHQTS).
+- Some simulated PALS for testing (based off of CHRE's linux simulated PALs).
+- Power Management APIs, e.g: waking the host AP and flushing messages.
+- Instructions around implementing a PAL.
+- Instructions around building and testing a nanoapp.
+- Dynamically loading nanoapps.
+
+Features that would be nice to have:
+
+- A plug-and-play implementation of AP <-> MCU flatbuffer message communication.
+- Pigweed defined facades for each PAL.
+- PAL implementations using Pigweed functionality (i.e: implementing bluetooth
+ via ``pw_bluetooth``).
+- Pigweed defined facades for core CHRE functionality, such as clock selection,
+ memory management, cache management.
+- A protobuf implementation of CHRE's flatbuffer API.
+- Cmake and Bazel build system integration.
+
+-------------
+API reference
+-------------
+.. doxygennamespace:: pw::chre
+ :members:
+
+-------------
+Porting Guide
+-------------
+The ``pw_chre`` module has completed the steps outlined for `creating a new CHRE platform`_ .
+
+.. _Creating a new CHRE platform: https://android.googlesource.com/platform/system/chre/+/refs/heads/main/doc/porting_guide.md#recommended-steps-for-porting-chre
+
+The ``pw_chre`` module still needs to be configured correctly on a new platform.
+You ``pw_chre`` user is responsible for:
+
+- Starting a thread for CHRE's event loop and calling the correct APIs.
+- Forwarding messages to/from the Application Processor (AP).
+
+-----------------------------
+Adding Optional Feature Areas
+-----------------------------
+However, ``pw_chre`` users will likely want to implement their own
+Platform Abstraction Layers (PALs). For more information see this
+`implementation guide <https://android.googlesource.com/platform/system/chre/+/refs/heads/main/doc/porting_guide.md#implementing-optional-feature-areas-e_g_pals>`_.
+
+.. list-table:: List of PALs
+ :widths: 1 1
+ :header-rows: 1
+
+ * - PAL Name
+ - Pigweed implementation available
+ * - Audio
+ - ❌
+ * - Bluetooth
+ - ❌
+ * - GNSS
+ - ❌
+ * - Sensor
+ - ❌
+ * - Wifi
+ - ❌
+ * - WWAN
+ - ❌
+
+
+For more information on a specific PAL see
+`the PAL headers <https://cs.android.com/android/platform/superproject/+/main:system/chre/pal/include/chre/pal/>`_
+or the `Linux reference PAL implementations <https://cs.android.com/android/platform/superproject/+/main:system/chre/platform/linux/>`_.
diff --git a/pw_chre/example_init.cc b/pw_chre/example_init.cc
new file mode 100644
index 000000000..5bd435cdb
--- /dev/null
+++ b/pw_chre/example_init.cc
@@ -0,0 +1,39 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "pw_chre/chre.h"
+#include "pw_system/target_hooks.h"
+#include "pw_thread/thread.h"
+
+namespace pw::system {
+namespace {
+
+pw::thread::Thread chre_thread;
+
+} // namespace
+
+// This will run once after pw::system::Init() completes. This callback must
+// return or it will block the work queue.
+void UserAppInit() {
+ // Start the thread that is running CHRE.
+ chre_thread = pw::thread::Thread(
+ pw::system::LogThreadOptions(),
+ [](void*) {
+ pw::chre::Init();
+ pw::chre::RunEventLoop();
+ pw::chre::Deinit();
+ },
+ nullptr);
+}
+
+} // namespace pw::system
diff --git a/pw_chre/host_link.cc b/pw_chre/host_link.cc
new file mode 100644
index 000000000..5a22d8e42
--- /dev/null
+++ b/pw_chre/host_link.cc
@@ -0,0 +1,44 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "chre/platform/host_link.h"
+
+#include <algorithm>
+
+#include "chre/core/host_comms_manager.h"
+#include "public/pw_chre/host_link.h"
+#include "pw_chre/host_link.h"
+
+namespace chre {
+
+// TODO(b/294106526): Implement these, possibly by adding a facade.
+void HostLink::flushMessagesSentByNanoapp(uint64_t) {}
+
+bool HostLink::sendMessage(const MessageToHost* message) {
+ pw::chre::MessageToAp pw_message{
+ .nanoapp_id = message->appId,
+ .message_type = message->toHostData.messageType,
+ .app_permissions = message->toHostData.appPermissions,
+ .message_permissions = message->toHostData.messagePermissions,
+ .woke_host = message->toHostData.wokeHost,
+ .data = message->message.data(),
+ .length = message->message.size(),
+ .chre_context = message,
+ };
+ return pw::chre::SendMessageToAp(std::move(pw_message));
+}
+
+void HostLinkBase::sendNanConfiguration(bool) {}
+
+} // namespace chre
diff --git a/pw_chre/include/chre/target_platform/atomic_base.h b/pw_chre/include/chre/target_platform/atomic_base.h
new file mode 100644
index 000000000..3462671c0
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/atomic_base.h
@@ -0,0 +1,30 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+
+#include <atomic>
+
+namespace chre {
+
+template <typename AtomicType>
+class AtomicBase {
+ protected:
+ std::atomic<AtomicType> atomic_;
+};
+
+typedef AtomicBase<bool> AtomicBoolBase;
+typedef AtomicBase<uint32_t> AtomicUint32Base;
+
+} // namespace chre
diff --git a/pw_chre/include/chre/target_platform/atomic_base_impl.h b/pw_chre/include/chre/target_platform/atomic_base_impl.h
new file mode 100644
index 000000000..3979a52d6
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/atomic_base_impl.h
@@ -0,0 +1,63 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+
+#include "chre/platform/atomic.h"
+
+namespace chre {
+
+inline AtomicBool::AtomicBool(bool starting_value) {
+ std::atomic_init(&atomic_, starting_value);
+}
+
+inline bool AtomicBool::operator=(bool desired) { return atomic_ = desired; }
+
+inline bool AtomicBool::load() const { return atomic_.load(); }
+
+inline void AtomicBool::store(bool desired) { atomic_.store(desired); }
+
+inline bool AtomicBool::exchange(bool desired) {
+ return atomic_.exchange(desired);
+}
+
+inline AtomicUint32::AtomicUint32(uint32_t startingValue) {
+ std::atomic_init(&atomic_, startingValue);
+}
+
+inline uint32_t AtomicUint32::operator=(uint32_t desired) {
+ return atomic_ = desired;
+}
+
+inline uint32_t AtomicUint32::load() const { return atomic_.load(); }
+
+inline void AtomicUint32::store(uint32_t desired) { atomic_.store(desired); }
+
+inline uint32_t AtomicUint32::exchange(uint32_t desired) {
+ return atomic_.exchange(desired);
+}
+
+inline uint32_t AtomicUint32::fetch_add(uint32_t arg) {
+ return atomic_.fetch_add(arg);
+}
+
+inline uint32_t AtomicUint32::fetch_increment() { return atomic_.fetch_add(1); }
+
+inline uint32_t AtomicUint32::fetch_sub(uint32_t arg) {
+ return atomic_.fetch_sub(arg);
+}
+
+inline uint32_t AtomicUint32::fetch_decrement() { return atomic_.fetch_sub(1); }
+
+} // namespace chre
diff --git a/pw_chre/include/chre/target_platform/condition_variable_base.h b/pw_chre/include/chre/target_platform/condition_variable_base.h
new file mode 100644
index 000000000..f40ab3004
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/condition_variable_base.h
@@ -0,0 +1,26 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+
+#include "pw_sync/timed_thread_notification.h"
+
+namespace chre {
+
+class ConditionVariableBase {
+ protected:
+ pw::sync::TimedThreadNotification notification_;
+};
+
+} // namespace chre
diff --git a/pw_chre/include/chre/target_platform/condition_variable_impl.h b/pw_chre/include/chre/target_platform/condition_variable_impl.h
new file mode 100644
index 000000000..2d826ec06
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/condition_variable_impl.h
@@ -0,0 +1,42 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+#include "chre/platform/condition_variable.h"
+#include "pw_chrono/system_clock.h"
+
+namespace chre {
+
+inline ConditionVariable::ConditionVariable() {}
+
+inline ConditionVariable::~ConditionVariable() {}
+
+inline void ConditionVariable::notify_one() { notification_.release(); }
+
+inline void ConditionVariable::wait(Mutex& mutex) {
+ mutex.unlock();
+ notification_.acquire();
+ mutex.lock();
+}
+
+inline bool ConditionVariable::wait_for(Mutex& mutex, Nanoseconds timeout) {
+ mutex.unlock();
+ auto pw_timeout = pw::chrono::SystemClock::for_at_least(
+ std::chrono::nanoseconds(timeout.toRawNanoseconds()));
+ bool did_acquire = notification_.try_acquire_for(pw_timeout);
+ mutex.lock();
+ return did_acquire;
+}
+
+} // namespace chre
diff --git a/pw_chre/include/chre/target_platform/fatal_error.h b/pw_chre/include/chre/target_platform/fatal_error.h
new file mode 100644
index 000000000..5b236f613
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/fatal_error.h
@@ -0,0 +1,21 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+#include "pw_assert/assert.h"
+
+#define FATAL_ERROR_QUIT() \
+ do { \
+ PW_ASSERT(false); \
+ } while (0)
diff --git a/pw_chre/include/chre/target_platform/host_link_base.h b/pw_chre/include/chre/target_platform/host_link_base.h
new file mode 100644
index 000000000..10621610a
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/host_link_base.h
@@ -0,0 +1,25 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+namespace chre {
+
+// TODO(b/294106526): This class will likely need a facade since this will be
+// implemented in downstream products.
+class HostLinkBase {
+ public:
+ void sendNanConfiguration(bool enable);
+};
+
+} // namespace chre
diff --git a/pw_chre/include/chre/target_platform/log.h b/pw_chre/include/chre/target_platform/log.h
new file mode 100644
index 000000000..58aad2907
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/log.h
@@ -0,0 +1,24 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+
+#include <cstddef>
+
+#include "pw_log/log.h"
+
+#define LOGW(...) PW_LOG_WARN(__VA_ARGS__)
+#define LOGE(...) PW_LOG_ERROR(__VA_ARGS__)
+#define LOGI(...) PW_LOG_INFO(__VA_ARGS__)
+#define LOGD(...) PW_LOG_DEBUG(__VA_ARGS__)
diff --git a/pw_chre/include/chre/target_platform/mutex_base.h b/pw_chre/include/chre/target_platform/mutex_base.h
new file mode 100644
index 000000000..b5e42b009
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/mutex_base.h
@@ -0,0 +1,20 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+#include "pw_sync/mutex.h"
+
+struct MutexBase {
+ pw::sync::Mutex mutex_;
+};
diff --git a/pw_chre/include/chre/target_platform/mutex_base_impl.h b/pw_chre/include/chre/target_platform/mutex_base_impl.h
new file mode 100644
index 000000000..215813861
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/mutex_base_impl.h
@@ -0,0 +1,31 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+
+#include "chre/platform/mutex.h"
+
+namespace chre {
+
+inline Mutex::Mutex() {}
+
+inline Mutex::~Mutex() {}
+
+inline void Mutex::lock() { mutex_.lock(); }
+
+inline bool Mutex::try_lock() { return mutex_.try_lock(); }
+
+inline void Mutex::unlock() { mutex_.unlock(); }
+
+} // namespace chre
diff --git a/pw_chre/include/chre/target_platform/platform_nanoapp_base.h b/pw_chre/include/chre/target_platform/platform_nanoapp_base.h
new file mode 100644
index 000000000..6f12d1e4a
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/platform_nanoapp_base.h
@@ -0,0 +1,29 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+
+#include "chre/platform/shared/nanoapp_support_lib_dso.h"
+
+namespace chre {
+
+class PlatformNanoappBase {
+ public:
+ void loadStatic(const struct chreNslNanoappInfo* app_info);
+
+ protected:
+ const struct chreNslNanoappInfo* app_info_ = nullptr;
+};
+
+} // namespace chre
diff --git a/pw_chre/include/chre/target_platform/platform_sensor_base.h b/pw_chre/include/chre/target_platform/platform_sensor_base.h
new file mode 100644
index 000000000..d87095de7
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/platform_sensor_base.h
@@ -0,0 +1,43 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+#include "chre_api/chre/sensor.h"
+
+namespace chre {
+
+class PlatformSensorBase {
+ public:
+ void initBase(const struct chreSensorInfo* sensor_info,
+ uint32_t sensor_handle) {
+ sensor_info_ = sensor_info;
+ sensor_handle_ = sensor_handle;
+ }
+
+ void setSensorInfo(const struct chreSensorInfo* sensor_info) {
+ sensor_info_ = sensor_info;
+ }
+
+ void setSensorHandle(uint32_t sensor_handle) {
+ sensor_handle_ = sensor_handle;
+ }
+
+ uint32_t getSensorHandle() const { return sensor_handle_; }
+
+ protected:
+ const struct chreSensorInfo* sensor_info_;
+ uint32_t sensor_handle_;
+};
+
+} // namespace chre
diff --git a/pw_chre/include/chre/target_platform/platform_sensor_manager_base.h b/pw_chre/include/chre/target_platform/platform_sensor_manager_base.h
new file mode 100644
index 000000000..1c425bdef
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/platform_sensor_manager_base.h
@@ -0,0 +1,38 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+#include <cstdint>
+
+#include "chre/pal/sensor.h"
+
+namespace chre {
+
+class PlatformSensorManagerBase {
+ public:
+ // Note: these are load bearing names
+ static const chrePalSensorCallbacks sSensorCallbacks;
+ const chrePalSensorApi* mSensorApi;
+
+ private:
+ static void samplingStatusUpdateCallback(
+ uint32_t sensor_handle, struct chreSensorSamplingStatus* status);
+ static void dataEventCallback(uint32_t sensor_handle, void* data);
+ static void biasEventCallback(uint32_t sensor_handle, void* bias_data);
+ static void flushCompleteCallback(uint32_t sensor_handle,
+ uint32_t flush_request_id,
+ uint8_t error_code);
+};
+
+} // namespace chre
diff --git a/pw_chre/include/chre/target_platform/platform_sensor_type_helpers_base.h b/pw_chre/include/chre/target_platform/platform_sensor_type_helpers_base.h
new file mode 100644
index 000000000..072f88678
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/platform_sensor_type_helpers_base.h
@@ -0,0 +1,20 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+namespace chre {
+
+class PlatformSensorTypeHelpersBase {};
+
+} // namespace chre
diff --git a/pw_chre/include/chre/target_platform/power_control_manager_base.h b/pw_chre/include/chre/target_platform/power_control_manager_base.h
new file mode 100644
index 000000000..c1d00d376
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/power_control_manager_base.h
@@ -0,0 +1,21 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+
+namespace chre {
+
+class PowerControlManagerBase {};
+
+} // namespace chre
diff --git a/pw_chre/include/chre/target_platform/static_nanoapp_init.h b/pw_chre/include/chre/target_platform/static_nanoapp_init.h
new file mode 100644
index 000000000..6f2c09119
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/static_nanoapp_init.h
@@ -0,0 +1,50 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+
+#include "chre/core/static_nanoapps.h"
+#include "chre/platform/fatal_error.h"
+#include "chre/platform/shared/nanoapp_support_lib_dso.h"
+
+#define CHRE_STATIC_NANOAPP_INIT(appName, appId_, appVersion_, appPerms) \
+ namespace chre { \
+ \
+ UniquePtr<Nanoapp> initializeStaticNanoapp##appName() { \
+ UniquePtr<Nanoapp> nanoapp = MakeUnique<Nanoapp>(); \
+ static struct chreNslNanoappInfo appInfo; \
+ appInfo.magic = CHRE_NSL_NANOAPP_INFO_MAGIC; \
+ appInfo.structMinorVersion = CHRE_NSL_NANOAPP_INFO_STRUCT_MINOR_VERSION; \
+ appInfo.targetApiVersion = CHRE_API_VERSION; \
+ appInfo.vendor = "Google"; \
+ appInfo.name = #appName; \
+ appInfo.isSystemNanoapp = true; \
+ appInfo.isTcmNanoapp = false; \
+ appInfo.appId = appId_; \
+ appInfo.appVersion = appVersion_; \
+ appInfo.entryPoints.start = nanoappStart; \
+ appInfo.entryPoints.handleEvent = nanoappHandleEvent; \
+ appInfo.entryPoints.end = nanoappEnd; \
+ appInfo.appVersionString = "<undefined>"; \
+ appInfo.appPermissions = appPerms; \
+ if (nanoapp.isNull()) { \
+ FATAL_ERROR("Failed to allocate nanoapp " #appName); \
+ } else { \
+ nanoapp->loadStatic(&appInfo); \
+ } \
+ \
+ return nanoapp; \
+ } \
+ \
+ } // namespace chre
diff --git a/pw_chre/include/chre/target_platform/system_timer_base.h b/pw_chre/include/chre/target_platform/system_timer_base.h
new file mode 100644
index 000000000..e8cb288c0
--- /dev/null
+++ b/pw_chre/include/chre/target_platform/system_timer_base.h
@@ -0,0 +1,38 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+
+#include <cinttypes>
+
+#include "pw_chrono/system_timer.h"
+
+namespace chre {
+
+class SystemTimerBase {
+ public:
+ SystemTimerBase()
+ : timer_([this](pw::chrono::SystemClock::time_point) {
+ this->OnExpired();
+ }) {}
+
+ protected:
+ void OnExpired();
+
+ bool is_active_ = false;
+ bool initialized_ = false;
+ pw::chrono::SystemTimer timer_;
+};
+
+} // namespace chre
diff --git a/pw_chre/memory.cc b/pw_chre/memory.cc
new file mode 100644
index 000000000..e5241c955
--- /dev/null
+++ b/pw_chre/memory.cc
@@ -0,0 +1,31 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "chre/platform/memory.h"
+
+#include <cstdlib>
+
+namespace chre {
+
+// TODO(b/294106526): Today these APIs call the system malloc and free, but they
+// should be updated to use pw_allocator.
+void* memoryAlloc(size_t size) { return malloc(size); }
+
+void* palSystemApiMemoryAlloc(size_t size) { return malloc(size); }
+
+void memoryFree(void* pointer) { free(pointer); }
+
+void palSystemApiMemoryFree(void* pointer) { free(pointer); }
+
+} // namespace chre
diff --git a/pw_chre/memory_manager.cc b/pw_chre/memory_manager.cc
new file mode 100644
index 000000000..0d3786cf9
--- /dev/null
+++ b/pw_chre/memory_manager.cc
@@ -0,0 +1,27 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "chre/platform/memory_manager.h"
+
+#include "chre/util/memory.h"
+
+namespace chre {
+
+void* MemoryManager::doAlloc(Nanoapp*, uint32_t size) {
+ return chre::memoryAlloc(size);
+}
+
+void MemoryManager::doFree(Nanoapp*, void* ptr) { chre::memoryFree(ptr); }
+
+} // namespace chre
diff --git a/pw_chre/platform_debug_dump_manager.cc b/pw_chre/platform_debug_dump_manager.cc
new file mode 100644
index 000000000..c7aa93c1d
--- /dev/null
+++ b/pw_chre/platform_debug_dump_manager.cc
@@ -0,0 +1,27 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "chre/platform/platform_debug_dump_manager.h"
+
+namespace chre {
+
+PlatformDebugDumpManagerBase::PlatformDebugDumpManagerBase() {}
+
+PlatformDebugDumpManagerBase::~PlatformDebugDumpManagerBase() {}
+
+// TODO(b/294106526): Implement these.
+void PlatformDebugDumpManager::sendDebugDump(const char*, bool) {}
+
+void PlatformDebugDumpManager::logStateToBuffer(DebugDumpWrapper&) {}
+
+} // namespace chre
diff --git a/pw_chre/platform_nanoapp.cc b/pw_chre/platform_nanoapp.cc
new file mode 100644
index 000000000..5c9076901
--- /dev/null
+++ b/pw_chre/platform_nanoapp.cc
@@ -0,0 +1,77 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "chre/platform/platform_nanoapp.h"
+
+#include "chre/util/system/napp_permissions.h"
+#include "chre_api/chre/version.h"
+
+namespace chre {
+
+PlatformNanoapp::~PlatformNanoapp() {}
+
+bool PlatformNanoapp::start() { return app_info_->entryPoints.start(); }
+
+void PlatformNanoapp::handleEvent(uint32_t SenderInstanceId,
+ uint16_t eventType,
+ const void* eventData) {
+ app_info_->entryPoints.handleEvent(SenderInstanceId, eventType, eventData);
+}
+
+void PlatformNanoapp::end() { app_info_->entryPoints.end(); }
+
+uint64_t PlatformNanoapp::getAppId() const {
+ return (app_info_ == nullptr) ? 0 : app_info_->appId;
+}
+
+uint32_t PlatformNanoapp::getAppVersion() const {
+ return app_info_->appVersion;
+}
+
+uint32_t PlatformNanoapp::getTargetApiVersion() const {
+ return CHRE_API_VERSION;
+}
+
+const char* PlatformNanoapp::getAppName() const {
+ return (app_info_ != nullptr) ? app_info_->name : "Unknown";
+}
+
+bool PlatformNanoapp::supportsAppPermissions() const {
+ return (app_info_ != nullptr) ? (app_info_->structMinorVersion >=
+ CHRE_NSL_NANOAPP_INFO_STRUCT_MINOR_VERSION)
+ : false;
+}
+
+uint32_t PlatformNanoapp::getAppPermissions() const {
+ return (supportsAppPermissions())
+ ? app_info_->appPermissions
+ : static_cast<uint32_t>(chre::NanoappPermissions::CHRE_PERMS_NONE);
+}
+
+bool PlatformNanoapp::isSystemNanoapp() const {
+ return (app_info_ != nullptr && app_info_->isSystemNanoapp);
+}
+
+void PlatformNanoapp::logStateToBuffer(DebugDumpWrapper& debugDump) const {
+ if (!app_info_) {
+ return;
+ }
+ debugDump.print("%s: %s", app_info_->name, app_info_->vendor);
+}
+
+void PlatformNanoappBase::loadStatic(
+ const struct chreNslNanoappInfo* app_info) {
+ app_info_ = app_info;
+}
+
+} // namespace chre
diff --git a/pw_chre/platform_pal.cc b/pw_chre/platform_pal.cc
new file mode 100644
index 000000000..04fffefcb
--- /dev/null
+++ b/pw_chre/platform_pal.cc
@@ -0,0 +1,22 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "chre/platform/shared/platform_pal.h"
+
+namespace chre {
+
+// TODO(b/294106526): Implement this.
+void PlatformPal::prePalApiCall(PalType) const {}
+
+} // namespace chre
diff --git a/pw_chre/power_control_manager.cc b/pw_chre/power_control_manager.cc
new file mode 100644
index 000000000..b2d229e46
--- /dev/null
+++ b/pw_chre/power_control_manager.cc
@@ -0,0 +1,25 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "chre/platform/power_control_manager.h"
+
+namespace chre {
+
+// TODO(b/294106526): Implement these, possibly by adding a facade.
+void PowerControlManager::preEventLoopProcess(size_t) {}
+void PowerControlManager::postEventLoopProcess(size_t) {}
+
+bool PowerControlManager::hostIsAwake() { return true; }
+
+} // namespace chre
diff --git a/pw_chre/public/pw_chre/chre.h b/pw_chre/public/pw_chre/chre.h
new file mode 100644
index 000000000..69f6f81d2
--- /dev/null
+++ b/pw_chre/public/pw_chre/chre.h
@@ -0,0 +1,71 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+
+#include <cstddef>
+#include <cstdint>
+
+#include "pw_chre/host_link.h"
+
+namespace pw::chre {
+
+/// A message to be sent to a CHRE nanoapp.
+/// This message originated from the Application Processor (AP).
+struct NanoappMessage {
+ /// The id of the nanoapp this message is sent to.
+ uint64_t nano_app_id;
+ /// The type of message this is.
+ uint32_t message_type;
+ /// The id of the host on the AP that sent this request.
+ uint16_t host_endpoint;
+ /// The actual message data.
+ const uint8_t* data;
+ /// The size in bytes of the message data.
+ size_t length;
+};
+
+/// Initialize the CHRE environment and load any static nanoapps that exist.
+/// This must be called before the event loop has been started.
+void Init();
+
+/// Teardown the CHRE environment.
+/// This must be called after Init and after the event loop has been stopped.
+void Deinit();
+
+/// Run the CHRE event loop.
+/// This function will not return until `StopEventLoop` is called.
+void RunEventLoop();
+
+/// Stop the CHRE event loop.
+/// This can be called from any thread.
+void StopEventLoop();
+
+/// Send a message to a nano app.
+/// This can be called from any thread.
+/// @param[in] message The message being send to the nano app.
+void SendMessageToNanoapp(NanoappMessage message);
+
+/// Free a message that CHRE created to send to the AP (via `SendMessageToAp`).
+/// This function must be called after the message is finishd being used.
+/// After this function is called, the message data must not be accessed.
+/// This can be called from any thread.
+/// @param[in] context The message being freed.
+void FreeMessageToAp(MessageToApContext context);
+
+/// Set the estimated offset between the AP time and CHRE's time.
+/// @param[in] offset The offset time in nanoseconds.
+void SetEstimatedHostTimeOffset(int64_t offset);
+
+} // namespace pw::chre
diff --git a/pw_chre/public/pw_chre/host_link.h b/pw_chre/public/pw_chre/host_link.h
new file mode 100644
index 000000000..ca4e2cc73
--- /dev/null
+++ b/pw_chre/public/pw_chre/host_link.h
@@ -0,0 +1,67 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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.
+
+#pragma once
+
+#include <cstddef>
+#include <cstdint>
+
+// These host link functions should be implemented by the system integrator.
+namespace pw::chre {
+
+/// This is a token representing a message that CHRE allocated.
+/// It must be passed to `FreeMessageToAp` when the message is finished.
+typedef const void* MessageToApContext;
+
+/// This is a message that should be sent to the AP.
+/// It was allocated by CHRE, so pw::chre::FreeMessageToAp should be called
+/// in order to free it.
+struct MessageToAp {
+ /// The id of the nanoapp sending the message.
+ uint64_t nanoapp_id;
+
+ /// The type of the message.
+ uint32_t message_type;
+
+ uint32_t app_permissions;
+ uint32_t message_permissions;
+
+ /// The id of the client that this message should be delivered to on the host.
+ uint16_t host_endpoint;
+
+ /// Whether CHRE is responsible for waking the AP.
+ /// If this is true, then the client must wake the AP in
+ /// `SendMessageToAp` before sending this message.
+ bool woke_host;
+
+ /// The underlying data of the message. This is owned by `chre_context` and
+ /// should not be accessed after the message has been freed.
+ const uint8_t* data;
+
+ /// The length of `data` in bytes.
+ size_t length;
+
+ /// The context of the message, used to free the message when the client is
+ /// finished sending it.
+ MessageToApContext chre_context;
+};
+
+/// CHRE calls this method to send a message to the Application Processor (AP).
+/// The client must implement this method, and the client is responsible for
+/// calling `FreeMessageToAp` once they are finished with the message.
+/// @param[in] message The message to be sent.
+/// @param[out] bool Whether this method was successful.
+bool SendMessageToAp(MessageToAp message);
+
+} // namespace pw::chre
diff --git a/pw_chre/static_nanoapps.cc b/pw_chre/static_nanoapps.cc
new file mode 100644
index 000000000..8612b7586
--- /dev/null
+++ b/pw_chre/static_nanoapps.cc
@@ -0,0 +1,34 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "chre/core/static_nanoapps.h"
+
+#include "chre/apps/apps.h"
+#include "chre/util/macros.h"
+
+namespace chre {
+
+const StaticNanoappInitFunction kStaticNanoappList[] = {
+ initializeStaticNanoappHelloWorld,
+ initializeStaticNanoappMessageWorld,
+#if defined(INCLUDE_SENSOR_APP)
+ initializeStaticNanoappSensorWorld,
+#endif
+ initializeStaticNanoappSpammer,
+ initializeStaticNanoappTimerWorld,
+ initializeStaticNanoappUnloadTester,
+};
+
+const size_t kStaticNanoappCount = ARRAY_SIZE(kStaticNanoappList);
+
+} // namespace chre
diff --git a/pw_chre/system_time.cc b/pw_chre/system_time.cc
new file mode 100644
index 000000000..9a9df9a61
--- /dev/null
+++ b/pw_chre/system_time.cc
@@ -0,0 +1,45 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "chre/platform/system_time.h"
+
+#include "chre/platform/assert.h"
+#include "chre/platform/log.h"
+#include "pw_chrono/system_clock.h"
+
+namespace chre {
+
+namespace {
+
+int64_t estimated_host_time_offset = 0;
+
+}
+
+Nanoseconds SystemTime::getMonotonicTime() {
+ const pw::chrono::SystemClock::time_point now =
+ pw::chrono::SystemClock::now();
+ auto nsecs = std::chrono::duration_cast<std::chrono::nanoseconds>(
+ now.time_since_epoch())
+ .count();
+ return Nanoseconds(static_cast<uint64_t>(nsecs));
+}
+
+int64_t SystemTime::getEstimatedHostTimeOffset() {
+ return estimated_host_time_offset;
+}
+
+void SystemTime::setEstimatedHostTimeOffset(int64_t offset) {
+ estimated_host_time_offset = offset;
+}
+
+} // namespace chre
diff --git a/pw_chre/system_timer.cc b/pw_chre/system_timer.cc
new file mode 100644
index 000000000..b178815be
--- /dev/null
+++ b/pw_chre/system_timer.cc
@@ -0,0 +1,67 @@
+// Copyright 2023 The Pigweed Authors
+//
+// 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
+//
+// https://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 "chre/platform/system_timer.h"
+
+#include "chre/platform/log.h"
+#include "chre/util/time.h"
+
+namespace chre {
+
+void SystemTimerBase::OnExpired() {
+ SystemTimer* timer = static_cast<SystemTimer*>(this);
+ timer->mCallback(timer->mData);
+}
+
+SystemTimer::SystemTimer() {}
+
+SystemTimer::~SystemTimer() {
+ if (!initialized_) {
+ return;
+ }
+ cancel();
+ initialized_ = false;
+}
+
+bool SystemTimer::init() {
+ initialized_ = true;
+ return initialized_;
+}
+
+bool SystemTimer::set(SystemTimerCallback* callback,
+ void* data,
+ Nanoseconds delay) {
+ if (!initialized_) {
+ return false;
+ }
+ mCallback = callback;
+ mData = data;
+ pw::chrono::SystemClock::duration interval =
+ std::chrono::nanoseconds(delay.toRawNanoseconds());
+ const pw::chrono::SystemClock::time_point now =
+ pw::chrono::SystemClock::now();
+ timer_.InvokeAt(now + interval);
+ return true;
+}
+
+bool SystemTimer::cancel() {
+ if (!initialized_) {
+ return false;
+ }
+ timer_.Cancel();
+ return true;
+}
+
+bool SystemTimer::isActive() { return is_active_; }
+
+} // namespace chre