Skip to content



MiraOS is depending on an event-driven execution model. Each process typically executes small chunks of instructions before telling the scheduler that they are waiting for an event, and thereby handing control back to the scheduler.

Events can be for instance expiration of an event timer, an incoming network packet, or a user defined event.

Waiting for events

It's only possible to wait for events in the part of a process definition that is between the PROCESS_BEGIN() and PROCESS_END() statements. Waiting for an event is done by calling the PROCESS_WAIT_EVENT() or PROCESS_WAIT_EVENT_UNTIL() system calls. Doing so yields the control back to the scheduler, and execution is resumed only after an event has been sent to the process.

PROCESS_WAIT_EVENT_UNTIL() also takes a statement as an argument, if this statement is evaluated to FALSE the process immediately yields back to the scheduler again waiting for the next event.

PROCESS_THREAD(test_hello, ev, data)
  /* An event-timer variable. Note that this variable must be static
     in order to preserve the value across yielding or waiting. */
  static struct etimer et;


  while (1) {
    etimer_set(&et, CLOCK_SECOND); /* Set the timer to 1 second. */
    printf("Hello, world!\n");


System events

The following events are defined by the kernel.

Event Description
PROCESS_EVENT_INIT Delivered to a process when it is started.
PROCESS_EVENT_POLL Delivered to a process being polled.
PROCESS_EVENT_EXIT Delivered to an exiting a process.
PROCESS_EVENT_CONTINUE Delivered to a paused process when resuming execution.
PROCESS_EVENT_EXITED Delivered to all processes about an exited process.
PROCESS_EVENT_TIMER Delivered to a process when one of its timers expired.

User-defined events

The application developer may also create new events that are not covered by the system-defined events.

The event variable must have an appropriate scope, so that all code using the event can access it.

static process_event_t my_event;

my_event = process_alloc_event();

Note that there is no support for deallocating events.

Asynchronous events

Posting an asynchronous event places the event on MiraOS kernel's event queue. Asynchronous events are delivered to the receiving process some time after they have been posted.

The events on the event queue are delivered to the receiving process by the kernel. The kernel loops through the event queue and delivers the events to the processes on the queue by invoking the processes.

The receiver of an asynchronous event can either be a specific process, or all running processes. When the receiver is a specific process, the kernel invokes this process to deliver the event. When an event is sent to all processes in the system, the kernel devlivers the event sequentially to all processes, one after another.

Asynchronous events are posted with the process_post() call. It first checks the size of the current event queue to determine if there is room for the event on the queue. If not, the function returns an error. If there is room for the event on the queue, the function inserts the event at the end of the event queue and returns.

Synchronous Events

Synchronous events are posted using the process_post_synch() system call. Unlike asynchronous events, synchronous events are delivered directly when they are posted. Synchronous events can only be posted to a specific process.

Because synchronous events are delivered immediately, posting a synchronous event is functionally equivalent to a function call: the process to which the event is delivered is directly invoked, and the process that posted the event is blocked until the receiving process has finished processing the event.

The receiving process is, however, not informed whether the event was posted synchronously or asynchronously.


Care should be taken when posting synchrounous events. They can't be used from ISRs.