Interrupt is very important and interesting topic in embedded systems as well as in computer systems. When a CPU is running then it, mainly do below steps
- Fetch instruction from text segment i.e. .txt segment (Click here to read different memory segments)
- Executes the instructions
- Based on the executed instruction, it may write the data back to memory or other registers.
In this way, the written code is executed. While it is busy in executing these steps, the world inside & outside the microcontroller/microprocessor keeps on changing. The MCU may toggle a GPIO or may send data outside the MCU via interfaces such as UART/SPI/I2C etc. On other hand it may receive data via these interfaces or the state of GPIO pin may change. So, it receives some external event that has happened. Inside the MCU, it may need to do specific stuff at regular period of interval.
One way to do this stuff is – at regular interval the MCU will keep on checking the Rx data on UART/SPI/I2C or the state of a pin or if some predefined time period has elapsed or not. This method is known as polling mode. Using this method, we end up wasting some time and resource.
Another way is to use get notification whenever any data is received on UART/SPI/I2C or the state of pin is changed by external world or a time period is expired. This notification is known as interrupt. It’s called interrupt because, when MCU gets this notification then it interrupts its normal routine of processing and takes care of the received notification. Whatever the task is done by MCU/MPU in the interrupt, it is known as Interrupt service routine i.e. IRQ also known as Interrupt handler.
To get the interrupt, we need to register the interrupt into the Interrupt Vector Table. An interrupt vector table is a table of memory addresses that specifies the location i.e. address of the interrupt service routines (ISRs) for each interrupt source in the system. When an interrupt occurs, the controller retrieves the address of the corresponding ISR from the interrupt vector table and jumps to that address to execute the ISR.
The interrupt vector table is typically located at a fixed memory address in the controller’s memory map, and each entry in the table corresponds to a specific interrupt source. For example, if the controller has two interrupt sources, there might be two entries in the interrupt vector table: one for the first interrupt source e.g. timer interrupt and one for the second interrupt source e.g. UART interrupt. The ARM controller uses the interrupt number to index into the interrupt vector table and find the correct ISR.
The interrupt vector table can be used to enable or disable specific interrupts by simply modifying the corresponding entry in the table. When an interrupt is disabled, the controller will ignore the interrupt request and will not jump to the corresponding ISR. This allows the system to selectively enable or disable certain interrupt sources as needed.
When an interrupt occurs then the CPU stops its normal execution and jumps to the address of ISR. It will start executing the instructions of the ISR. Once it executes all the instruction of an ISR then the CPU will resume executing the instruction where it was before.
We cannot pass any argument to the ISR routine and the ISR routine cannot return anything.
It might be possible that when CPU is executing instruction from an ISR i.e. it is inside an interrupt then another interrupt can also occur. This event is known as Nested Interrupt. Based on the priority of the interrupt, the CPU will execute the highest interrupt first. e.g. if timer interrupt is configured with higher interrupt priority than an UART interrupt, then there will be two cases
- If CPU is inside UART interrupt and a timer interrupt is triggered, then CPU will jump to the timer interrupt and will serve it. Then it will serve the UART interrupt and then will go back to normal execution.
- If CPU is inside timer interrupt and a UART interrupt got triggered, then CPU will not serve the UART interrupt. It will first finish the timer interrupt and then it will move to the UART interrupt.