1.. _sensing:
2
3Sensing Subsystem
4########################
5
6.. contents::
7    :local:
8    :depth: 2
9
10Overview
11********
12
13Sensing Subsystem is a high level sensor framework inside the OS user
14space service layer. It is a framework focused on sensor fusion, client
15arbitration, sampling, timing, scheduling and sensor based power management.
16
17Key concepts in Sensing Subsystem include physical sensor and virtual sensor objects,
18and a scheduling framework over sensor object relationships.
19Physical sensors do not depend on any other sensor objects for input, and
20will directly interact with existing zephyr sensor device drivers.
21Virtual sensors rely on other sensor objects (physical or virtual) as
22report inputs.
23
24The sensing subsystem relies on Zephyr sensor device APIs (existing version or update in future)
25to leverage Zephyr's large library of sensor device drivers (100+).
26
27Use of the sensing subsystem is optional. Applications that only need to access simple sensors
28devices can use the Zephyr :ref:`sensor` API directly.
29
30Since the sensing subsystem is separated from device driver layer or
31kernel space and could support various customizations and sensor
32algorithms in user space with virtual sensor concepts. The existing
33sensor device driver can focus on low layer device side works, can keep
34simple as much as possible, just provide device HW abstraction and
35operations etc. This is very good for system stability.
36
37The sensing subsystem is decoupled with any sensor expose/transfer
38protocols, the target is to support various up-layer frameworks and
39Applications with different sensor expose/transfer protocols,
40such as `CHRE <https://github.com/zephyrproject-rtos/chre>`_, HID sensors Applications,
41MQTT sensor Applications according different products requirements. Or even support multiple
42Applications with different up-layer sensor protocols at the same time
43with it's multiple clients support design.
44
45Sensing subsystem can help build a unified Zephyr sensing architecture for
46cross host OSes support and as well as IoT sensor solutions.
47
48The diagram below illustrates how the Sensing Subsystem integrates with up-layer frameworks.
49
50.. image:: images/sensing_solution.png
51   :align: center
52   :alt: Unified Zephyr sensing architecture.
53
54Configurability
55***************
56
57* Reusable and configurable standalone subsystem.
58* Based on Zephyr existing low-level Sensor API (reuse 100+ existing sensor device drivers)
59* Provide Zephyr high-level Sensing Subsystem API for Applications.
60* Separate option CHRE Sensor PAL Implementation module to support CHRE.
61* Decoupled with any host link protocols, it's Zephyr Application's role to handle different
62  protocols (MQTT, HID or Private, all configurable)
63
64Main Features
65*************
66
67* Scope
68    * Focus on framework for sensor fusion, multiple clients, arbitration, data sampling, timing
69      management and scheduling.
70
71* Sensor Abstraction
72    * ``Physical sensor``: interacts with Zephyr sensor device drivers, focus on data collecting.
73    * ``Virtual sensor``: relies on other sensor(s), ``physical`` or ``virtual``, focus on
74      data fusion.
75
76* Data Driven Model
77    * ``Polling mode``: periodical sampling rate
78    * ``Interrupt mode``: data ready, threshold interrupt etc.
79
80* Scheduling
81    * single thread main loop for all sensor objects sampling and process.
82
83* Buffer Mode for Batching
84
85* Configurable Via Device Tree
86
87
88Below diagram shows the API position and scope:
89
90.. image:: images/sensing_api_org.png
91   :align: center
92   :alt: Sensing subsystem API organization.
93
94``Sensing Subsystem API`` is for Applications.
95``Sensing Sensor API`` is for development ``sensors``.
96
97
98Major Flows
99***********
100
101* Sensor Configuration Flow
102
103.. image:: images/sensor_config_flow.png
104   :align: center
105   :alt: Sensor Configuration Flow (App set report interval to hinge angel sensor example).
106
107* Sensor Data Flow
108
109.. image:: images/sensor_data_flow.png
110   :align: center
111   :alt: Sensor Data Flow (App receive hinge angel data through data event callback example).
112
113Sensor Types And Instance
114*************************
115
116The ``Sensing Subsystem`` supports multiple instances of the same sensor type,
117there're two methods for Applications to identify and open an unique sensor instance:
118
119* Enumerate all sensor instances
120
121  :c:func:`sensing_get_sensors` returns all current board configuration supported sensor instances'
122  information in a :c:struct:`sensing_sensor_info` pointer array .
123
124  Then Applications can use :c:func:`sensing_open_sensor` to
125  open specific sensor instance for future accessing, configuration and receive sensor data etc.
126
127  This method is suitable for supporting some up-layer frameworks like ``CHRE``, ``HID`` which need
128  to dynamically enumerate the underlying platform's sensor instances.
129
130* Open the sensor instance by devicetree node directly
131
132  Applications can use :c:func:`sensing_open_sensor_by_dt` to open a sensor instance directly with
133  sensor devicetree node identifier.
134
135  For example:
136
137.. code-block:: c
138
139   sensing_open_sensor_by_dt(DEVICE_DT_GET(DT_NODELABEL(base_accel)), cb_list, handle);
140   sensing_open_sensor_by_dt(DEVICE_DT_GET(DT_CHOSEN(zephyr_sensing_base_accel)), cb_list, handle);
141
142This method is useful and easy use for some simple Application which just want to access specific
143sensor(s).
144
145
146``Sensor type`` follows the
147`HID standard sensor types definition <https://usb.org/sites/default/files/hutrr39b_0.pdf>`_.
148
149See :zephyr_file:`include/zephyr/sensing/sensing_sensor_types.h`
150
151Sensor Instance Handler
152***********************
153
154Clients using a :c:type:`sensing_sensor_handle_t` type handler to handle a opened sensor
155instance, and all subsequent operations on this sensor instance need use this handler,
156such as set configurations, read sensor sample data, etc.
157
158For a sensor instance, could have two kinds of clients:
159``Application clients`` and ``Sensor clients``.
160
161``Application clients`` can use :c:func:`sensing_open_sensor` to open a sensor instance
162and get it's handler.
163
164For ``Sensor clients``, there is no open API for opening a reporter, because the client-report
165relationship is built at the sensor's registration stage with devicetree.
166
167The ``Sensing Subsystem`` will auto open and create ``handlers`` for client sensor
168to it's reporter sensors.
169``Sensor clients`` can get it's reporters' handlers via :c:func:`sensing_sensor_get_reporters`.
170
171.. image:: images/sensor_top.png
172   :align: center
173   :alt: Sensor Reporting Topology.
174
175.. note::
176   Sensors inside the Sensing Subsystem, the reporting relationship between them are all auto
177   generated by Sensing Subsystem according devicetree definitions, handlers between client sensor
178   and reporter sensors are auto created.
179   Application(s) need to call :c:func:`sensing_open_sensor` to explicitly open the sensor instance.
180
181Sensor Sample Value
182*******************
183
184* Data Structure
185
186  Each sensor sample value defines as a common ``header`` + ``readings[]`` data structure, like
187  :c:struct:`sensing_sensor_value_3d_q31`, :c:struct:`sensing_sensor_value_q31`, and
188  :c:struct:`sensing_sensor_value_uint32`.
189
190  The ``header`` definition :c:func:`sensing_sensor_value_header`.
191
192
193* Time Stamp
194
195  Time stamp unit in sensing subsystem is ``micro seconds``.
196
197  The ``header`` defines a **base_timestamp**, and
198  each element in the **readings[]** array defines **timestamp_delta**.
199
200  The **timestamp_delta** is in relation to the previous **readings** (or the **base_timestamp**)
201
202  For example:
203
204  * timestamp of ``readings[0]`` is ``header.base_timestamp`` + ``readings[0].timestamp_delta``.
205
206  * timestamp of ``readings[1]`` is ``timestamp of readings[0]`` + ``readings[1].timestamp_delta``.
207
208  Since timestamp unit is micro seconds,
209  the max **timestamp_delta** (``uint32_t``) is ``4295`` seconds.
210
211  If a sensor has batched data where two consecutive readings differ by more than ``4295`` seconds,
212  the sensing subsystem runtime will split them across multiple instances of the readings structure,
213  and send multiple events.
214
215  This concept is referred from `CHRE Sensor API <https://github.com/zephyrproject-rtos/
216  chre/blob/zephyr/chre_api/include/chre_api/chre/sensor_types.h>`_.
217
218* Data Format
219
220  ``Sensing Subsystem`` uses per sensor type defined data format structure,
221  and support ``Q Format`` defined in :zephyr_file:`include/zephyr/dsp/types.h`
222  for ``zdsp`` lib support.
223
224  For example :c:struct:`sensing_sensor_value_3d_q31` can be used by 3D IMU sensors like
225  :c:macro:`SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D`,
226  :c:macro:`SENSING_SENSOR_TYPE_MOTION_UNCALIB_ACCELEROMETER_3D`,
227  and :c:macro:`SENSING_SENSOR_TYPE_MOTION_GYROMETER_3D`.
228
229  :c:struct:`sensing_sensor_value_uint32` can be used by
230  :c:macro:`SENSING_SENSOR_TYPE_LIGHT_AMBIENTLIGHT` sensor,
231
232  and :c:struct:`sensing_sensor_value_q31` can be used by
233  :c:macro:`SENSING_SENSOR_TYPE_MOTION_HINGE_ANGLE` sensor
234
235  See :zephyr_file:`include/zephyr/sensing/sensing_datatypes.h`
236
237
238Device Tree Configuration
239*************************
240
241Sensing subsystem using device tree to configuration all sensor instances and their properties,
242reporting relationships.
243
244See the example :zephyr_file:`samples/subsys/sensing/simple/boards/native_sim.overlay`
245
246API Reference
247*************
248
249.. doxygengroup:: sensing_sensor_types
250.. doxygengroup:: sensing_datatypes
251.. doxygengroup:: sensing_api
252.. doxygengroup:: sensing_sensor
253