“Batching” refers to storing sensor events in a hardware FIFO before reporting them through the HAL instead of reporting them immediately.
Batching can enable significant power savings by preventing the SoC from waking up to receive each event. Instead, the events can be grouped and processed together.
The bigger the FIFOs, the more power can be saved. Implementing batching is an exercise of trading off hardware memory for reduced power consumption.
Batching happens when a sensor possesses a hardware FIFO
(sensor_t.fifoMaxEventCount > 0
) and we are in one of two situations:
max_report_latency > 0
, meaning the sensor events for this specific sensor can
be delayed up to max_report_latency
before being reported through the HAL. See the paragraph on the HAL batch function for more details.
The opposite of batching is the continuous operation, where events are not buffered, meaning they are reported immediately. Continuous operation corresponds to:
max_report_latency = 0
and the events can be delivered to the application,
meaning
sensor_t.fifoMaxEventCount =
0
), in which case
Sensor events from wake-up sensors must be stored into a wake-up FIFO. There can be one wake-up FIFO per sensor, or, more commonly, one big shared wake-up FIFO where events from all wake-up sensors are interleaved. Other options are also possible, with for example some wake-up sensors having a dedicated FIFO, and the rest of the wake-up sensors all sharing the same one.
Similarly, sensor events from non-wake-up sensors must be stored into a non-wake-up FIFOs, and there can be one or several non-wake-up FIFOs.
In all cases, wake-up sensor events and non-wake-up sensor events cannot be interleaved into the same FIFO. Wake-up events go in wake-up FIFOs, and non-wake-up events go in non-wake-up FIFOs.
For the wake-up FIFO, the “one big shared FIFO” design provides the best power benefits. For the non-wake-up FIFO, there is no preference between the “one big shared FIFO” and “several small reserved FIFOs”. See FIFO allocation priority for suggestions on how to dimension each FIFO.
When the SoC is awake (not in suspend mode), the events can be stored
temporarily in their FIFO, as long as they are not delayed by more than
max_report_latency
.
As long as the SoC doesn’t enter the suspend mode, no event shall be dropped or
lost. If internal hardware FIFOs is getting full before max_report_latency
elapsed, then events are reported at that point to ensure that no event is
lost.
If several sensors share the same FIFO and the max_report_latency
of one of
them elapses, all events from the FIFO are reported, even if the
max_report_latency
of the other sensors didn’t elapse yet. The general goal is
to reduce the number of times batches of events must be reported, so as soon as
one event must be reported, all events from all sensors can be reported.
For example, if the following sensors are activated:
max_report_latency
= 20s max_report_latency
= 5s Then the accelerometer batches can be reported at the same time the gyroscope batches are reported (every 5 seconds), even if the accelerometer and the gyroscope do not share the same FIFO.
Batching is particularly beneficial when wanting to collect sensor data in the background without keeping the SoC awake. Because the sensor drivers and HAL implementation are not allowed to hold a wake-lock*, the SoC can enter the suspend mode even while sensor data is being collected.
The behavior of sensors while the SoC is suspended depends on whether the sensor is a wake-up sensor. See Wake-up sensors for some details.
When a non-wake-up FIFO fills up, it must wrap around and behave like a
circular buffer, overwriting older events: the new events replace the old ones.
max_report_latency
has no impact on non-wake-up FIFOs while in suspend mode.
When a wake-up FIFO fills up, or when the max_report_latency
of one of the
wake-up sensor elapsed, the hardware must wake up the SoC and report the data.
In both cases (wake-up and non-wake-up), as soon as the SoC comes out of
suspend mode, a batch is produced with the content of all FIFOs, even if
max_report_latency
of some sensors didn’t elapse yet. This minimizes the risk
of having to wake-up the SoC again soon if it goes back to suspend. Hence, it
minimizes power consumption.
*One notable exception of drivers not being allowed to hold a wake lock is when
a wake-up sensor with continuous
reporting mode is activated with max_report_latency
< 1
second. In that case, the driver can hold a wake lock because the SoC would
anyway not have the time to enter the suspend mode, as it would be awoken by
a wake-up event before reaching the suspend mode.
Depending on the device, it might take a few milliseconds for the SoC to
entirely come out of suspend and start flushing the FIFO. Enough head room must
be allocated in the FIFO to allow the device to entirely come out of suspend
without the wake-up FIFO overflowing. No events shall be lost, and the
max_report_latency
must be respected.
On-change sensors only generate events when the value they are measuring is changing. If the measured value changes while the SoC is in suspend mode, applications expect to receive an event as soon as the SoC wakes up. Because of this, batching of non-wake-up on-change sensor events must be performed carefully if the sensor shares its FIFO with other sensors. The last event generated by each on-change sensor must always be saved outside of the shared FIFO so it can never be overwritten by other events. When the SoC wakes up, after all events from the FIFO have been reported, the last on-change sensor event must be reported.
Here is a situation we want to avoid:
By saving the last step counter event outside of the FIFO, the HAL can report this event when the SoC wakes up, even if all other step counter events were overwritten by accelerometer events. This way, the application receives “step_count = 1020 steps” when the SoC wakes up.
Batching cannot be emulated in software. It must be implemented entirely in hardware, with hardware FIFOs. In particular, it cannot be implemented on the SoC, for example in the HAL implementation, as this would be counter-productive. The goal here is to save significant amounts of power. Batching must be implemented without the aid of the SoC, which should be allowed to be in suspend mode during batching.
max_report_latency
can be modified at any time, in particular while the
specified sensor is already enabled; and this shall not result in the loss of
events.
On platforms in which hardware FIFO size is limited, the system designers may have to choose how much FIFO to reserve for each sensor. To help with this choice, here is a list of applications made possible when batching is implemented on the different sensors.
Target batching time: 1 to 10 minutes
Sensors to batch:
Batching this data allows performing pedestrian dead reckoning while letting the SoC go to suspend.
Target batching time: 3 seconds
Sensors to batch: Non-wake-up Accelerometer at 50Hz
Batching this data allows periodically recognizing arbitrary activities and gestures without having to keep the SoC awake while the data is collected.
Target batching time: 1 to 3 minutes
Sensors to batch: Wake-up Accelerometer at 50Hz
Batching this data allows continuously recognizing arbitrary activities and gestures without having to keep the SoC awake while the data is collected.
Target batching time: < 1 second
Sensors to batch: any high frequency sensor, usually non-wake-up.
If the gyroscope is set at 240Hz, even batching just 10 gyro events can reduce the number of interrupts from 240/second to 24/second.
Target batching time: 1 to 10 minutes
Sensors to batch:
Allows creating monitoring applications at low power.
Target batching time: 1 to 10 minutes
Sensors to batch: all wake-up sensors, at high frequencies
Allows full collection of sensor data while leaving the SoC in suspend mode. Only to consider if FIFO space is not an issue.