pw_chre#

Android Context Hub Runtime Environment backend

Experimental C++

The Context Hub Runtime Environment (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#

namespace chre#

Typedefs

using MessageToApContext = const void*#

This is a token representing a message that CHRE allocated. It must be passed to FreeMessageToAp when the message is finished.

Functions

void Init()#

Initialize the CHRE environment and load any static nanoapps that exist. This must be called before the event loop has been started.

void Deinit()#

Teardown the CHRE environment. This must be called after Init and after the event loop has been stopped.

void RunEventLoop()#

Run the CHRE event loop. This function will not return until StopEventLoop is called.

void StopEventLoop()#

Stop the CHRE event loop. This can be called from any thread.

void SendMessageToNanoapp(NanoappMessage message)#

Send a message to a nano app. This can be called from any thread.

Parameters:

message[in] The message being send to the nano app.

void FreeMessageToAp(MessageToApContext context)#

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.

Parameters:

context[in] The message being freed.

void SetEstimatedHostTimeOffset(int64_t offset)#

Set the estimated offset between the AP time and CHRE’s time.

Parameters:

offset[in] The offset time in nanoseconds.

bool SendMessageToAp(MessageToAp message)#

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.

Parameters:
  • message[in] The message to be sent.

  • bool[out] Whether this method was successful.

struct MessageToAp#

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.

Public Members

uint64_t nanoapp_id#

The id of the nanoapp sending the message.

uint32_t message_type#

The type of the message.

uint16_t host_endpoint#

The id of the client that this message should be delivered to on the host.

bool woke_host#

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.

const uint8_t *data#

The underlying data of the message. This is owned by chre_context and should not be accessed after the message has been freed.

size_t length#

The length of data in bytes.

MessageToApContext chre_context#

The context of the message, used to free the message when the client is finished sending it.

struct NanoappMessage#

A message to be sent to a CHRE nanoapp. This message originated from the Application Processor (AP).

Public Members

uint64_t nano_app_id#

The id of the nanoapp this message is sent to.

uint32_t message_type#

The type of message this is.

uint16_t host_endpoint#

The id of the host on the AP that sent this request.

const uint8_t *data#

The actual message data.

size_t length#

The size in bytes of the message data.

Porting Guide#

The pw_chre module has completed the steps outlined for creating a new CHRE platform .

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.

List of PALs#

PAL Name

Pigweed implementation available

Audio

Bluetooth

GNSS

Sensor

Wifi

WWAN

For more information on a specific PAL see the PAL headers or the Linux reference PAL implementations.