Imagine this scenario: you are waiting for a important mail. You open the door to check the mailbox every 3 minutes. You waste a lot of time to check 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 you 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 scenario back to the embedded system design. In the system, the microcontroller monitors the status of a device. When the data is ready, the microcontroll 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 of 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 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 immediate.
Interrupt, just like a doorbell for the microcontroller, will tell microcontroller when data on the devices are ready and can be processed. It send a signal to the microcontroller to mark an event that requires immediate attention. Interrupt is requesting CPU to suspend performing 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
Device is connected to a CPU pin that called the IRQ (Interrupt Request Pin). When the device needs a I/O transmission, it will active IRQ signal to the CPU. The CPU will respond to IRQ by the following steps:
- Complete the current instruction
- Save content of the CPU registers onto the stack.
- Load program counter (PC) with address of an interrupt service routine (ISR)
These three steps is called a content switch. It occurs automatically in the hardware. Then, the CPU will executes the ISR program to handle the I/O operations. The last instruction of ISR is a 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. An non-maskable Interrupt (also known as NMI) can not be disabled. Once an non-maskable interrupt occurs, the CPU needs to handle it immediately. Usually it is reserved for critical events such as power failure.
A interrupt controller is used on the most of high performance microcontrollers. It is a device that is used to combine several interrupt sources onto on 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 sepcial type of interrupts. When a reset occurs, the CPU will finish executing the current instruction, and then beging 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 instuctions from a predetermined starting address.
Reset has 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 operting 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.
In edge-triggered interrupt, the IRQ becomes active when the signal changes at falling or rising edge state. To get a new request, the signal must go back to inactive state, and then change the signal again.
Edge-trigger is like a postman delivering mail to you 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 edge-triggered interrupt is set, the ISR will only get fired on falling or rising edge of a pulse on the IRQ pin.
In 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 pervious program, if the IRQ line is still asserted, the CPU get 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 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 system design perspective, the 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 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 a feedback to the interrupt source (the device that sends a level-sensitive signal on the IRQ pin) in order to reset it's 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 a 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 are hold 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 the 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 interrupts, 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 stack. When a interrupt occur, CPU will automatically save the registers onto the stack and then switches from current program to ISR. When CPU is exiting from ISR, it will restore the registers back to the their previous values. The program does not know when and in which code that the interrupt will be triggered. It is hard to prepare the parameters into the registers for the interrupt. Thus, the parameters must be saved on 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 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?