User guide

22 Focusing on a Single Device
User-Defined Events
A user-defined event can contain assignments and function calls. Such events
using complex expressions can affect the response time for all events within a
program, so you must minimize calls to complex functions within user-defined
events. Assignments within user-defined events can only be done to global
variables.
Furthermore, the evaluation of an event keyword or an event expression, such as
timer_expires(t), clears any pending event, regardless of whether the entire
expression is TRUE or FALSE, as below:
when ((timer_expires(t)) && (flag = = TRUE))
As with ANSI C compilers, the Neuron C compiler evaluates logical expressions
only as much as needed. For example, in an if (a && b) expression, the b term is
only evaluated if a is TRUE, and in an if (a || b) expression, the b term is only
executed if a is FALSE. This is called
short-circuit evaluation
, and is specified by
the ANSI C language definition.
When combining user-defined expressions with a predefined event using the
logical operators discussed in the paragraph above, you must make sure that this
does not prevent the predefined events from being evaluated as needed, in order
to avoid blockage of the event queue as discussed earlier in this chapter.
For example, the following user-defined event expression is okay:
when ((timer_expires(t)) && (flag = = TRUE))
But, if the expression above is reversed, as shown below, it is likely to cause a
blockage of the event queue if the flag variable is true for any significant time,
because the short-circuit nature of the logical-and operator can prevent the timer
expiration event from being checked at all. Thus, the reversed expression shown
below must be avoided:
when ((flag = = TRUE) && (timer_expires(t)))
Scheduling of When Clauses
The scheduler evaluates when clauses in round-robin fashion: Each when clause
is evaluated by the scheduler and, if TRUE, the task associated with it is
executed. If the when clause is FALSE, the scheduler moves on to examine the
following when clause. After the last when clause, the scheduler returns to the
top and moves through the group of when clauses again.
Example: A group of when clauses might look like the following:
when (nv_update_occurs) // Event A
// {task to execute}
when (nv_update_fails) // Event B
// {task to execute}
when (io_changes) // Event C
// {task to execute}
when (timer_expires) // Event D
// {task to execute}