Codel declaration

## Contents

- Your rights

- Introduction

- Component model

- Component description file

  - Preprocessing

  - Elements of a description file

  - Data type and constant definitions

  - Module declaration

  - Component declaration

  - Interface declaration

  - IDS declaration

  - Port declaration

  - Task declaration

  - Service declaration

  - Codel declaration

  - Identifiers and reserved keywords

  - Pragmas

  - Grammar reference

- GenoM IDL mappings

- Running GenoM

- Tutorials

- Templates

## Codel declaration

Codels are callbacks to the actual code implementing services in a component. There are two kind of codels: `simple codels` and `finite state machine codels`.

(42) `codel-property ::=` | `opt-async` `"codel"` `(` `codel` `";"` `|` `fsm-codel` `";"` `)`
(37) `opt-async ::=` | `[` `"async"` `]`

Codels are normally functions that execute in a short amount of time compared to the time characteristics of the component. During the execution of a codel, the component is typically blocked. If a codel is expected to last much longer than the desired reaction time of the component, or block until some external event arrives, it can be labelled `async`.

### Simple codels

Simple codels are functions associated to service validation callbacks or implementing component `functions`.

(35) `codel ::=` | `identifier` `"("` `codel-parameters` `")"`

The identifier is the name of the external function implementing the codel. parameters are described in the third section.

### Finite state machine codels

Finite state machine (FSM) codels are functions associated to the execution of `activities`.

(36) `fsm-codel ::=` | `"<"` `event-list` `">"` `identifier` `"("` `codel-parameters` `")"` `"yields"` `event-list`
(39) `event-list ::=` | `{` `event-name` `","` `}` `event-name`
(38) `event-name ::=` | `[` `"pause"` `"::"` `]` `identifier`

In addition to the identifier and parameters described in the previous section, FSM codels define the state machine of their corresponding `activity`. The state machine is defined with a list of states and possible transitions.

The bracketed event list, before the codel identifier defines one (or more) state of the FSM, and associates the codel with this state (or list of states). When the FSM reaches the corresponding state, the codel is executed. There are two predefined states : start and stop. The start state is required: this is the state in which the FSM begins its execution. The stop state is optional: the FSM goes into this state when it receives an external interruption request.

The event list specified after the `yield` keyword statically defines all possible transitions from this state to other states. For each possible transition, a corresponding state must exist in the activity FSM. There is one predefined transition called ether: this is the final state of the FSM and it is used to indicate the regular termination of the activity. There must always exist a path from the start state to the ether state. If a stop state is defined, a path from stop to ether must also exist. The actual transition executed by the FSM depends on the codel function return value.

Transitions normally occur immediately, so that the FSM executes as fast as possible. This execution can still be explicitely paused, for instance to wait until the next period or until something new happens in the component. For this purpose, a transition to a new state `s` can optionally be defined in the `pause` namespace, by specifying the transition as `pause::s`. A `paused` transition means that the FSM will pause its execution either until the next period (within periodic tasks), or until a new internal event occurs (within tasks with no period). Internal events correspond to a non-paused transition of another activity within the component, or the execution of an `attribute` or `function`.

### Example

This would declare a FSM with one main state, typically looping until some condition is met, and a stop state in case of premature interruption.

    codel<start> do_start()            yield main;
    codel<main>  do_main(in condition) yield pause::main, ether;
    codel<stop>  do_stop()             yield ether;

In this example, the main loop will be paced according to the context in which the codels are defined (a periodic task, for instance). Without the `paused` transition, the loop would typically eat all the available CPU.

### Codel parameters

(40) `codel-parameters ::=` | `[` `{` `codel-parameter` `","` `}` `codel-parameter` `]`
(41) `codel-parameter ::=` | `opt-parameter-src` `parameter-dir` `(` `parameter-variable` `|` `parameter-variable` `"::"` `identifier` `|` `"::"` `identifier` `)`
(43) `opt-parameter-src ::=` | `[` `"ids"` `|` `"local"` `|` `"port"` `|` `"remote"` `]`
(44) `parameter-dir ::=` | `"in"` `|` `"out"` `|` `"inout"`
(45) `parameter-variable ::=` | `identifier` `|` `parameter-variable` `"."` `identifier` `|` `parameter-variable` `"["` `positive-int-const` `"]"`