zephyr/doc/kernel/microkernel/microkernel_events.rst
Rodrigo Caballero 4d8b60adca Doc: Change the Microkernel Objects to the Microkernel Services section.
Moves the Microkernel Object documentation to a new Microkernel Services
section within the Kernel Primer. Labels, cross-references, figures,
headings and filenames were updated to reflect the new structure. 

Change-Id: Ia2a91410a94caa8a97bb8211db5afc84b5dc0974
Signed-off-by: Rodrigo Caballero <rodrigo.caballero.abraham@intel.com>
2016-02-05 20:15:19 -05:00

176 lines
5.5 KiB
ReStructuredText

.. _microkernel_events:
Events
######
Definition
**********
Event objects are microkernel synchronization objects that tasks can
signal and test. Fibers and interrupt service routines may signal
events but they cannot test or wait on them. Use event objects for
situations in which multiple signals come in but only one test is
needed to reset the event. Events do not count signals like a semaphore
does due to their binary behavior. An event needs only one signal to be
available and only needs to be tested once to become clear and
unavailable.
Function
********
Events were designed for interrupt service routines and nanokernel
fibers that need to wake up a waiting task. The event signal can be
passed to a task to trigger an event test to RC_OK. Events are the
easiest and most efficient way to wake up a task to synchronize
operations between the two levels.
A feature of events are the event handlers. Event handlers are attached
to events. They perform simple processing in the nanokernel before a
context switch is made to a blocked task. This way, signals can be
interpreted before the system requires to reschedule a fiber or task.
Only one task may wait for an event. If a second task tests the same
event the call returns a fail. Use semaphores for multiple tasks to
wait on a signal from them.
Usage
*****
Defining an Event
=================
The following parameters must be defined:
*name*
This specifies a unique name for the event.
*handler*
This specifies the name of the event handler function to be executed
each time the event is signalled. If no event handler is required
specify NULL.
Add an entry for the event in the project .MDEF file using the
following syntax:
.. code-block:: console
EVENT %name %handler
For example, the file :file:`projName.mdef` defines two events
as follows:
.. code-block:: console
% EVENT NAME ENTRY
% ==========================================
EVENT KEYPRESS validate_keypress
EVENT BUTTONPRESS NULL
Example: Signaling an Event from an ISR
========================================
This code signals an event during the processing of an interrupt.
.. code-block:: c
void keypress_interrupt_handler(void *arg)
{
...
isr_event_signal(KEYPRESS);
...
}
Example: Consuming an Event using a Task
========================================
This code processes events of a single type using a task.
.. code-block:: c
void keypress_task(void)
{
/* consume key presses */
while (1) {
/* wait for a key press to be signalled */
task_event_recv(KEYPRESS);
/* determine what key was pressed */
char c = get_keypress();
/* process key press */
...
}
}
Example: Filtering Event Signals using an Event Handler
=======================================================
This code registers an event handler that filters out unwanted events
so that the consuming task only wakes up when needed.
.. code-block:: c
int validate_keypress(int event_id_is_unused)
{
/* determine what key was pressed */
char c = get_keypress();
/* signal task only if key pressed was a digit */
if ((c >= '0') && (c <= '9')) {
/* save key press information */
...
/* event is signalled to task */
return 1;
} else {
/* event is not signalled to task */
return 0;
}
}
void keypress_task(void)
{
/* register the filtering routine */
task_event_set_handler(KEYPRESS, validate_keypress);
/* consume key presses */
while (1) {
/* wait for a key press to be signalled */
task_event_recv(KEYPRESS);
/* process saved key press, which must be a digit */
...
}
}
APIs
****
The following Event APIs are provided by microkernel.h.
+------------------------------------------+----------------------------------+
| Call | Description |
+==========================================+==================================+
| :c:func:`isr_event_send()` | Signal an event from an ISR |
+------------------------------------------+----------------------------------+
| :c:func:`fiber_event_send()` | Signal an event from a fiber. |
+------------------------------------------+----------------------------------+
| :c:func:`task_event_send()` | Signal an event from a task. |
+------------------------------------------+----------------------------------+
| :c:func:`task_event_recv()` | Tests for an event signal |
| | without waiting. |
+------------------------------------------+----------------------------------+
| :c:func:`task_event_recv_wait()` | Waits for an event signal. |
+------------------------------------------+----------------------------------+
| :c:func:`task_event_recv_wait_timeout()` | Waits for an event signal |
| | for a specified time period. |
+------------------------------------------+----------------------------------+
| :c:func:`task_event_set_handler()` | Registers an event handler |
| | function for an event. |
+------------------------------------------+----------------------------------+