xref: /aosp_15_r20/system/chre/doc/framework_overview.md (revision 84e339476a462649f82315436d70fd732297a399)
1*84e33947SAndroid Build Coastguard Worker*** aside
2*84e33947SAndroid Build Coastguard WorkerSee also:
3*84e33947SAndroid Build Coastguard Worker[Porting Guide](/doc/porting_guide.md) |
4*84e33947SAndroid Build Coastguard Worker[Build System](/doc/framework_build.md) |
5*84e33947SAndroid Build Coastguard Worker[Debugging](/doc/framework_debugging.md) |
6*84e33947SAndroid Build Coastguard Worker[Testing](/doc/framework_testing.md) |
7*84e33947SAndroid Build Coastguard Worker[Vendor Extensions](/doc/vendor_extensions.md)
8*84e33947SAndroid Build Coastguard Worker***
9*84e33947SAndroid Build Coastguard Worker
10*84e33947SAndroid Build Coastguard Worker# CHRE Framework Overview
11*84e33947SAndroid Build Coastguard Worker
12*84e33947SAndroid Build Coastguard Worker[TOC]
13*84e33947SAndroid Build Coastguard Worker
14*84e33947SAndroid Build Coastguard WorkerThe CHRE reference implementation (hereafter referred to just as "CHRE" or "the
15*84e33947SAndroid Build Coastguard WorkerCHRE framework") is developed primarily in C++17 using a modular object-oriented
16*84e33947SAndroid Build Coastguard Workerapproach that separates common code from platform-specific code. CHRE is an
17*84e33947SAndroid Build Coastguard Workerevent-based system, so CHRE is built around an event loop which executes nanoapp
18*84e33947SAndroid Build Coastguard Workercode as well as CHRE system callbacks. Per the CHRE API, nanoapps can’t execute
19*84e33947SAndroid Build Coastguard Workerin more than one thread at a time, so CHRE is structured around a single thread
20*84e33947SAndroid Build Coastguard Workerthat executes the event loop, although there may be other threads in the system
21*84e33947SAndroid Build Coastguard Workerthat support CHRE. The EventLoopManager is a Singleton object which owns the
22*84e33947SAndroid Build Coastguard Workermain state of the CHRE framework, including EventLoop and \*Manager classes for
23*84e33947SAndroid Build Coastguard Workerthe various subsystems supported by CHRE.
24*84e33947SAndroid Build Coastguard Worker
25*84e33947SAndroid Build Coastguard WorkerTo get a better understanding of code structure and how it weaves between common
26*84e33947SAndroid Build Coastguard Workerand platform-specific components, it is helpful to trace the flow through a few
27*84e33947SAndroid Build Coastguard Workerexample scenarios. Note that this is not meant to be an exhaustive list of
28*84e33947SAndroid Build Coastguard Workereverything that happens in each case (for that, refer to the code itself), but
29*84e33947SAndroid Build Coastguard Workerrather an overview of key points to serve as an introduction.
30*84e33947SAndroid Build Coastguard Worker
31*84e33947SAndroid Build Coastguard Worker## Loading a nanoapp via the HAL
32*84e33947SAndroid Build Coastguard Worker
33*84e33947SAndroid Build Coastguard WorkerThere are multiple ways by which a nanoapp can be loaded (see the relevant
34*84e33947SAndroid Build Coastguard Workersection below for details), but this example traces the flow for dynamically
35*84e33947SAndroid Build Coastguard Workerloading a nanoapp that has been passed in via the Context Hub HAL's
36*84e33947SAndroid Build Coastguard Worker`loadNanoapp()` method.
37*84e33947SAndroid Build Coastguard Worker
38*84e33947SAndroid Build Coastguard Worker1. The nanoapp binary reaches the HAL implementation, and it is loaded into the
39*84e33947SAndroid Build Coastguard Worker   processor where CHRE is running using a platform-specific method. While the
40*84e33947SAndroid Build Coastguard Worker   path this takes can vary, one common approach is to transmit the binary into
41*84e33947SAndroid Build Coastguard Worker   CHRE via the platform-specific HostLink implementation, then verify its
42*84e33947SAndroid Build Coastguard Worker   digital signature, and parse the binary file format (e.g. ELF) to load and
43*84e33947SAndroid Build Coastguard Worker   link the code.
44*84e33947SAndroid Build Coastguard Worker
45*84e33947SAndroid Build Coastguard Worker2. Once the nanoapp code is loaded, the platform code calls
46*84e33947SAndroid Build Coastguard Worker   `EventLoopManager::deferCallback()` to switch context to the main CHRE thread
47*84e33947SAndroid Build Coastguard Worker   (if needed), so it can complete loading and starting the nanoapp.
48*84e33947SAndroid Build Coastguard Worker   `deferCallback()` effectively posts an event to the main event loop which
49*84e33947SAndroid Build Coastguard Worker   does not get delivered to any nanoapps. Instead, the purpose is to invoke the
50*84e33947SAndroid Build Coastguard Worker   supplied callback from the CHRE thread once the event is popped off the
51*84e33947SAndroid Build Coastguard Worker   queue.
52*84e33947SAndroid Build Coastguard Worker
53*84e33947SAndroid Build Coastguard Worker3. The (platform-specific) callback finalizes the newly constructed `Nanoapp`
54*84e33947SAndroid Build Coastguard Worker   object as needed, and passes it to `EventLoop::startNanoapp()` - this marks a
55*84e33947SAndroid Build Coastguard Worker   transition from platform-specific to common code.
56*84e33947SAndroid Build Coastguard Worker
57*84e33947SAndroid Build Coastguard Worker4. `EventLoop` takes ownership of the `Nanoapp` object (which is a composite of
58*84e33947SAndroid Build Coastguard Worker   common and platform-specific data and functions, as described in the Platform
59*84e33947SAndroid Build Coastguard Worker   Abstractions section), includes it in the collection of loaded nanoapps to
60*84e33947SAndroid Build Coastguard Worker   execute in the main event loop, updates `mCurrentNanoapp` to reference the
61*84e33947SAndroid Build Coastguard Worker   nanoapp it's about to execute, and calls into `PlatformNanoapp::start()`.
62*84e33947SAndroid Build Coastguard Worker
63*84e33947SAndroid Build Coastguard Worker5. Since the mechanism of supporting dynamic linkage and position independent
64*84e33947SAndroid Build Coastguard Worker   code can vary by platform, transferring control from the framework to a
65*84e33947SAndroid Build Coastguard Worker   nanoapp is considered part of the platform layer. So
66*84e33947SAndroid Build Coastguard Worker   `PlatformNanoapp::start()` performs any necessary tasks for this, and calls
67*84e33947SAndroid Build Coastguard Worker   into the `nanoappStart()` function defined in the nanoapp binary.
68*84e33947SAndroid Build Coastguard Worker
69*84e33947SAndroid Build Coastguard Worker## Invoking a CHRE API from a nanoapp
70*84e33947SAndroid Build Coastguard Worker
71*84e33947SAndroid Build Coastguard WorkerLet's assume the nanoapp we've loaded in the previous section calls the
72*84e33947SAndroid Build Coastguard Worker`chreSensorConfigure()` CHRE API function within `nanoappStart()`:
73*84e33947SAndroid Build Coastguard Worker
74*84e33947SAndroid Build Coastguard Worker1. The nanoapp invokes `chreSensorConfigure()` with parameters to enable the
75*84e33947SAndroid Build Coastguard Worker   accelerometer.
76*84e33947SAndroid Build Coastguard Worker
77*84e33947SAndroid Build Coastguard Worker2. The Nanoapp Support Library (NSL) and/or the platform's dynamic linking
78*84e33947SAndroid Build Coastguard Worker   module are responsible for handling the transition of control from the
79*84e33947SAndroid Build Coastguard Worker   nanoapp binary to the CHRE framework. This can vary by platform, but we'll
80*84e33947SAndroid Build Coastguard Worker   assume that control arrives in the `chreSensorConfigure()` implementation in
81*84e33947SAndroid Build Coastguard Worker   `platform/shared/chre_api_sensor.cc`.
82*84e33947SAndroid Build Coastguard Worker
83*84e33947SAndroid Build Coastguard Worker3. `EventLoopManager::validateChreApiCall()` is invoked to confirm that this
84*84e33947SAndroid Build Coastguard Worker   function is being called from the context of a nanoapp being executed within
85*84e33947SAndroid Build Coastguard Worker   the event loop (since associating the API call with a specific nanoapp is a
86*84e33947SAndroid Build Coastguard Worker   requirement of this API and many others, and the majority of the CHRE
87*84e33947SAndroid Build Coastguard Worker   framework code is only safe to execute from within the main CHRE thread), and
88*84e33947SAndroid Build Coastguard Worker   fetch a pointer to the current `Nanoapp` (i.e. it retrieves `mCurrentNanoapp`
89*84e33947SAndroid Build Coastguard Worker   set previosly by `EventLoop`).
90*84e33947SAndroid Build Coastguard Worker
91*84e33947SAndroid Build Coastguard Worker4. `SensorManager::setSensorRequest()` (via
92*84e33947SAndroid Build Coastguard Worker   `EventLoopManager::getSensorRequestManager()`) is called to process the
93*84e33947SAndroid Build Coastguard Worker   nanoapp’s request - we transition to common code here.
94*84e33947SAndroid Build Coastguard Worker
95*84e33947SAndroid Build Coastguard Worker5. The request is validated and combined with other nanoapp requests for the
96*84e33947SAndroid Build Coastguard Worker   same sensor to determine the effective sensor configuration that should be
97*84e33947SAndroid Build Coastguard Worker   requested from the platform, and the nanoapp is registered to receive
98*84e33947SAndroid Build Coastguard Worker   broadcast accelerometer sensor events.
99*84e33947SAndroid Build Coastguard Worker
100*84e33947SAndroid Build Coastguard Worker6. `SensorRequestManager` calls into `PlatformSensorManager::configureSensor()`,
101*84e33947SAndroid Build Coastguard Worker   which performs the necessary operations to actually configure the
102*84e33947SAndroid Build Coastguard Worker   accelerometer to collect data.
103*84e33947SAndroid Build Coastguard Worker
104*84e33947SAndroid Build Coastguard Worker7. Assuming success, the return value propagates back up to the nanoapp, and it
105*84e33947SAndroid Build Coastguard Worker   continues executing.
106*84e33947SAndroid Build Coastguard Worker
107*84e33947SAndroid Build Coastguard Worker## Passing an event to a nanoapp
108*84e33947SAndroid Build Coastguard Worker
109*84e33947SAndroid Build Coastguard WorkerFollowing the example from above, let's follow the case where an accelerometer
110*84e33947SAndroid Build Coastguard Workersample has been generated and is delivered to the nanoapp for processing.
111*84e33947SAndroid Build Coastguard Worker
112*84e33947SAndroid Build Coastguard Worker1. Starting in platform-specific code, likely in a different thread, the
113*84e33947SAndroid Build Coastguard Worker   accelerometer sample is received from the underlying sensor framework - this
114*84e33947SAndroid Build Coastguard Worker   typically happens in a different thread than the main CHRE thread, and within
115*84e33947SAndroid Build Coastguard Worker   the fully platform-specific `PlatformSensorManagerBase` class.
116*84e33947SAndroid Build Coastguard Worker
117*84e33947SAndroid Build Coastguard Worker2. As needed, memory is allocated to store the sample while it is being
118*84e33947SAndroid Build Coastguard Worker   processed, and the data is converted into the CHRE format: `struct
119*84e33947SAndroid Build Coastguard Worker   chreSensorThreeAxisData`.
120*84e33947SAndroid Build Coastguard Worker
121*84e33947SAndroid Build Coastguard Worker3. `SensorRequestManager::handleSensorDataEvent()` is invoked (common code) to
122*84e33947SAndroid Build Coastguard Worker   distribute the data to nanoapps.
123*84e33947SAndroid Build Coastguard Worker
124*84e33947SAndroid Build Coastguard Worker4. `SensorRequestManager` calls into `EventLoop` to post an event containing the
125*84e33947SAndroid Build Coastguard Worker   sensor data to all nanoapps registered for the broadcast event type
126*84e33947SAndroid Build Coastguard Worker   associated with accelerometer data, and sets `sensorDataEventFree()` as the
127*84e33947SAndroid Build Coastguard Worker   callback invoked after the system is done processing the event.
128*84e33947SAndroid Build Coastguard Worker
129*84e33947SAndroid Build Coastguard Worker5. `EventLoop` adds this event to its event queue and signals the CHRE thread.
130*84e33947SAndroid Build Coastguard Worker
131*84e33947SAndroid Build Coastguard Worker6. Now, within the context of the CHRE thread, once the event loop pops this
132*84e33947SAndroid Build Coastguard Worker   event off of its queue in `EventLoop::run()`, the `nanoappHandleEvent()`
133*84e33947SAndroid Build Coastguard Worker   function is invoked (via `PlatformNanoapp`, as with `nanoappStart`) for each
134*84e33947SAndroid Build Coastguard Worker   nanoapp that should receive the event.
135*84e33947SAndroid Build Coastguard Worker
136*84e33947SAndroid Build Coastguard Worker7. Once the event has been processed by each nanoapp, the free callback
137*84e33947SAndroid Build Coastguard Worker   (`sensorDataEventFree()`), is called to release any memory or do other
138*84e33947SAndroid Build Coastguard Worker   necessary cleanup actions now that the event is complete.
139*84e33947SAndroid Build Coastguard Worker
140*84e33947SAndroid Build Coastguard Worker## Platform Abstractions
141*84e33947SAndroid Build Coastguard Worker
142*84e33947SAndroid Build Coastguard WorkerCHRE follows the 'compile time polymorphism' paradigm, to allow for the benefits
143*84e33947SAndroid Build Coastguard Workerof `virtual` functions, while minimizing code size impact on systems with tight
144*84e33947SAndroid Build Coastguard Workermemory constraints.
145*84e33947SAndroid Build Coastguard Worker
146*84e33947SAndroid Build Coastguard WorkerEach framework module as described in the previous section is represented by a
147*84e33947SAndroid Build Coastguard WorkerC++ class in `core/`, which serves as the top-level reference to the module and
148*84e33947SAndroid Build Coastguard Workerdefines and implements the common functionality. This common object is then
149*84e33947SAndroid Build Coastguard Workercomposed with platform-specific functionality at compile-time. Using the
150*84e33947SAndroid Build Coastguard Worker`SensorRequestManager` class as an example, its role is to manage common
151*84e33947SAndroid Build Coastguard Workerfunctionality, such as multiplexing sensor requests from all clients into a
152*84e33947SAndroid Build Coastguard Workersingle request made to the platform through the `PlatformSensorManager` class,
153*84e33947SAndroid Build Coastguard Workerwhich in turn is responsible for forwarding that request to the underlying
154*84e33947SAndroid Build Coastguard Workersensor system.
155*84e33947SAndroid Build Coastguard Worker
156*84e33947SAndroid Build Coastguard WorkerWhile `SensorRequestManager` is fully common code, `PlatformSensorManager` is
157*84e33947SAndroid Build Coastguard Workerdefined in a common header file (under `platform/include/chre/platform`), but
158*84e33947SAndroid Build Coastguard Workerimplemented in a platform-specific source file. In other words, it defines the
159*84e33947SAndroid Build Coastguard Workerinterface between common code and platform-specific code.
160*84e33947SAndroid Build Coastguard Worker
161*84e33947SAndroid Build Coastguard Worker`PlatformSensorManager` inherits from `PlatformSensorManagerBase`, which is
162*84e33947SAndroid Build Coastguard Workerdefined in a platform-specific header file, which allows for extending
163*84e33947SAndroid Build Coastguard Worker`PlatformSensorManager` with platform-specific functions and data. This pattern
164*84e33947SAndroid Build Coastguard Workerapplies for all `Platform<Module>` classes, which must be implemented for all
165*84e33947SAndroid Build Coastguard Workerplatforms that support the given module.
166*84e33947SAndroid Build Coastguard Worker
167*84e33947SAndroid Build Coastguard WorkerSelection of which `PlatformSensorManager` and `PlatformSensorManagerBase`
168*84e33947SAndroid Build Coastguard Workerimplementation is instantiated is controlled by the build system, by setting the
169*84e33947SAndroid Build Coastguard Workerappropriate include path and source files. This includes the path used to
170*84e33947SAndroid Build Coastguard Workerresolve include directives appearing in common code but referencing
171*84e33947SAndroid Build Coastguard Workerplatform-specific headers, like `#include
172*84e33947SAndroid Build Coastguard Worker"chre/target_platform/platform_sensor_manager_base.h"`.
173*84e33947SAndroid Build Coastguard Worker
174*84e33947SAndroid Build Coastguard WorkerTo ensure compatibility across all platforms, common code is restricted in how
175*84e33947SAndroid Build Coastguard Workerit interacts with platform-specific code - it must always go through a common
176*84e33947SAndroid Build Coastguard Workerinterface with platform-specific implementation, as described above. However,
177*84e33947SAndroid Build Coastguard Workerplatform-specific code is less restricted, and can refer to common code, as well
178*84e33947SAndroid Build Coastguard Workeras other platform code directly.
179*84e33947SAndroid Build Coastguard Worker
180*84e33947SAndroid Build Coastguard Worker## Coding conventions
181*84e33947SAndroid Build Coastguard Worker
182*84e33947SAndroid Build Coastguard WorkerThis project follows the [Google-wide style guide for C++
183*84e33947SAndroid Build Coastguard Workercode](https://google.github.io/styleguide/cppguide.html), with the exception of
184*84e33947SAndroid Build Coastguard WorkerAndroid naming conventions for methods and variables. This means 2 space
185*84e33947SAndroid Build Coastguard Workerindents, camelCase method names, an mPrefix on class members and so on.  Style
186*84e33947SAndroid Build Coastguard Workerrules that are not specified in the Android style guide are inherited from
187*84e33947SAndroid Build Coastguard WorkerGoogle. Additionally, this project uses clang-format for automatic code
188*84e33947SAndroid Build Coastguard Workerformatting.
189*84e33947SAndroid Build Coastguard Worker
190*84e33947SAndroid Build Coastguard WorkerThis project uses C++17, but with two main caveats:
191*84e33947SAndroid Build Coastguard Worker
192*84e33947SAndroid Build Coastguard Worker1. General considerations for using C++ in an embedded environment apply. This
193*84e33947SAndroid Build Coastguard Worker   means avoiding language features that can impose runtime overhead, due to the
194*84e33947SAndroid Build Coastguard Worker   relative scarcity of memory and CPU resources, and power considerations.
195*84e33947SAndroid Build Coastguard Worker   Examples include RTTI, exceptions, overuse of dynamic memory allocation, etc.
196*84e33947SAndroid Build Coastguard Worker   Refer to existing literature on this topic including this [Technical Report
197*84e33947SAndroid Build Coastguard Worker   on C++ Performance](http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf)
198*84e33947SAndroid Build Coastguard Worker   and so on.
199*84e33947SAndroid Build Coastguard Worker
200*84e33947SAndroid Build Coastguard Worker2. Full support of the C++ standard library is generally not expected to be
201*84e33947SAndroid Build Coastguard Worker   extensive or widespread in the embedded environments where this code will
202*84e33947SAndroid Build Coastguard Worker   run. This means things like <thread> and <mutex> should not be used, in
203*84e33947SAndroid Build Coastguard Worker   favor of simple platform abstractions that can be implemented directly with
204*84e33947SAndroid Build Coastguard Worker   less effort (potentially using those libraries if they are known to be
205*84e33947SAndroid Build Coastguard Worker   available).
206