Learn about Interrupts
Introduction
An interrupt is a signal to the processor emitted by hardware or software indicating an event that needs immediate attention. Whenever an interrupt occurs, the processor completes the execution of the current instruction and stops what it is doing, then handles a high-priority task first. After the interrupt is handled, the processor goes back to whatever it was doing before and then continues executing the code.
Interrupt Service Routine
When an interrupt occurs, the system needs to handle it in a special routine code, which is called an interrupt service routine. An Interrupt Service Routine (ISR) is a function called by hardware that corresponds to a function that is executed when an interrupt happens.
Whenever an interrupt occurs, the controller completes the execution of the current instruction and starts the execution of an Interrupt Service Routine (ISR) or Interrupt Handler.
Figure 1: Handling of Interrupts
Since an ISR is called by hardware and not your program, your main program has no idea when an ISR will be called, and can not pass parameters to the ISR.
Having an ISR is like having a second program independent from the main. These little programs can handle mundane tasks only when mundane tasks need to be worked on. This allows the main to focus on the important command, control, and communications tasks. In fact, there is much different hardware inside the microcontroller that can generate interrupts, take a look at the microcontroller datasheet to find the detailed information.
Design an Interrupts Supported System
- Decide a background/main task
- Prioritize interrupt properly
- Edge triggered or level triggered interrupt
- Keep them short – use-flags
- Keep it simple – use state machines
- Global variables – know when it's modified
- Local variables – know your compiler
- Using data buffers – be heedful of overflows
- Shared memory – read completely at once
- A little more on buffers
- Multi-Byte Buffers – know the Endianness
- Structured buffers – understand the structure padding
- Calling functions in an ISR – be cautious
- Time-critical tasks – understand the latency
- LVD (Low Voltage Detect) Interrupt- make it blocking
Decide a background/main task
ISR Guidelines
- The code inside an ISR should be simple and as small as possible.
- Never put an infinite loop inside ISR - unless you never want to get back to main.
- Never put a delay that waits for user input inside an ISR. For example, do not put the following in an ISR: while (BUTTON == 0){}; inside an ISR.
- All communication between the ISR and main requires the use of global variables.
- Avoid data processing inside ISR, instead, have the main do the heavy lifting and communicate to the ISR through flags and global variables.
- Sometimes an ISR will need to retain a value between invocations. In cases like this, you will need to use a static variable.
- Carefully calling the function from within an ISR, especially a function is also called from within main. If you want to call a function, make sure that the function is thread-safety.
- Do not call a blocking function.