Barr Group FacebookBarr Group TwitterBarr Group LinkedInBarr Group Vimeo

Rules

The following C coding rules relate to functions that are actually interrupt service routines:

Rule 6.5.a.) Interrupt service routines (ISRs) are not ordinary functions. The compiler must be informed that the function is an ISR by way of a #pragma or compiler-specific keyword, such as __interrupt.

Rule 6.5.b.) All functions that implement ISRs shall be given names ending with _isr().

Rule 6.5.c.) To ensure that ISRs are not inadvertently called from other parts of the software (they may corrupt the CPU and call stack if this happens), each ISR function shall lack a prototype, be declared static, and be located at the end of the associated driver module. (Note: Be forewarned that a smart static analysis tool, such as lint, will likely complain about this unreachability.)

Rule 6.5.d.) A stub or default ISR shall be installed in the vector table at the location of all unexpected or otherwise unhandled interrupt sources. Each such stub could attempt to disable future interrupts of the same type, say at the interrupt controller, and assert(). (Note: Although this doesn’t prevent any bugs, it sure does help find bugs in the hardware and makes the system more robust.)

Example

__interrupt 
void
timer_isr (void)
{
    // Handle the interrupt efficiently here, then return.
}

Reasoning

An ISR is an extension of the hardware. By definition, it and the straight-line code are asynchronous to each other. If they share global data, that data must be protected with interrupt disables in the straight-line code. The ISR must not get hung up inside the operating system or waiting for a variable or register to change value.

Exceptions

None.

Enforcement

These rules shall be enforced during code reviews.

Comments:

It's worth noting that the ARM Cortex microcontrollers (M series in particular) are designed so that an ISR can be coded as just an ordinary C void function: no need for a #pragma or similar compiler magic.

In re: Rule 6.5.c, the ARM Cortex Microcontroller Software Interface Standard (CMSIS) requires that ISRs be declared as global (ie. non-static) functions--though at least they need not be mentioned in a header file.

If an ISR function has no prototype and is declared static at the end of a file, it cannot always be correctly referenced to assign it to a vector.  In that case, there must at least be a prototype for it at the top of the source file within which it is contained.

Absolutely.  This happens when there's a static vector table and the compiler lacks a #pragma or keyword for assigning the interrupt function to a slot in the table.

What’s happening and how it’s done. Get in the know.

Sign up for our newsletter today!

Receive free how-to articles, industry news, and the latest info on Barr Group webinars and training courses via email. 

To prevent automated spam submissions leave this field empty.