CAF: Sensor manager module
The sensor manager module of the Common Application Framework (CAF) generates the following types of events in relation with the sensor defined in the module configuration:
sensor_event
when the sensor is sampled.sensor_state_event
when the sensor state changes.
Configuration
The following Kconfig options are required:
CONFIG_CAF_SENSOR_MANAGER
- This option enables the sensor manager module.CONFIG_SENSOR
- This option enables Zephyr’s Sensors driver, which is required for interacting with the sensors.
The following Kconfig options are also available for the module:
To use the module, you must complete the following requirements:
Physically connect the sensor.
Add and enable the sensor in the devicetree file. For example, in the
BOARD.dts
file. For more information about adding sensor device to devicetree, refer to Use devicetree overlays.Enable the
CONFIG_CAF_SENSOR_MANAGER
andCONFIG_SENSOR
Kconfig options.Enable the sensor of your choice in Kconfig. Each sensor has its own set of Kconfig options.
Add the configuration file that contains an array of
sm_sensor_config
for the sensor that you want to use in your application by completing the following steps:Add a file that defines the following information in an array of
sm_sensor_config
for every sensor that you want to be handled by the sensor manager module:sm_sensor_config.dev_name
- Sensor device name. The name must match the sensor label in theBOARD.dts
file.sm_sensor_config.event_descr
- Sensor event description. The event description is used to identify the sensor in the application.sm_sensor_config.chans
- Channel configuration. This is an array ofcaf_sampled_channel
struct that configures the sensor channel with the following information:caf_sampled_channel.chan
- Sensor channel. Depends on the particular sensor.caf_sampled_channel.data_cnt
- Number of values incaf_sampled_channel.chan
.
sm_sensor_config.chan_cnt
- Size of thesm_sensor_config.chans
array.sm_sensor_config.sampling_period_ms
- Sensor sampling period, in milliseconds.sm_sensor_config.active_events_limit
- Maximum number of unprocessedsensor_event
.
For example, the file content could look like follows:
#include <caf/sensor_manager.h> static const struct caf_sampled_channel accel_chan[] = { { .chan = SENSOR_CHAN_ACCEL_XYZ, .data_cnt = 3, }, }; static const struct sm_sensor_config sensor_configs[] = { { .dev_name = "LIS2DH12-ACCEL", .event_descr = "accel_xyz", .chans = accel_chan, .chan_cnt = ARRAY_SIZE(accel_chan), .sampling_period_ms = 20, .active_events_limit = 3, }, };
Specify the location of the file with the
CONFIG_CAF_SENSOR_MANAGER_DEF_PATH
Kconfig option.
Note
Only the configured module should include the configuration file. Do not include the configuration file in other source files.
Enabling sensor trigger
The sensor manager module supports the sensor trigger functionality. This functionality allows the sensor manager module to stop sampling a specific sensor when specified conditions are met. For more details about the sensor trigger, see Zephyr’s Sensors driver.
Note
Not all sensors support the trigger functionality. For more details, see the sensor-specific Kconfig file.
To use the sensor trigger, complete the following steps:
Enable the sensor trigger option in the sensor-specific Kconfig file. The Kconfig option name is different for each sensor. For example, for the LIS2DH accelerometer, set the
CONFIG_LIS2DH_TRIGGER_GLOBAL_THREAD
option toy
.Extend the module configuration file by adding
sm_sensor_config.trigger
in an array ofsm_sensor_config
.sm_sensor_config.trigger
configures the sensor trigger with the following information:.cfg
information that depends on the particular sensor API:sm_trigger.cfg.type
- Trigger type. The type depends on the particular sensor.sm_trigger.cfg.chan
- Channel on which the trigger is set. The channel depends on the particular sensor.
.activation
information that depends on the sensor manager module:sm_trigger.activation.type
- Sensor value comparison method. See Sensor trigger activation for more details.sm_trigger.activation.thresh
- Sensor trigger activation threshold.sm_trigger.activation.timeout_ms
- Time after which the sensor is put to sleep.
For example, the extended configuration file for the LIS2DH accelerometer could look like follows:
#include <caf/sensor_manager.h> static const struct caf_sampled_channel accel_chan[] = { { .chan = SENSOR_CHAN_ACCEL_XYZ, .data_cnt = 3, }, }; static struct sm_trigger trig = { .cfg = { .type = SENSOR_TRIG_DELTA, .chan = SENSOR_CHAN_ACCEL_XYZ, }, .activation = { .type = ACT_TYPE_ABS, .thresh = 0.5, .timeout_ms = 4000, }, }; static const struct sm_sensor_config sensor_configs[] = { { .dev_name = "LIS2DH12-ACCEL", .event_descr = "accel_xyz", .chans = accel_chan, .chan_cnt = ARRAY_SIZE(accel_chan), .sampling_period_ms = 20, .active_events_limit = 3, .trigger = &trig, }, };
Note
Only the configured module should include the configuration file. Do not include the configuration file in other source files.
Enabling passive power management
The sensor manager module can react to power_down_event
and wake_up_event
.
This functionality is called passive power management and allows the sensor manager module to manage sensors state.
See Passive power management for more information.
The configuration scenario depends on whether you configured and enabled the sensor trigger:
If you enabled the sensor trigger for your sensor, enable the
CONFIG_CAF_SENSOR_MANAGER_PM
Kconfig option to use passive power management.If you did not enable the sensor trigger functionality, you need to manually configure passive power management.
Manually configuring passive power management
To manually configure the passive power management functionality, complete the following steps:
Enable
CONFIG_CAF_SENSOR_MANAGER_PM
Kconfig option.Extend the module configuration file of the sensor of your choice by adding
sm_sensor_config.suspend
in an array ofsm_sensor_config
. For example, the extended configuration file for the LIS2DH accelerometer could look like follows:#include <caf/sensor_manager.h> static const struct sm_sensor_config sensor_configs[] = { { .dev_name = "LIS2DH12-ACCEL", .event_descr = "accel_xyz", .chans = accel_chan, .chan_cnt = ARRAY_SIZE(accel_chan), .sampling_period_ms = 20, .active_events_limit = 3, .suspend = true, }, };
If sm_sensor_config.suspend
is true, the sensor is suspended when power_down_event
is received.
The default value for sm_sensor_config.suspend
is false
.
Note
Not all device power states might be supported by the sensor’s device.
Check the sensor’s driver implementation before configuring sm_sensor_config.suspend
.
Enabling active power management
The sensor manager module can create power_manager_restrict_event
and wake_up_event
.
This functionality is called active power management.
See Active power management for more information.
To use the active power management in the sensor manager module, enable the CONFIG_CAF_SENSOR_MANAGER_ACTIVE_PM
Kconfig option.
Implementation details
The sensor manager module starts in reaction to module_state_event
.
When started, it can do the following operations:
Periodically sample the configured sensors.
Submit
sensor_event
when the sensor channels are sampled.Submit
sensor_state_event
if the sensor state changes.
The sensor manager module samples sensors periodically, according to the configuration specified for each sensor.
Sampling of the sensors is done from a dedicated preemptive thread.
You can change the thread priority by setting the CONFIG_CAF_SENSOR_MANAGER_THREAD_PRIORITY
Kconfig option.
Use the preemptive thread priority to make sure that the thread does not block other operations in the system.
For each sensor, the sensor manager module limits the number of sensor_event
events that it submits, but whose processing has not been completed.
This is done to prevent out-of-memory error if the system workqueue is blocked.
The limit value for the maximum number of unprocessed events for each sensor is placed in the sm_sensor_config.active_events_limit
structure field in the configuration file.
The active_sensor_events_cnt
counter is incremented when sensor_event
is sent and decremented when the event is processed by the sensor manager module that is the final subscriber of the event.
A situation can occur that the active_sensor_events_cnt
counter will already be decremented but the memory allocated by the event would not yet be freed.
Because of this behavior, the maximum number of allocated sensor events for the given sensor is equal to sm_sensor_config.active_events_limit
plus one.
The dedicated thread uses its own thread stack.
You can change the size of the stack by setting the CONFIG_CAF_SENSOR_MANAGER_THREAD_STACK_SIZE
Kconfig option.
The thread stack size must be big enough for the sensors used.
Sensor state events
Each sensor can be in one of the following states:
SENSOR_STATE_DISABLED
- Initial state.SENSOR_STATE_SLEEP
- Sensor sleeps and no sampling is performed. Available if the sensor trigger is configured orCONFIG_CAF_SENSOR_MANAGER_PM
is enabled.SENSOR_STATE_ACTIVE
- Sensor is actively sampling.SENSOR_STATE_ERROR
- Sensor error.
The following figure shows the possible state transitions.
The sensor manager module submits sensor_state_event
whenever the sensor state changes.
Each sensor starts in the SENSOR_STATE_DISABLED
state, which is not reported by the module.
Also, each sensor acts independently to others.
If one of the sensors reports an error, it does not stop the sensor manager module from sampling other sensors.
After the initialization, each sensor changes its state to SENSOR_STATE_ACTIVE
and start periodic sampling.
In case of an error sensor submits sensor_state_event
with the SENSOR_STATE_ERROR
state.
If the trigger functionality or CONFIG_CAF_SENSOR_MANAGER_PM
is enabled the sensor can be put into the SENSOR_STATE_SLEEP
state.
In this state, the sensor is not actively sampling and is not reporting any sensor_event
.
If the sensor trigger fires or the wake_up_event
comes, the sensor state changes to SENSOR_STATE_ACTIVE
and periodic sampling is restarted.
Sensor trigger activation
The sensor trigger is activated and the sensor is put to sleep if the values measured by the sensor do not deviate from the last sensor value by more than sm_trigger.activation.threshold
for the period of time specified in sm_trigger.activation.timeout_ms
.
If the value measured by the sensor does not fit within the threshold, the last sensor value is updated and the sensor continues the sampling process.
The sensor trigger activation type is of the ACT_TYPE_ABS
(Absolute deviation) type.
Passive power management
If the CONFIG_CAF_SENSOR_MANAGER_PM
Kconfig option is enabled, the sensors react to power_down_event
and wake_up_event
.
If a power_down_event
comes when the sensor is in the SENSOR_STATE_ACTIVE
state, the sensor state changes to SENSOR_STATE_SLEEP
and sensor stops sampling.
Depending on the trigger functionality configuration:
If the sensor has the trigger functionality configured, the trigger is activated and the
sm_sensor_config.suspend
is ignored.If no trigger is configured, the sensor is either resumed or suspended depending on the value of
sm_sensor_config.suspend
.
Note
Not all device power states might be supported by the sensor’s device.
Check the sensor’s driver implementation before configuring sm_sensor_config.suspend
.
If a wake_up_event
comes when the sensor is in the SENSOR_STATE_SLEEP
state, the sensor switches to SENSOR_STATE_ACTIVE
and starts actively sampling.
Depending on the trigger functionality configuration:
If the sensor does not support the trigger functionality and
sensor_config.suspend
is true, the sensor device is resumed.If the sensor supports the trigger functionality, the trigger is deactivated.
Active power management
If CONFIG_CAF_SENSOR_MANAGER_ACTIVE_PM
is enabled, the sensor can submit power_manager_restrict_event
and wake_up_event
.
A power_manager_restrict_event
restricts a power level to which the application can be put.
It is submitted every time the allowed state changes.
If there is any sensor that is in the SENSOR_STATE_ACTIVE
state, the module power state is restricted to the POWER_MANAGER_LEVEL_ALIVE
state.
If all the sensors are in the SENSOR_STATE_SLEEP
state and if at least one sensor has trigger activated, the power state is restricted to the POWER_MANAGER_LEVEL_SUSPENDED
state.
Having all the sensors sleeping and none of them with the trigger functionality enabled means that any power state is allowed.
If the sensor’s trigger functionality is configured, each time the trigger is activated wake_up_event
is created and sent to other modules.
Sending wake_up_event
to other modules results in waking up the whole system.
Changing sensor sample period
To change sensor sample period you have to send set_sensor_period_event
with new period value in milliseconds.
To identify which sensor sampling period you want to change, set the sensor description in set_sensor_period_event
.
The following code shows an example of changing accelerometer sampling to 400 ms:
#include <caf/events/sensor_event.h> struct set_sensor_period_event *event = new_set_sensor_period_event(); event->sampling_period = 400; event->descr = "accel_sim_xyz"; APP_EVENT_SUBMIT(event);