Updated: October 28, 2024 |
Use event mode when you want the sensor to asynchronously notify your application when the sensor has data available or status has changed.
You can use custom events to have the Sensor library asynchronously notify you when the sensor has some data or status information available that can be acted upon. Unlike callback mode, the handling of a sensor event is executed in your application's thread. When you register a sigevent with a specific sensor event, the Sensor library will send you this sigevent type when the given sensor event occurs. It's up to your application to receive this event and handle it accordingly within the thread model of your application. Usually, applications implement a separate event loop to listen for sigevents to handle them approprioately.
In general when you're using event mode to access sensor data or status, do the following:
If you're accessing sensor data, the Sensor library can send events to your application for receiving data when the following sensor events occur:
If you're accessing sensor status, the Sensor library can send events to your application for receiving status change when the following sensor events occur:
Some statues may have additional information that's related to the event. For these statuses, the Sensor library specifies the additional information to you in the extra parameter of the callback function.
Ensure that you release any resources that you still have access to before you disable your custom events of type sigvent. Once you disable your events from a specified sensor event, the Sensor library no longer sends your custom event to your application when that sensor event occurs.
Event mode permits you simultaneous access to multiple buffers. However, if you aren't releasing buffers in a timely manner, either the publisher or the subscriber may run out of buffers for processing.
The events that the Sensor library sends to you application are structures of type sigevent. Define sigevents that's most suitable for your application; the sigevents can be of different notification types. See sigevent in the QNX Neutrino RTOS C Library Reference.
A simple sigevent that can be used is a pulse. A pulse is a non-blocking message that can carry a small payload. See _pulse in the QNX Neutrino RTOS C Library Reference. For example, you can define pulse codes for each sensor event that you are registering for:
... #define PULSE_CODE_EVENT_BUFFER _PULSE_CODE_MINAVAIL #define PULSE_CODE_STREAM_DATA (PULSE_CODE_EVENT_BUFFER + 1) #define PULSE_CODE_STREAM_STATUS (PULSE_CODE_EVENT_BUFFER + 2) ...
You need to establish a connection to your application. The Sensor library uses this connection to signal your application to receive an event. For example:
... int chid = -1; chid = ChannelCreate(0); int coid = -1; coid = ConnectAttach(0, 0, chid, _NTO_SIDE_CHANNEL, 0); ...
Now, define the events that the Sensor library notifies your application with when it's time for sending that notification type. If you are registering for more than one notification type, you'll need one event for each notification type. Your application can register up to 16 events for each notification type for any one sensor. For example, you can define events that send pulses:
... struct sigevent buffer_event; struct sigevent stream_data_event; struct sigevent stream_status_event; SIGEV_PULSE_INIT(&buffer_event, coid, SIGEV_PULSE_PRIO_INHERIT, PULSE_CODE_EVENT_BUFFER, 0); SIGEV_PULSE_INIT(&stream_data_event, coid, SIGEV_PULSE_PRIO_INHERIT, PULSE_CODE_STREAM_DATA, 0); SIGEV_PULSE_INIT(&stream_status_event, coid, SIGEV_PULSE_PRIO_INHERIT, PULSE_CODE_STREAM_STATUS, 0); ...
Now, enable your events with the Sensor library by calling sensor_enable_event(). For example:
... sensor_error_t err; sensor_event_key_t keyBuffer, keyStreamData, keyStreamStatus; sensor_handle_t handle = NULL; ... err = sensor_enable_event(handle, SENSOR_EVENT_BUFFER, SENSOR_EVENTMODE_READONLY, &keyBuffer, &buffer_event ); err = sensor_enable_event(handle, SENSOR_EVENT_STREAM_DATA, SENSOR_EVENTMODE_READONLY, &keyStreamData, &stream_data_event ); err = sensor_enable_event(handle, SENSOR_EVENT_STREAM_STATUS, SENSOR_EVENTMODE_READONLY, &keyStreamStatus, &stream_status_event ); ...
The mode parameter of sensor_enable_event() is applicable only when you're enabling an event to receive data.
In your application, you must have an event loop to handle the events that Sensor library sends to you. Call the appropriate functions to access data or status according to the event that you receive. For example:
... int chid; int rcvid; struct _pulse pulse; sensor_error_t err; sensor_handle_t handle = NULL; sensor_buffer_t buffer sensor_devstatus_t devstatus; uint16_t devstatusextra; union sigval sig_value; ... while (1) { rcvid = MsgReceivePulse(chid, &pulse, sizeof(pulse), NULL); ... switch (pulse.code) { case PULSE_CODE_EVENT_BUFFER: ... printf("Received a SENSOR_EVENT_BUFFER event\n"); err = sensor_get_buffer(handle, keyBuffer, &buffer); ... err = sensor_return_buffer(handle, &buffer); ... case PULSE_CODE_STREAM_DATA: ... printf("Received a SENSOR_EVENT_STREAM_DATA event\n"); err = sensor_get_buffer(handle, keyStreamData, &buffer); ... err = sensor_return_buffer(handle, &buffer); ... case PULSE_CODE_STREAM_STATUS: ... printf("Received a SENSOR_EVENT_STREAM_STATUS event\n"); ... err = sensor_get_status_details(handle, value, &devstatus, &devstatusextra); ... } ...
When you no longer need signals for specific sensor events, disable them from being sent from the Sensor library by calling sensor_disable_event(). For example:
... sensor_error_t err; sensor_event_key_t keyBuffer, keyStreamData, keyStreamStatus; sensor_handle_t handle = NULL; ... err = sensor_disable_event(handle, &keyBuffer,); err = sensor_disable_event(handle, &keyStreamData); err = sensor_disable_event(handle, &keyStreamStatus); ...
Ensure that you release any resources that you still have access to before you disable your events. Once you disable your events from a specified sensor event, the Sensor library no longer invokes triggers your events when that sensor event occurs.