Skip to content

modules: chre #41735

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/zephyr/arch/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@

/* Per CPU architecture specifics (empty) */
struct _cpu_arch {
#ifdef __cplusplus
/* This struct will have a size 0 in C which is not allowed in C++ (it'll have a size 1). To
* prevent this, we add a 1 byte dummy variable.
*/
uint8_t dummy;
#endif
};

#endif
Expand Down
9 changes: 9 additions & 0 deletions include/zephyr/kernel/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,15 @@ typedef struct k_thread_runtime_stats {

uint64_t idle_cycles;
#endif

#if __cplusplus && !defined(CONFIG_SCHED_THREAD_USAGE) && \
!defined(CONFIG_SCHED_THREAD_USAGE_ANALYSIS) && !defined(CONFIG_SCHED_THREAD_USAGE_ALL)
/* If none of the above Kconfig values are defined, this struct will have a size 0 in C
* which is not allowed in C++ (it'll have a size 1). To prevent this, we add a 1 byte dummy
* variable when the struct would otherwise be empty.
*/
uint8_t dummy;
#endif
} k_thread_runtime_stats_t;

struct z_poller {
Expand Down
3 changes: 3 additions & 0 deletions modules/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ comment "FFF module not available."
comment "zcbor module not available."
depends on !ZEPHYR_ZCBOR_MODULE

comment "CHRE module not available."
depends on !ZEPHYR_CHRE_MODULE

# This ensures that symbols are available in Kconfig for dependency checking
# and referencing, while keeping the settings themselves unavailable when the
# modules are not present in the workspace
Expand Down
11 changes: 11 additions & 0 deletions samples/modules/chre/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (c) Google LLC
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(chre_sample)

FILE(GLOB app_sources src/*.cpp)
target_sources(app PRIVATE ${app_sources})
target_include_directories(app PRIVATE include)
69 changes: 69 additions & 0 deletions samples/modules/chre/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
Android's Context Hub Runtime Environment (CHRE)
################################################

Android's context hub enables the use of nanoapps. A single nanoapp has 3 entry points seen in
`chre_api/chre/nanoapp.h`_:

* A ``nanoappStart`` function used to notify the nanoapp that it is now active.
* A ``nanoappHandleEvent`` function used to notify the nanoapp tha an event of interest took place.
* A ``nanoappEnd`` function used to notify the nanoapp that it is now deactivated.

The CHRE connects to several frameworks called Platform Abstraction Layers (PAL)s. Note that
currently, none of these are implemented for Zephyr, but they are scheduled to be added. These
frameworks include:

#. *Audio* - a framework allowing nanoapps to get audio events. See `pal/audio.h`_ for API details.
#. *GNSS* - a framework allowing nanoapps to manage location and measurement sessions. See
`pal/gnss.h`_ for API details.
#. *Sensor* - a framework allowing nanoapps to request changes to sensors configuration get
data/bias events. See `pal/sensor.h`_ for API details.
#. *System* - a framework allowing nanoapps to make common system requests such as logging, clock,
and some basic memory allocation/deallocation. See `pal/system.h`_ for API details.
#. *WiFi* - a framework allowing nanoapps to interact with the on board WiFi. See `pal/wifi.h`_ for
API details.
#. *WWAN* - a framework allowing nanoapps to interact with the WWAN module such as getting the
current capabilities and info. See `pal/wwan.h`_ for API details.

Building and expectations
=========================

To build the sample use the following west command:

.. zephyr-app-commands::
:zephyr-app: samples/modules/chre
:board: native_posix
:goals: build

Once built and run, the sample application should:

#. Print a hello message
#. Notify that the event loop started via an ``inf`` level log
#. Notify that a nanoapp was started and assigned an instance/app ID of 1 via a ``dbg`` level log
#. Print a message saying that the nanoapp's start callback was called
#. Send an event of type ``1`` and no data to the nanoapp
#. Notify that the event was processed
#. Call the ``nanoappEnd`` function of the nanoapp
#. Print a message notifying that it's not possible to remove a system level nanoapp
#. Exit the event loop

Roadmap
=======

#. Add an implementation of the `pal/sensor.h`_ and `pal/system.h`_ to Zephyr. These will be
standalone modules that can be used independently of CHRE, but when ``CONFIG_CHRE`` is enabled
will also provide an implementation of ``chrePalSensorGetApi()`` and ``struct chrePalSystemApi``.
#. Add a directory ``chre/nanoapps`` which will host various nanoapps to be used by the Zephyr
community. These should each have their own Kconfig to enable them and set the appropriate
dependencies. The first nanoapp will be a lid angle calculator which will use 2 accelerometers.
#. Update the ``overlay.dts`` of this sample application to include 2 emulated accelerometers and
configure them to return scripted data.
#. Run this sample application and watch the nanoapp provide lid angle calculations based on 2
accelerometers provided by the sensors PAL framework.

.. _`chre_api/chre/nanoapp.h`: https://cs.android.com/android/platform/superproject/+/master:system/chre/chre_api/include/chre_api/chre/nanoapp.h;drc=7c60a553288d63e6e3370d679803da46dac723a4
.. _`pal/audio.h`: https://cs.android.com/android/platform/superproject/+/master:system/chre/pal/include/chre/pal/audio.h;l=69;drc=6ca547ad175f80ce9f09f5b7b14fcc6f14565f5c
.. _`pal/gnss.h`: https://cs.android.com/android/platform/superproject/+/master:system/chre/pal/include/chre/pal/gnss.h;l=152;drc=830255234157cc7afe5201dca19a7fb71ea850fe
.. _`pal/sensor.h`: https://cs.android.com/android/platform/superproject/+/master:system/chre/pal/include/chre/pal/sensor.h;l=51;drc=23207906add05054a94dfab41b95bcfc39bedfe4
.. _`pal/system.h`: https://cs.android.com/android/platform/superproject/+/master:system/chre/pal/include/chre/pal/system.h;l=49;drc=6ca547ad175f80ce9f09f5b7b14fcc6f14565f5c
.. _`pal/wifi.h`: https://cs.android.com/android/platform/superproject/+/master:system/chre/pal/include/chre/pal/wifi.h;l=153;drc=b673b80ed98e1b6e6360bee4ba98e2cd8f4e0935
.. _`pal/wwan.h`: https://cs.android.com/android/platform/superproject/+/master:system/chre/pal/include/chre/pal/wwan.h;l=69;drc=629361a803cb305c8575b41614e6e071e7141a03
17 changes: 17 additions & 0 deletions samples/modules/chre/include/apps.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* Copyright (c) 2021 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef SAMPLES_APPLICATION_DEVELOPMENT_CHRE_INCLUDE_APPS_H_
#define SAMPLES_APPLICATION_DEVELOPMENT_CHRE_INCLUDE_APPS_H_

#include "chre/core/nanoapp.h"
#include "chre/util/unique_ptr.h"

namespace chre {

UniquePtr<Nanoapp> initializeStaticNanoappEchoApp();

} /* namespace chre */

#endif /* SAMPLES_APPLICATION_DEVELOPMENT_CHRE_INCLUDE_APPS_H_ */
7 changes: 7 additions & 0 deletions samples/modules/chre/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CONFIG_CHRE=y
CONFIG_LOG=y
CONFIG_CHRE_LOG_LEVEL_DBG=y

CONFIG_CPLUSPLUS=y
CONFIG_STD_CPP17=y
CONFIG_LIB_CPLUSPLUS=y
23 changes: 23 additions & 0 deletions samples/modules/chre/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
sample:
description: A simple echo app using Android's Context Hub Runtime
Environment (CHRE).
name: chre
tests:
sample.modules.chre:
tags: introduction
harness: console
harness_config:
type: multi_line
ordered: false
regex:
- "Hello CHRE!"
- "\\[.*\\] .*<inf> chre: EventLoop start.*"
- "\\[.*\\] .*<dbg> chre: startNanoapp: Instance ID 1 assigned to app ID 0x0000000000000001.*"
- "EchoApp::nanoappStart\\(\\)"
- "EchoApp::nanoappHandleEvent\\(sender_instance_id=0, event_type=1, event_data@\\(nil\\)\\)"
- "Event \\(1\\) complete!"
- "EchoApp::nanoappEnd\\(\\)"
- "\\[.*\\] .*<inf> chre: Exiting EventLoop.*"
integration_platforms:
- native_posix
filter: not CONFIG_MINIMAL_LIBC
43 changes: 43 additions & 0 deletions samples/modules/chre/src/echoapp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* Copyright (c) 2021 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

#include <cinttypes>
#include <sys/printk.h>

#include "chre_api/chre/event.h"
#include "chre/core/event_loop_manager.h"
#include "chre/platform/static_nanoapp_init.h"
#include "chre/util/system/napp_permissions.h"

namespace
{
constexpr const uint64_t kAppId = 1;
constexpr const uint32_t kAppVersion = 1;

chre::Nanoapp *nanoapp = nullptr;

bool nanoappStart(void)
{
printk("EchoApp::nanoappStart()\n");
nanoapp = chre::EventLoopManagerSingleton ::get()->getEventLoop().getCurrentNanoapp();
nanoapp->registerForBroadcastEvent(CHRE_EVENT_MESSAGE_FROM_HOST);
return true;
}

void nanoappHandleEvent(uint32_t sender_instance_id, uint16_t event_type, const void *event_data)
{
printk("EchoApp::nanoappHandleEvent(sender_instance_id=%u, event_type=%u, event_data@%p)\n",
sender_instance_id, event_type, event_data);
}

void nanoappEnd()
{
nanoapp->unregisterForBroadcastEvent(0);
nanoapp = nullptr;
printk("EchoApp::nanoappEnd()\n");
}

} /* anonymous namespace */

CHRE_STATIC_NANOAPP_INIT(EchoApp, kAppId, kAppVersion, chre::NanoappPermissions::CHRE_PERMS_NONE);
47 changes: 47 additions & 0 deletions samples/modules/chre/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* Copyright (c) 2021 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr.h>
#include <sys/printk.h>

#include "apps.hpp"
#include "chre/core/event_loop_manager.h"
#include "chre/target_platform/init.h"

inline const char *boolToString(bool cond)
{
return cond ? "SUCCESS" : "FAIL";
}

void main(void)
{
auto echo_app = chre::initializeStaticNanoappEchoApp();
auto& eventLoop = chre::EventLoopManagerSingleton::get()->getEventLoop();
uint32_t instanceId;

if (chre::zephyr::init()) {
printk("Failed to initialize!\n");
return;
}

printk("Hello CHRE!\n");

k_msleep(500);
printk("Starting EchoApp... %s\n", boolToString(eventLoop.startNanoapp(echo_app)));
printk("Nanoapp count=%u\n", eventLoop.getNanoappCount());
printk("Finding instance ID... %s\n", boolToString(eventLoop.findNanoappInstanceIdByAppId(1, &instanceId)));
printk("Nanoapp count=%u\n", eventLoop.getNanoappCount());
printk("Instance ID: %u\n", instanceId);

printk("Sending event %u...\n", eventLoop.getNanoappCount());
eventLoop.postEventOrDie(CHRE_EVENT_MESSAGE_FROM_HOST, nullptr, [](uint16_t eventType, void *eventData) {
printk("Event (%u) complete!\n", eventType);
});

k_sleep(K_MSEC(500));
printk("Ending EchoApp... %s\n",
boolToString(eventLoop.unloadNanoapp(instanceId, false)));
chre::zephyr::deinit();
printk("Goodbye!\n");
}
3 changes: 3 additions & 0 deletions west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ manifest:
- name: canopennode
revision: 53d3415c14d60f8f4bfca54bfbc5d5a667d7e724
path: modules/lib/canopennode
- name: chre
revision: 0edfe2c2ec656afb910cfab8ed59a5ffd59b87c8
path: modules/lib/chre
- name: civetweb
revision: 094aeb41bb93e9199d24d665ee43e9e05d6d7b1c
path: modules/lib/civetweb
Expand Down