173 lines
4.5 KiB
ReStructuredText
173 lines
4.5 KiB
ReStructuredText
.. _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);
|
|
|
|
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:option:`CONFIG_EVENTS`
|
|
|
|
API Reference
|
|
**************
|
|
|
|
.. doxygengroup:: event_apis
|