diff options
author | David Gilhooley <dgilhooley@google.com> | 2023-09-12 14:36:00 +0000 |
---|---|---|
committer | CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-09-12 14:36:00 +0000 |
commit | f210a064bf6d67fe0d58074f4e3a6eed1e9851bd (patch) | |
tree | 8215f9431976c9519907c6fd4822c20c5b7da00d /pw_chre | |
parent | ef447ae6f95cab0d4f6f74f4e356c14f212cb0bb (diff) | |
download | pigweed-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')
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 |