Modes of Operation

A mode of operation specifies how Céu-Arduino captures events from the environment (e.g., pin changes) and redirects them to the Céu application.

Céu-Arduino supports the polling and interrupt-based modes of operation.

The polling mode is the default mode of operation.

The modes of operation are implemented in C and are part of Céu-Arduino. Each mode is described in pseudo-code as follows.

Polling

The polling mode of Céu-Arduino continually checks for changes in the environment in an infinite loop:

void setup () {
    ceu_start();
    while (<program-is-running>) {
        ceu_input(CEU_INPUT__NONE, NULL, <time>);   /* input async and timer */
        if (<pin-*-changed>) {
            ceu_input(CEU_INPUT__PIN_*, <...>);     /* input pins */
        }
        <...>   // for each pin
    }
    ceu_stop();
    while (1);                                      /* freezes arduino */
}

void loop () { /* never reached */ }

The inputs are polled on each loop iteration and changes are notified to the Céu application through ceu_input calls.

The polling mode uses 100% of the CPU time.

Input Events

Currently, the polling mode supports the following input events:

Compilation

Since polling is the default mode of operation, compilation only needs to provide the Céu application:

$ make CEU_SRC=<path-to-ceu-application>

Interrupts

In the interrupt-based mode of Céu-Arduino, all input is done in Céu itself through async/isr blocks. Emitting an input event from an async/isr only sets a flag which is then checked in the Arduino loop:

void setup () {
    ceu_start();
    while (<program-is-running>) {
        ceu_input(CEU_INPUT__NONE, NULL, CEU_WCLOCK_INACTIVE);
        if (<any-isr-evt-occurred>) {               // interrupts off
            ceu_input(<isr-evt-occuring>, <...>);   // interrupts on
        }
#ifdef CEU_FEATURES_ISR_SLEEP
        else if (!<program-has-pending-async>) {
            <enter-sleep-mode>
        }
#endif
    }
    ceu_stop();
    while (1);                                      /* freezes arduino */
}

void loop () { /* never reached */ }

To comply with the synchronous semantics of Céu, all ceu_input calls are serialized in the loop.

If the macro CEU_FEATURES_ISR_SLEEP is defined, the Arduino enters in the SLEEP_MODE_IDLE sleep mode after each reaction.

Interrupts are disabled only while checking for occurring inputs. Hence, async/isr blocks and synchronous code may be concurrent and require atomic blocks.

An async/isr in Céu-Arduino requires two arguments:

  • the interrupt number (i.e., the index in the interrupt vector)
  • the interrupt trigger mode (i.e., when the interrupt should be triggered)

The interrupt trigger mode is only used for digital pin interrupts:

https://www.arduino.cc/en/Reference/AttachInterrupt

The example that follows executes the code marked as <...> whenever the value of pin 2 changes:

spawn async/isr [_digitalPinToInterrupt(2),_CHANGE] do
    <...>
end

Input Events

Drivers:

Compilation

Applications that use interrupts have to be compiled with CEU_ISR=true:

$ make CEU_ISR=true CEU_SRC=<path-to-ceu-application>