| Event Queues |
| ============ |
| |
| An event queue allows a task to serialize incoming events and simplify |
| event processing. Events are stored in a queue and a task removes and |
| processes an event from the queue. An event is processed in the context |
| of this task. Events may be generated by OS callouts, interrupt handlers, |
| and other tasks. |
| |
| Description |
| --------------- |
| |
| Mynewt's event queue model uses callback functions to process events. |
| Each event is associated with a callback function that is called to |
| process the event. This model enables a library package, that uses |
| events in its implementation but does not have real-time timing |
| requirements, to use an application event queue instead of creating a |
| dedicated event queue and task to process its events. The callback |
| function executes in the context of the task that the application |
| creates to manage the event queue. This model reduces an application's |
| memory requirement because memory must be allocated for the task's stack |
| when a task is created. A package that has real-time timing requirements |
| and must run at a specific task priority should create a dedicated event |
| queue and task to process its events. |
| |
| In the Mynewt model, a package defines its events and implements the |
| callback functions for the events. A package that does not have |
| real-time timing requirements should use Mynewt's default event queue |
| for its events. The callback function for an event from the Mynewt |
| default event queue is executed in the context of the application main |
| task. A package can, optionally, export a function that allows an |
| application to specify the event queue for the package to use. The |
| application task handler that manages the event queue simply pulls events |
| from the event queue and executes the event's callback function in its context. |
| |
| A common way that Mynewt applications or packages process events from an |
| event queue is to have a task that executes in an infinite loop and |
| calls the :c:func:`os_eventq_get()` function to dequeue and return the event |
| from the head of the event queue. The task then calls the event callback |
| function to process the event. The :c:func:`os_eventq_get()` function puts the |
| task in to the ``sleeping`` state when there are no events on the queue. |
| (See :doc:`../context_switch/context_switch` for more |
| information on task execution states.) Other tasks (or interrupts) call |
| the :c:func:`os_eventq_put()` function to add an event to the queue. The |
| :c:func:`os_eventq_put()` function determines whether a task is blocked |
| waiting for an event on the queue and puts the task into the |
| ``ready-to-run`` state. |
| |
| A task can use the :c:func:`os_eventq_run()` wrapper function that calls the |
| :c:func:`os_eventq_get()` function to dequeue an event from the queue and then |
| calls the event callback function to process the event. |
| Note: |
| |
| - Only one task should consume or block waiting for events from an |
| event queue. |
| - The OS callout subsystem uses events for timer expiration notification. |
| |
| Example |
| ------- |
| |
| Here is an example of using an event from the BLE host: |
| |
| .. code:: c |
| |
| static void ble_hs_event_tx_notify(struct os_event *ev); |
| |
| /** OS event - triggers tx of pending notifications and indications. */ |
| static struct os_event ble_hs_ev_tx_notifications = { |
| .ev_cb = ble_hs_event_tx_notify, |
| }; |
| |
| |
| API |
| ---- |
| |
| .. doxygengroup:: OSEvent |
| :members: |
| :content-only: |