doc: events: Add events documention
Adds documentation for event objects. Events are posted to event objects. Threads may wait on an event object for a specified set of events. Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
This commit is contained in:
parent
10637afc00
commit
3ff549d1a2
2 changed files with 173 additions and 0 deletions
|
@ -40,6 +40,7 @@ synchronization.
|
||||||
synchronization/semaphores.rst
|
synchronization/semaphores.rst
|
||||||
synchronization/mutexes.rst
|
synchronization/mutexes.rst
|
||||||
synchronization/condvar.rst
|
synchronization/condvar.rst
|
||||||
|
synchronization/events.rst
|
||||||
smp/smp.rst
|
smp/smp.rst
|
||||||
|
|
||||||
.. _kernel_data_passing_api:
|
.. _kernel_data_passing_api:
|
||||||
|
|
172
doc/reference/kernel/synchronization/events.rst
Normal file
172
doc/reference/kernel/synchronization/events.rst
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
.. _events:
|
||||||
|
|
||||||
|
Events
|
||||||
|
######
|
||||||
|
|
||||||
|
An :dfn:`event object` is a kernel object that implements traditional events.
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
:depth: 2
|
||||||
|
|
||||||
|
Concepts
|
||||||
|
********
|
||||||
|
|
||||||
|
Any number of event objects can be defined (limited only by available RAM). Each
|
||||||
|
event object is referenced by its memory address. One or more threads may wait
|
||||||
|
on an event object until the desired set of events has been delivered to the
|
||||||
|
event object. When new events are delivered to the event object, all threads
|
||||||
|
whose wait conditions have been satisfied become ready simultaneously.
|
||||||
|
|
||||||
|
An event object has the following key properties:
|
||||||
|
|
||||||
|
* A 32-bit value that tracks which events have been delivered to it.
|
||||||
|
|
||||||
|
An event object must be initialized before it can be used.
|
||||||
|
|
||||||
|
Events may be **delivered** by a thread or an ISR. When delivering events, the
|
||||||
|
events may either overwrite the existing set of events or add to them in
|
||||||
|
a bitwise fashion. When overwriting the existing set of events, this is referred
|
||||||
|
to as setting. When adding to them in a bitwise fashion, this is referred to as
|
||||||
|
posting. Both posting and setting events have the potential to fulfill match
|
||||||
|
conditions of multiple threads waiting on the event object. All threads whose
|
||||||
|
match conditions have been met are made active at the same time.
|
||||||
|
|
||||||
|
Threads may wait on one or more events. They may either wait for all of the
|
||||||
|
the requested events, or for any of them. Furthermore, threads making a wait
|
||||||
|
request have the option of resetting the current set of events tracked by the
|
||||||
|
event object prior to waiting. Care must be taken with this option when
|
||||||
|
multiple threads wait on the same event object.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
The kernel does allow an ISR to query an event object, however the ISR must
|
||||||
|
not attempt to wait for the events.
|
||||||
|
|
||||||
|
Implementation
|
||||||
|
**************
|
||||||
|
|
||||||
|
Defining an Event Object
|
||||||
|
========================
|
||||||
|
|
||||||
|
An event object is defined using a variable of type :c:struct:`k_event`.
|
||||||
|
It must then be initialized by calling :c:func:`k_event_init`.
|
||||||
|
|
||||||
|
The following code defines an event object.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
struct k_event my_event;
|
||||||
|
|
||||||
|
k_event_init(&my_event);
|
||||||
|
|
||||||
|
Alternatively, an event object can be defined and initialized at compile time
|
||||||
|
by calling :c:macro:`K_EVENT_DEFINE`.
|
||||||
|
|
||||||
|
The following code has the same effect as the code segment above.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
K_EVENT_DEFINE(my_event, 0, 1);
|
||||||
|
|
||||||
|
Setting Events
|
||||||
|
==============
|
||||||
|
|
||||||
|
Events in an event object are set by calling :c:func:`k_event_set`.
|
||||||
|
|
||||||
|
The following code builds on the example above, and sets the events tracked by
|
||||||
|
the event object to 0x001.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
void input_available_interrupt_handler(void *arg)
|
||||||
|
{
|
||||||
|
/* notify threads that data is available */
|
||||||
|
|
||||||
|
k_event_set(&my_event, 0x001);
|
||||||
|
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
Posting Events
|
||||||
|
==============
|
||||||
|
|
||||||
|
Events are posted to an event object by calling :c:func:`k_event_post`.
|
||||||
|
|
||||||
|
The following code builds on the example above, and posts a set of events to
|
||||||
|
the event object.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
void input_available_interrupt_handler(void *arg)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
|
||||||
|
/* notify threads that more data is available */
|
||||||
|
|
||||||
|
k_event_post(&my_event, 0x120);
|
||||||
|
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
Waiting for Events
|
||||||
|
==================
|
||||||
|
|
||||||
|
Threads wait for events by calling :c:func:`k_event_wait`.
|
||||||
|
|
||||||
|
The following code builds on the example above, and waits up to 50 milliseconds
|
||||||
|
for any of the specified events to be posted. A warning is issued if none
|
||||||
|
of the events are posted in time.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
void consumer_thread(void)
|
||||||
|
{
|
||||||
|
uint32_t events;
|
||||||
|
|
||||||
|
events = k_event_wait(&my_event, 0xFFF, false, K_MSEC(50));
|
||||||
|
if (events == 0) {
|
||||||
|
printk("No input devices are available!");
|
||||||
|
} else {
|
||||||
|
/* Access the desired input device(s) */
|
||||||
|
...
|
||||||
|
}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
Alternatively, the consumer thread may desire to wait for all the events
|
||||||
|
before continuing.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
void consumer_thread(void)
|
||||||
|
{
|
||||||
|
uint32_t events;
|
||||||
|
|
||||||
|
events = k_event_wait_all(&my_event, 0x121, false, K_MSEC(50));
|
||||||
|
if (events == 0) {
|
||||||
|
printk("At least one input device is not available!");
|
||||||
|
} else {
|
||||||
|
/* Access the desired input devices */
|
||||||
|
...
|
||||||
|
}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
Suggested Uses
|
||||||
|
**************
|
||||||
|
|
||||||
|
Use events to indicate that a set of conditions have occurred.
|
||||||
|
|
||||||
|
Use events to pass small amounts of data to multiple threads at once.
|
||||||
|
|
||||||
|
Configuration Options
|
||||||
|
*********************
|
||||||
|
|
||||||
|
Related configuration options:
|
||||||
|
|
||||||
|
* :kconfig:`CONFIG_EVENTS`
|
||||||
|
|
||||||
|
API Reference
|
||||||
|
**************
|
||||||
|
|
||||||
|
.. doxygengroup:: event_apis
|
Loading…
Add table
Add a link
Reference in a new issue