Interrupt service routines (ISR) can communicate with CTL tasks using a subset of the CTL programming interface. An ISR should not call any of the CTL functions that can block; if your ISR calls a blocking function, ctl_handle_error will be called. To detect whether a task or an ISR has called a function, CTL uses the global variable ctl_interrupt_count. Interrupt service routines must increment this variable on entry and decrement it on exit. Any CTL functions called by an ISR that require a task reschedule will set the variable ctl_reschedule_on_last_isr_exit.

On exit from an interrupt service routine, ctl_interrupt_count is decremented to zero and, if ctl_reschedule_on_last_isr_exit is set (after resetting ctl_reschedule_on_last_isr_exit), a CTL reschedule operation occurs. The support for writing ISRs differs, depending on the target. In general, on entry to an ISR the following is needed:

// … preserve register state here
++ctl_interrupt_count;

…and, on exit from an ISR:

ctl_interrupt_count--;
if (ctl_interrupt_count == 0 && ctl_reschedule_on_last_isr_exit)
  {
    ctl_reschedule_on_last_isr_exit = 0;
    // reschedule
  }
else
  {
    // ...restore register state here
  }