Skip to content
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

Sensing Subsystem Upstream PR1 #55389

Merged
merged 8 commits into from Jun 17, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Expand Up @@ -210,6 +210,7 @@
/doc/develop/tools/coccinelle.rst @himanshujha199640 @JuliaLawall
/doc/services/device_mgmt/smp_protocol.rst @de-nordic @nordicjm
/doc/services/device_mgmt/smp_groups/ @de-nordic @nordicjm
/doc/services/sensing/ @lixuzha @ghu0510 @qianruh
/doc/CMakeLists.txt @carlescufi
/doc/_scripts/ @carlescufi
/doc/connectivity/bluetooth/ @alwa-nordic @jhedberg @Vudentz
Expand Down Expand Up @@ -575,6 +576,8 @@
/dts/bindings/sensor/*bme680* @BoschSensortec
/dts/bindings/sensor/*ina23* @bbilas
/dts/bindings/sensor/st* @avisconti
/dts/bindings/sensor/zephyr,sensing.yaml @lixuzha @ghu0510 @qianruh
/dts/bindings/sensor/zephyr,sensing*.yaml @lixuzha @ghu0510 @qianruh
/dts/bindings/smbus/ @finikorg
/dts/bindings/sip_svc/ @maheshraotm
/dts/bindings/cpu/intel,niosv.yaml @sweeaun
Expand Down Expand Up @@ -671,6 +674,7 @@
/include/zephyr/pm/pm.h @nashif @ceolin
/include/zephyr/drivers/ptp_clock.h @tbursztyka
/include/zephyr/rtio/ @teburd
/include/zephyr/sensing/ @lixuzha @ghu0510 @qianruh
/include/zephyr/shared_irq.h @dcpleung @nashif @andyross
/include/zephyr/shell/ @jakub-uC @nordic-krch
/include/zephyr/shell/shell_mqtt.h @ycsin
Expand All @@ -694,6 +698,7 @@
/lib/posix/ @cfriedt
/lib/posix/getopt/ @jakub-uC
/subsys/portability/ @nashif
/subsys/sensing/ @lixuzha @ghu0510 @qianruh
/lib/libc/ @nashif
/lib/libc/arcmwdt/ @abrodkin @ruuddw @evgeniy-paltsev
/misc/ @tejlmand
Expand Down Expand Up @@ -740,6 +745,7 @@
/samples/subsys/usb/ @jfischer-no
/samples/subsys/usb_c/ @sambhurst
/samples/subsys/pm/ @nashif @ceolin
/samples/subsys/sensing/ @lixuzha @ghu0510 @qianruh
/samples/tfm_integration/ @microbuilder
/samples/userspace/ @dcpleung @nashif
/scripts/release/bug_bash.py @cfriedt
Expand Down
18 changes: 18 additions & 0 deletions MAINTAINERS.yml
Expand Up @@ -2002,6 +2002,24 @@ Retention:
labels:
- "area: Retention"

Sensor Subsystem:
status: maintained
maintainers:
yperess marked this conversation as resolved.
Show resolved Hide resolved
- lixuzha
- ghu0510
- yperess
collaborators:
- qianruh
files:
- dts/bindings/sensor/zephyr,sensing.yaml
- dts/bindings/sensor/zephyr,sensing*.yaml
- include/zephyr/sensing/
- doc/services/sensing/
- subsys/sensing/
- samples/subsys/sensing/
labels:
- "area: Sensor Subsystem"

Twister:
status: maintained
maintainers:
Expand Down
4 changes: 4 additions & 0 deletions cmake/linker_script/common/common-ram.cmake
Expand Up @@ -54,6 +54,10 @@ if(CONFIG_NETWORKING)
zephyr_iterable_section(NAME eth_bridge GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4)
endif()

if(CONFIG_SENSING)
zephyr_iterable_section(NAME sensing_sensor GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4)
endif()

if(CONFIG_UART_MUX)
zephyr_iterable_section(NAME uart_mux GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4)
endif()
Expand Down
4 changes: 4 additions & 0 deletions cmake/linker_script/common/common-rom.cmake
Expand Up @@ -136,6 +136,10 @@ if(CONFIG_SETTINGS)
zephyr_iterable_section(NAME settings_handler_static KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4)
endif()

if(CONFIG_SENSING)
zephyr_iterable_section(NAME sensing_sensor_info KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4)
endif()

if(CONFIG_SENSOR_INFO)
zephyr_iterable_section(NAME sensor_info KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4)
endif()
Expand Down
1 change: 1 addition & 0 deletions doc/services/index.rst
Expand Up @@ -26,6 +26,7 @@ OS Services
settings/index.rst
smf/index.rst
storage/index.rst
sensing/index.rst
task_wdt/index.rst
tfm/index
usb/index.rst
Expand Down
Binary file added doc/services/sensing/images/sensing_api_org.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/services/sensing/images/sensor_top.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
274 changes: 274 additions & 0 deletions doc/services/sensing/index.rst
keith-zephyr marked this conversation as resolved.
Show resolved Hide resolved
@@ -0,0 +1,274 @@
.. _sensing_api:

Sensing Subsystem
########################

.. contents::
:local:
:depth: 2

Overview
********

Sensing Subsystem is a high level sensor framework inside the OS user
space service layer. It is a framework focused on sensor fusion, client
arbitration, sampling, timing, scheduling and sensor based power management.

Key concepts in Sensing Subsystem include physical sensor and virtual sensor objects,
and a scheduling framework over sensor object relationships.
Physical sensors do not depend on any other sensor objects for input, and
will directly interact with existing zephyr sensor device drivers.
Virtual sensors rely on other sensor objects (physical or virtual) as
report inputs.

The sensing subsystem relies on Zephyr sensor device APIs (existing version or update in future)
to leverage Zephyr's large library of sensor device drivers (100+).

Use of the sensing subsystem is optional. Applications that only need to access simple sensors
devices can use the Zephyr :ref:`sensor_api` API directly.

Since the sensing subsystem is separated from device driver layer or
kernel space and could support various customizations and sensor
algorithms in user space with virtual sensor concepts. The existing
sensor device driver can focus on low layer device side works, can keep
simple as much as possible, just provide device HW abstraction and
operations etc. This is very good for system stability.

The sensing subsystem is decoupled with any sensor expose/transfer
protocols, the target is to support various up-layer frameworks and
Applications with different sensor expose/transfer protocols,
such as `CHRE <https://github.com/zephyrproject-rtos/chre>`_, HID sensors Applications,
MQTT sensor Applications according different products requirements. Or even support multiple
Applications with different up-layer sensor protocols at the same time
with it's multiple clients support design.

Sensing subsystem can help build a unified Zephyr sensing architecture for
cross host OSes support and as well as IoT sensor solutions.

The diagram below illustrates how the Sensing Subsystem integrates with up-layer frameworks.

.. image:: images/sensing_solution.png
:align: center
:alt: Unified Zephyr sensing architecture.

Configurability
===============

* Reusable and configurable standalone subsystem.
* Based on Zephyr existing low-level Sensor API (reuse 100+ existing sensor device drivers)
* Provide Zephyr high-level Sensing Subsystem API for Applications.
* Separate option CHRE Sensor PAL Implementation module to support CHRE.
* Decoupled with any host link protocols, it's Zephyr Application's role to handle different
protocols (MQTT, HID or Private, all configurable)

Main Features
=============

* Scope
* Focus on framework for sensor fusion, multiple clients, arbitration, data sampling, timing
management and scheduling.

* Sensor Abstraction
* ``Physical sensor``: interacts with Zephyr sensor device drivers, focus on data collecting.
* ``Virtual sensor``: relies on other sensor(s), ``physical`` or ``virtual``, focus on
data fusion.

* Data Driven Model
* ``Polling mode``: periodical sampling rate
* ``Interrupt mode``: data ready, threshold interrupt etc.

* Scheduling
* single thread main loop for all sensor objects sampling and process.

* Buffer Mode for Batching

* Configurable Via Device Tree

API Design
**********

API Organization
================

* Sensing Subsystem
* Sensor Types

.. doxygengroup:: sensing_sensor_types

* Data Types

.. doxygengroup:: sensing_datatypes

* Sensing Subsystem API

.. doxygengroup:: sensing_api

* Sensing Sensor API

.. doxygengroup:: sensing_sensor

Below diagram shows the API position and scope:

.. image:: images/sensing_api_org.png
:align: center
:alt: Sensing subsystem API organization.

``Sensing Subsystem API`` is for Applications.
``Sensing Sensor API`` is for development ``sensors``.


Major Flows
=========================

* Sensor Configuration Flow

.. image:: images/sensor_config_flow.png
:align: center
:alt: Sensor Configuration Flow (App set report interval to hinge angel sensor example).

* Sensor Data Flow

.. image:: images/sensor_data_flow.png
:align: center
:alt: Sensor Data Flow (App receive hinge angel data through data event callback example).

Sensor Types And Instance
=========================

The ``Sensing Subsystem`` supports multiple instances of the same sensor type,
there're two methods for Applications to identify and open an unique sensor instance:

* Enumerate all sensor instances

:c:func:`sensing_get_sensors` returns all current board configuration supported sensor instances'
information in a :c:struct:`sensing_sensor_info` pointer array .

Then Applications can use :c:func:`sensing_open_sensor` to
open specific sensor instance for future accessing, configuration and receive sensor data etc.

This method is suitable for supporting some up-layer frameworks like ``CHRE``, ``HID`` which need
to dynamically enumerate the underlying platform's sensor instances.

* Open the sensor instance by devicetree node directly

Applications can use :c:func:`sensing_open_sensor_by_dt` to open a sensor instance directly with
sensor devicetree node identifier.

For example:

.. code-block:: c

sensing_open_sensor_by_dt(DEVICE_DT_GET(DT_NODELABLE(base_accel)), cb_list, handle);
sensing_open_sensor_by_dt(DEVICE_DT_GET(DT_CHOSEN(zephyr_sensing_base_accel)), cb_list, handle);

This method is useful and easy use for some simple Application which just want to access specific
sensor(s).


``Sensor type`` follows the
`HID standard sensor types definition <https://usb.org/sites/default/files/hutrr39b_0.pdf>`_.

See :zephyr_file:`include/zephyr/sensing/sensing_sensor_types.h`

Sensor Instance Handler
=========================

Clients using a :c:type:`sensing_sensor_handle_t` type handler to handle a opened sensor
instance, and all subsequent operations on this sensor instance need use this handler,
such as set configurations, read sensor sample data, etc.

For a sensor instance, could have two kinds of clients:
``Application clients`` and ``Sensor clients``.

``Application clients`` can use :c:func:`sensing_open_sensor` to open a sensor instance
and get it's handler.

For ``Sensor clients``, there is no open API for opening a reporter, because the client-report
relationship is built at the sensor's registration stage with devicetree.

The ``Sensing Subsystem`` will auto open and create ``handlers`` for client sensor
to it's reporter sensors.
``Sensor clients`` can get it's reporters' handlers via :c:func:`sensing_sensor_get_reporters`.

.. image:: images/sensor_top.png
:align: center
:alt: Sensor Reporting Topology.

.. note::
Sensors inside the Sensing Subsystem, the reporting relationship between them are all auto
generated by Sensing Subsystem according devicetree definitions, handlers between client sensor
and reporter sensors are auto created.
Application(s) need to call :c:func:`sensing_open_sensor` to explicitly open the sensor instance.

Sensor Sample Value
==================================

* Data Structure

Each sensor sample value defines as a common ``header`` + ``readings[]`` data structure, like
:c:struct:`sensing_sensor_value_3d_q31`, :c:struct:`sensing_sensor_value_q31`, and
:c:struct:`sensing_sensor_value_uint32`.

The ``header`` definition :c:func:`sensing_sensor_value_header`.


* Time Stamp

Time stamp unit in sensing subsystem is ``micro seconds``.

The ``header`` defines a **base_timestamp**, and
each element in the **readings[]** array defines **timestamp_delta**.

The **timestamp_delta** is is in relation to the previous **readings** (or the **base_timestamp**)

For example:

* timestamp of ``readings[0]`` is ``header.base_timestamp`` + ``readings[0].timestamp_delta``.

* timestamp of ``readings[1]`` is ``timestamp of readings[0]`` + ``readings[1].timestamp_delta``.

Since timestamp unit is micro seconds,
the max **timestamp_delta** (``uint32_t``) is ``4295`` seconds.

If a sensor has batched data where two consecutive readings differ by more than ``4295`` seconds,
the sensing subsystem runtime will split them across multiple instances of the readings structure,
and send multiple events.

This concept is referred from `CHRE Sensor API <https://github.com/zephyrproject-rtos/
chre/blob/zephyr/chre_api/include/chre_api/chre/sensor_types.h>`_.

* Data Format

``Sensing Subsystem`` uses per sensor type defined data format structure,
and support ``Q Format`` defined in :zephyr_file:`include/zephyr/dsp/types.h`
for ``zdsp`` lib support.

For example :c:struct:`sensing_sensor_value_3d_q31` can be used by 3D IMU sensors like
:c:macro:`SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D`,
:c:macro:`SENSING_SENSOR_TYPE_MOTION_UNCALIB_ACCELEROMETER_3D`,
and :c:macro:`SENSING_SENSOR_TYPE_MOTION_GYROMETER_3D`.

:c:struct:`sensing_sensor_value_uint32` can be used by
:c:macro:`SENSING_SENSOR_TYPE_LIGHT_AMBIENTLIGHT` sensor,

and :c:struct:`sensing_sensor_value_q31` can be used by
:c:macro:`SENSING_SENSOR_TYPE_MOTION_HINGE_ANGLE` sensor

See :zephyr_file:`include/zephyr/sensing/sensing_datatypes.h`


Device Tree Configuration
*************************

Sensing subsystem using device tree to configuration all sensor instances and their properties,
reporting relationships.

See the example :zephyr_file:`samples/subsys/sensing/simple/boards/native_posix.overlay`

API Reference
*************

Sensing
========

.. doxygengroup:: sensing
13 changes: 13 additions & 0 deletions dts/bindings/sensor/zephyr,sensing-phy-sensor.yaml
@@ -0,0 +1,13 @@
# Copyright (c) 2023, Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#

description: Sensing subsystem physical sensor properties bindings.

include: zephyr,sensing-sensor.yaml

properties:
underlying-device:
type: phandle
required: true
description: underlying sensor device for physical sensor