Now, let's put our exception handling theory to the test to see what it actually looks like and how it works. This is our main application again, and we're going to use an NVIC function, NVIC_SetPendingIRQ, or set pending interrupt to set that TIM0_IRQn to one. What this function does is it sets the pending bit further interrupt in the list of system registers to one and because in this particular application, there's no other interrupts that are pending, the processor takes the exception and branches to the relevant exception handler. Let's look at that through tarmac trace. That function call SetPendingIRQ eventually results in this store instruction and we can see that this store instruction now writes a different address, xE000E200 implies the value 4. Tarmac trace translate this address automatically for us to assume a readable name and we can see that it is the register, NVIC_ISPR0. If you look in the ARM on ISPR0 is the interrupt set pending register Number 0. This register also has multiple fields. In fact, each bit corresponds to an individual interrupt. Bit number 3, that is bit 012, index number 2 is the bit for our setting for our interrupt and we're setting it to one to indicate that interrupt is pending. That's what's shown and done by this seems, this function. But now because there is no other interrupt pending, the processor starts implicitly automatically triggering the exception. The first thing it does as part of that is it automatically also sets the NVIC ICPR0 bit further interrupts to one. ICPR0, according to the ARM on, is the interrupt clear pending register. You can already see that some implicit changes start happening automatically. Tarmac trace shows this all. The processor also updates the ICSR register. This is the interrupt control and status register and it changes quite a bit of the values in there, but the one we care about is bit 22, which is being set to one to indicate that there is an interrupt service routine or ISR that is pending. We haven't started handling the exception yet, but we can see what the side effect of setting that set pending register is. Then according to the tarmac trace, a whole lot of stuff happens. Let's break it down. First thing is that the processor saves the required registers to the stack automatically. This is the stack frame as defined in the exception handling module. The registers that need to be saved by the exception handler, the process states register, the stack pointer, and that special exception return value. We claimed that the Cortex M exception handling does all of this automatically and you can use tarmac trace to verify that it indeed does happen. After that, you get a couple of other lines of trace. The main one that you will see that's common to fast models in RTL will be this E identifier or exception identifier showing you once again the address of the exception handler, cd0. The internal interrupt number that the processor fast model uses for this purpose, 12x in this case, and the human-readable name, external interrupt number 2. This is what you would look for, a clk E to find any exceptions that are being handled based on a tarmac trace. The other line that we find up to here, info exception reason is specific to fast models and it's not something that RTL will show you and it's a way for you to quickly find the start of the handling of an exception. If you see phase equals activate within for exception reason, then that is saying that the fast model is starting to handle an exception. This is followed by a bunch of other things, but the ones we care about and want to focus on are these two implicit register updates. Here, we are writing to a register, NVIC IABR0, and we are again writing to the field that corresponds to interrupt Number 2. IABR is the interrupt active bit register. We're saying that now that interrupt is being actively handled and just before this, we also did a couple of other things. We cleared the interrupt set pending register and the interrupt clear pending register bits to zero. We also said that, yes, we are about to start having this interrupt, we are going to be active in this interrupt, so we do not need to say that it is pending or that it needs to be cleared. Once we started to handle that interrupt, we again update the interrupt controller and status register, ICSR, and this time, instead of setting bit 22, the ISR pending bit, we clear it to say there are no more interrupts pending and we are actively handling this interrupt. This is a simple use case where there aren't any nested interrupts. You can create more complicated examples where those bits might not be cleared and then you could use tarmac trace in a similar way to study how the nesting of interrupts works. We've just seen what happens automatically on the processor. In terms of fast models, it's very easy to pick out using tarmac trace. All of the different steps of handling an exception. You can look for info exception reason with phase equals activate which shows up just before the exceptions about to be handled. Then you can look for a clk E or exception Identifier entry, which will give you the name of the interrupt at SP handled. On RTL, you would only get this clk E part, you won't get the exception reason part. Eventually then after all of your system register updates and so on, you would see the first instruction in your exception handler being executed. The key thing here is that now, instead of being in thread mode, you are now in handler mode and the tarmac trace will show you this. Then when the interrupt handling is finished, you will see on a fast model another info exception reason entry, this time with phase equals deactivate to say you are stopping handling that interrupt. You won't see anything from RTL which specifically indicates that you've ended your interrupt handling, you don't get an extra entry like a clk E with the deactivate or something like that. But what you do see is the next instruction that you execute is back in thread mode. If you want to identify where an exception is being handled and when you're returning, look for handler mode to find where the exception handler instructions are being executed. Then look for the first instruction in thread mode to identify where you returned from your exception handler and started the rest of your application.