From the course: Introduction to Embedded Systems with Rust
Interrupts - Rust Tutorial
From the course: Introduction to Embedded Systems with Rust
Interrupts
- [Narrator] We came across interrupts when building our first program. We used it to wake up our system every second when the timer is zero. Interrupts are one of the most important parts of an embedded system. So, what exactly are they? An interrupt is a signal that ensures events are handled in a timely manner. They're sent to the CPU to request it to interrupt the currently executing code and handle it instead. Interrupts can be generated from either software or hardware. Imagine the timer in the program we wrote hit zero, but there was an expensive computation running. Without interrupt, we would have to wait for that computation to finish. It could take five more seconds or five more hours. Who knows? What we want is to be able to handle our timer expiring immediately as it happens. So we interrupt whatever's currently processing, handle our timer, and then continue processing. Interrupts are handled by interrupt service routines. These are just functions, but you may be wondering, "How does the hardware know which function to call for which interrupt?" That is a great question. These are defined in the interrupt vector table. The interrupt vector table is a data structure that maps interrupt signals to the interrupt service routines. Here, we can see the vector table of our Cortex-M3. It shows each interrupt and their respective location in memory. It is up to the startup code to populate the locations with the corresponding interrupt service routine. At a high level, we can see how a CPU handles an interrupt. When an interrupt fires, the CPU receives a signal to handle it. The CPU will likely be busy with some other work. However, we want it to continue where it left off after handling the interrupt. To do this, the processor saves the current state of execution, that includes the registers and the current address of the current instruction. It then looks at the interrupt vector table to find the memory address of the interrupt service routine and subsequently execute it. It'll then restore the state of the interrupted execution and carry on. The last piece of the puzzle is: What happens if we have multiple interrupts firing at the same time? We handle them by priority. Interrupts have a priority associated with them. When multiple interrupts fire, it'll process the one with the highest priority first. Additionally, a higher priority interrupt can even interrupt a lower priority interrupt. That's a lot of interrupting. This ensures that critical interrupts are handled timely. This is especially useful in hard real-time systems where they're upper bounds on worst case performance. And that's it on interrupt.