How to write interrupt handlers

ChibiOS RT and NIL offer a cross-platform method for writing interrupt handlers. Port-related and compiler-related details are encapsulated within standard system macros.

Interrupt Types

ChibiOS abstracts interrupt sources in two classes:

  • Regular Interrupts. Regular interrupts ISRs are able to interact with the OS and wake up threads or use other OS services. System critical sections suspends regular interrupts so such sources are subject to additional jitter caused by the OS and/or Application.
  • Fast Interrupts. On certain architectures it is possible to use fast interrupt sources, such sources can preempt the kernel and have on additional jitter caused by the OS and/or Application. Fast ISRs must never use any OS-related function or macro.

Writing Regular Interrupt handlers

A Regular Interrupts handler is an ISR from where the invocation of system APIs is possible, it must be written using the following general form:

CH_IRQ_HANDLER(vector_name) {
  CH_IRQ_PROLOGUE();
 
  /* IRQ handling code, preemptable if the architecture supports it.*/
 
  chSysLockFromISR();
  /* Invocation of some I-Class system APIs, never preemptable.*/
  chSysUnlockFromISR();
 
  /* More IRQ handling code, again preemptable.*/
 
  CH_IRQ_EPILOGUE();
}

Writing Fast Interrupt handlers

On some architectures it is supported a special class of “Fast Interrupts”, such interrupt sources have a higher hardware priority than the kernel so it is not possible to invoke system APIs from there. Fast interrupts handlers must be written using the following general form:

CH_FAST_IRQ_HANDLER(vector_name) {
 
  /* Fast IRQ handling code,
     The invocation of any API is forbidden here because fast interrupt
     handlers can preempt the kernel even within its critical zones in
     order to minimize latency.*/
}

Handlers naming

A note about the handler name vector_name, in some ports it must be a vector number rather than a function name, it could also be a name from within a predefined set, see the notes about the various ports. For example, for Cortex-M a vector name is under the form VectorXX where XX is the byte offset (uppercase hexadecimal) of the vector from the vectors table base, example VectorBC.