Imagine this scenario: you are waiting for an important mail. You open the door to check the mailbox every 3 minutes. You waste a lot of time checking the mail, and it also makes your work very inefficient. Now, you decide to install a doorbell, and a mobile application to notify you when a new mail is delivered to your house. Now, you do not need to check the mailbox every time. You just need to hear the alarm from the doorbell or cell phone and can focus on your current job.
Converts these scenarios back to the embedded system design. In the system, the microcontroller monitors the status of a device. When the data is ready, the microcontroller will process the data. After that, it moves on to monitor the next device until all devices are serviced. The microcontroller checks all devices in a round-robin fashion. This is called the Polling method. The main drawback of this method is that the program is a waste of time for the microcontroller, which needs to wait and check whether the new data has arrived, just like you opening the door to check the mailbox every time. This is suitable for a simple tasks system. However, if the microcontroller is working on a heavy calculation, the new data, such as the user pressed on a keypad, may not be processed immediately.
Interrupt, just like a doorbell for the microcontroller, will tell the microcontroller when data on the devices are ready and can be processed. It sends a signal to the microcontroller to mark an event that requires immediate attention. The interrupt is requesting the CPU to suspend performing the current program and to make time to execute a special code, which is called Interrupt Service Routine (ISR) or Interrupt Handler, and then resumes what CPU was doing. Whenever any device needs service, the device notifies the microcontroller by sending an interrupt signal. The system can focus on the current procedure without missing or delaying the handling of important events.
Typical Interrupt Scenario
The device is connected to a CPU pin called the IRQ (Interrupt Request Pin). When the device needs an I/O transmission, it will activate the IRQ signal to the CPU. The CPU will respond to IRQ by the following steps:
- Complete the current instruction
- Save the content of the CPU registers onto the stack.
- The load program counter (PC) with the address of an interrupt service routine (ISR)
These three steps are called a content switch. It occurs automatically in the hardware. Then, the CPU will execute the ISR program to handle the I/O operations. The last instruction of ISR is an RTI (return from interrupt). The CPU will restore the old register contents from the stack, then continue executing the program.
Interrupt Request, IRQ
There are two types of interrupts: maskable and non-maskable IRQs. A maskable IRQ can be disabled by instruction, hence the CPU can ignore the interrupt signal until it is enabled. A non-maskable Interrupt (also known as NMI) can not be disabled. Once a non-maskable interrupt occurs, the CPU needs to handle it immediately. Usually, it is reserved for critical events such as power failure.
An interrupt controller is used on most high-performance microcontrollers. It is a device that is used to combine several interrupt sources onto one or more CPU IRQ lines while allowing priority levels to be assigned to its interrupt outputs. When the device has multiple interrupt outputs to assert, it asserts them in the order of their relative priority.
All interrupts are asynchronous to instruction execution. In the embedded system, peripherals use interrupts to communicate with the processor.
Non-maskable Interrupts, NMI
A non-maskable interrupt (NMI) can be signaled using the NMI signal or triggered by software. This exception has the highest priority other than reset. NMI is permanently enabled and has a fixed priority. NMIs cannot be masked or prevented from activation by any other interrupt or preempted by any interrupt other than reset.
A reset is a special type of interrupt. When a reset occurs, the CPU will finish executing the current instruction, and then begin the execution of the reset routine. Reset does not return back to the original code, and it is used to force the CPU to assume a set of initial conditions and to being executing instructions from a predetermined starting address.
Reset has the highest priority than other interrupts, and it is non-maskable.
Software Interrupts, SWI
A software interrupt is a type of interrupt that is caused either by a special instruction in the instruction set or by an exceptional condition in the processor itself. It is basically a mechanism to call an interrupt routine almost as a normal routine. Software interrupts are often used for programs to call a subroutine located in the operating system without knowing in advance where the function will be located in memory since the call will invoke the switching to interrupt state.
In the early operating system, such as MS-DOS, the common software interrupts used are INT 10h for videos services and INT 21h for DOS services. The software interrupts also are used for debugging programs, such as setting breakpoints into your program.
Interrupt Triggered Modes
There are two activation levels for the hardware interrupts edge-triggered and level-triggered interrupts.
An edge-triggered interrupt, the IRQ becomes active when the signal changes at a falling or rising edge state. To get a new request, the signal must go back to the inactive state, and then change signal again.
Edge-trigger is like a postman delivering mail to your house. He just put the mail into your mailbox, press the doorbell to notify you, and then he left to go to the next house.
If the edge-triggered interrupt is set, the ISR will only get fired on the falling or rising edge of a pulse on the IRQ pin.
In a level-triggered interrupt, as long as the IRQ line is asserted, the CPU gets an interrupt request. When CPU exists from ISR and return to the previous program, if the IRQ line is still asserted, the CPU gets the interrupt again immediately.,
Level-trigger is like a postman delivering parcels to your house. He presses the doorbell and stays a while at the door waiting for your signature. After you signed all the documents, you got your package and he went to the next door.
For example, If a low-level-triggered interrupt is set, the ISR will get fired when a low-level signal is on the IRQ pin. The signal on the IRQ pin must be removed (set to high-level) before the execution of the last instruction of ISR. Otherwise, the ISR will be launched again as long as the pin is low.
From a system design perspective, the edge-triggered is like a detection for events; the level-triggered is like a detection for states.
If the device sends a pulse on the IRQ pin, the edge-triggered interrupt must be used on that pin. If the device sends a level type signal on the IRQ pin, either edge-triggered or level-triggered interrupt can be used in that pin. One thing frequently overlooked when you connected level-type IRQ devices is that the interrupt signal requires feedback to the interrupt source (the device that sends a level-sensitive signal on the IRQ pin) in order to reset its IRQ signal while edge type devices do not need it.
If a device is sending a shorter pulse on a longer wired IRQ line, the microcontroller may not receive the signal. The most certain way to avoid missing edge-level IRQs is to use a latch to lock the IRQ signal at the source, and use level-sensitive interrupts on the microcontroller. However, ensure that the latch must be cleared in the interrupt handler.
On the other hand less-than-perfect hardware,
Edge triggers for scalability and level triggers for more reliable outcomes.
Interrupt Service Routine (ISR) and Interrupt Vectors
When an interrupt occurs, the CPU will just to a special code, that is called Interrupt Service Routine (ISR), or Interrupt Handler. The difference for a subroutine is that the address of ISRs is held at a fixed location in memory or at pre-determined starting addresses. The group of memory locations set aside to hold the address of ISRs is called Interrupt Vector Table.
For every interrupts, there must be an Interrupt Service Routine (ISR) or interrupt handler.
The programmer can customize the service routine addresses by using a vector jump table.
If multiple devices shares on same interrupt signal, then the code in the ISR needs to check which device sent the IRQ (Interrupt Request).
Summary of Interrupt and ISR
- An ISR will most likely change the content of some of the CPU registers
- An ISR also needs to know where to return to when it has completed servicing the request
- When an interrupt request occurs and it is enabled the CPU will push all the CPU register values onto the stack before it fetches the vector
- An ISR use instruction, such as RTI, to return control back to the program interrupted
- When RTI is executed, it pulls the data from the stack to restore them to the CPU registers
- Resets do not stack the CPU registers, since a reset routine does not normally return control back to the program interrupted
Communication and Synchronization Between Interrupts and Main Program
For regular function (or subroutine) calls and software interrupt, the registers and stack will be used to pass the parameters to the function. For hardware interrupts, the parameters can not be passed through registers and stacks. When an interrupt occurs, the CPU will automatically save the registers onto the stack and then switches from the current program to ISR. When the CPU is exiting from ISR, it will restore the registers back to their previous values. The program does not know when and in which code the interrupt will be triggered. It is hard to prepare the parameters into the registers for the interrupt. Thus, the parameters must be saved in the global memory area. And some control variables must be included for the synchronization. Data or parameters can be variables, arrays, structures, or queues.
This architecture is very useful for reading data from the devices. When the device prepares the data ready, send an interrupt request to the CPU. In ISR, data will be read from the device to the global data area. Then use the control variable (such as Flag, Status...) to notify the main program that the data is already in the data area.
- What is the difference between interrupt and a signal when to use each?
- What is the difference between the RET (Return from Subroutine) and RTI (Return from Interrupt) instructions? Explain why we can not use RET instead of RTI as the last instruction of an ISR?