A look at interrupts What are interrupts and why are they needed in an embedded system? Equally as important – how are these ideas handled on the Blackfin Dispatch_Tasks ( ) The “standard” instruction cycle of a microprocessor (ENCM369) RESET THE PROCESSOR RESET* INTERRUPT (ACTIVE low) FETCH AN INSTRUCTION FROM PROGRAM MEMORY DECODE THE INSTRUCTION AND FETCH ANY VALUES NEEDED FROM REGISTER OR MEMORY WRITE BACK THE ANSWER EXECUTE THE INSTRUCTION +5V RESET* +5V PROCESSOR RC time constant 200 ms on 68K GROUND The “standard” instruction cycle RESET THE PROCESSOR FETCH AN INSTRUCTION FROM PROGRAM MEMORY RESET* (ACTIVE low) DECODE THE INSTRUCTION AND FETCH ANY VALUES NEEDED FROM REGISTER OR MEMORY WRITE BACK THE ANSWER EXECUTE THE INSTRUCTION EXECUTING ‘YOUR PROGRAM’ UNTIL POWER IS REMOVED The “standard” instruction cycle with external device having important data RESET THE PROCESSOR FETCH AN INSTRUCTION FROM PROGRAM MEMORY RESET* (ACTIVE low) DECODE THE INSTRUCTION AND FETCH ANY VALUES NEEDED FROM REGISTER OR MEMORY WRITE BACK THE ANSWER EXECUTE THE INSTRUCTION This is the data 16-bits EXTERNAL HARDWARE Control signal – Thanks Data received Check if ready Control signal – I have data for you The “wait till ready” approach of reading data from external device In decode phase – read control register value In execute phase – check if 1 -- keep waiting (fetch-decode-execute-writeback instruction cycle) until the control value changes from 0 (device not ready) to 1 (device ready) When 1 – go to a different part of your program code to read the data e.g. call ReadData( ) Then your program must send an acknowledge back to device that the data has been read. e.g. call AcknowledgeReadData( ). The device can then go and get more values for you. PROBLEM: You have no time to do anything else other than wait Not a problem if waiting for this device is the only thing you want to do with the processor Wait till ready approach Very problematic if many devices RESET THE PROCESSOR FETCH AN INSTRUCTION FROM PROGRAM MEMORY RESET* (ACTIVE low) Check if ready Check if ready WRITE BACK THE ANSWER 16-bits Check if ready 16-bits EXTERNAL HARDWARE EXECUTE THE INSTRUCTION 16EXTERNAL HARDWARE EXTERNAL HARDWARE WAITS TOO LONG DECODE THE INSTRUCTION AND FETCH ANY VALUES NEEDED FROM REGISTER OR MEMORY Check if ready The “Poll approach” of getting data Not much waiting – but a lot of “doing” read control register value of device 1 -- if 1 go to a different part of the code to “read the data” (ReadData1( ) ) – after reading the data send an acknowledge signal back to device 1 (AcknowledgeReadData1( ) ) -- if 0 go and read the control value of device 2 – don’t worry about device 1 for some time read control register value of device 2 -- if 1 go to a different part of the code to “read the data” (ReadData2() ) – after reading the data send an acknowledge signal back to device 2 (AcknowledgeReadData2( ) ) -- if 0 go and read the control value of device 3 – don’t worry about device 2 and 3 for some time ETC PROBLEM: What happens if, while you are handling device 2, device 1 has “time sensitive information” that will disappear if device 1 is not serviced immediately Interrupt Approach – basic idea Extra “phase” in instruction cycle DECODE THE RESET THE PROCESSOR RESET* (ACTIVE low) CONTINUE AS BEFORE DO ISR yes FETCH AN INSTRUCTION FROM “NORMAL” (NOT ISR) PROGRAM MEMORY NO CHECK IF AN INTERRUPT REQUEST HAS OCCURRED Acknowledge Request done INSTRUCTION AND FETCH ANY VALUES NEEDED FROM REGISTER OR MEMORY WRITE BACK THE ANSWER CONTROL SIGNAL DATA READY SIGNAL BECOMES INTERRUPT REQUEST EXECUTE THE INSTRUCTION 16-bits data EXTERNAL HARDWARE Issues that MUST be solved if using interrupts on a real uP 1. What if device hardware can only provide a “quick” I am ready signal? 2. What if more than one hardware device wants to send an interrupt request? 3. What if the programmer wants to “ignore” “low priority” interrupt requests? 4. What if certain interrupt requests are too important to ignore? What if hardware device can only provide a “quick” I am ready signal? Add interrupt (capture) latch to processor CONTINUE AS BEFORE DO ISR yes CHECK IF AN INTERRUPT REQUEST HAS OCCURRED Interrupt Latch (Capture Request) Processor clock signal causes load of the latch to capture the transient interrupt Interrupt Buffer 16-bits Acknowledge done EXTERNAL HARDWARE CONTROL SIGNAL FAST CHANGING DATA READY SIGNAL Signal send (1) and then becomes 0 What if the programmer wants to “ignore” a “low priority” interrupt? Add (Ignore) Interrupt Mask Interrupt Latch (Capture) CONTINUE AS BEFORE DO ISR yes CHECK IF AN INTERRUPT REQUEST HAS OCCURRED e.g. IGNORE INTERRUP IF FIO_MASK_A BIT is 0 Interrupt Mask Ignore Processor clock signal causes load of the latch to capture the transient interrupt Interrupt Buffer 16-bits Acknowledge done EXTERNAL HARDWARE CONTROL SIGNAL DATA READY SIGNAL BECOMES INTERRUPT REQUEST LINE What if certain hardware interrupts are too important to ignore? NMI bypass the IGNORE Interrupt Mask CONTINUE AS BEFORE DO ISR yes CHECK IF AN INTERRUPT REQUEST HAS OCCURRED Interrupt Latch (Capture) Interrupt Mask Ignore Processor clock signal causes load of the latch to capture the transient interrupt Interrupt Buffer 16-bits Acknowledge done EXTERNAL HARDWARE CONTROL SIGNAL DATA READY SIGNAL BECOMES INTERRUPT REQUEST LINE What if more than one hardware wants to send an interrupt? Pending interrupts (still to be done CONTINUE AS BEFORE DO ISR yes CHECK IF AN INTERRUPT REQUEST HAS OCCURRED Interrupt Latch (Capture) Interrupt Mask Ignore Processor clock signal causes load of the latch to capture the transient interrupt Interrupt Buffer 16-bits Acknowledge done EXTERNAL HARDWARE CONTROL SIGNAL DATA READY SIGNAL BECOMES INTERRUPT REQUEST LINE Blackfin MASKS and Latches Same hardware in concept Using “idle” low power mode in Lab. 2 Normal “linear flow” PC increments to next instruction Use program counter PC as an Instruction Pointer register Fetch instruction at memory location PC then increment the PC to point at the next instruction PC = PC+2 PC = PC + 4; Subroutine call flow PC = PC + 2 CALL INSTRUCTION DOES RETS = PC + 4 (FFA03C78) PC set to 0xFFA01E24 So instruction 0xFFA01E24 done next This instruction is NOT fetched (until end of subroutine) This instruction is now fetched HAVE JUMPED TO SUBROUTINE Interrupt occurs HERE Must Jump to ISR NOW– but how? Use program counter PC as an Instruction Pointer register Fetch instruction at memory location PC then increment the PC to point at the next instruction PC = PC+2 PC = PC + 4; Interrupt occurs HERE (green arrow) Must Jump to ISR NOW – but how? First step is obvious PC has 0xFFA01E44 in it – Just about to fetch P0.L = instruction Remember what instruction you were about to execute – so you can do that instruction after finishing the ISR How make this happen? RETI is “register used to remember the instruction “stopped” by interrupt RETI = PC (0xFFA01E44) PC now set to ????? value to make interrupt happen Interrupt occurs HERE Must Jump to ISR – but how First step is obvious Remember what instruction you were about to execute RETI = PC (0xFFA01E44) PC = ????? Some how – like magic we must set PC = start of Timer ISR 0xFFA01EC0 then processor will start executing TimerISR code Solution – Blackfin has Lookup table of what value to put into PC for each interrupt than can occur Look-up table for the start of every interrupt routine is stored in EVR table Event vector register table Event (e.g interrupts) Table Why are all these “event addresses” in the EVR (ISR jump) table the same? This is the address of the “the processor does not know what to do if there is an interrupt of this sort” EXCEPTION The “don’t know what to do” “exception” service routine (ESR) • IDLE This is the assembly code While (wait till some happens) instruction VDSP Emulator puts in a “breakpoint” so for us the program stops. In real life – processor can’t “stop”, just goes into an infinite loop until “watchdog timer” resets the processor “Don’t know what to do” Exception • This exception hangs the processor – Keeps doing same instruction (doing nothing) which is safer than doing something – The developer should have provided a better ESR if had known what to do • Problem solved by using “WATCHDOG TIMER” Solution – Lookup table of what value to put into PC for each type of interrupt that occurs • Question – the start of the ISR is in the event table – How did it get there? Event (e.g interrupts) Table The start address of the ISR got into the event table HOW? • Tell (register) the processor how to handle each interrupt service routine Also we can understand what the raise( ) C++ function does – This is a special C++ instruction to allow us to test ISR Blackfin MASKS and Latches Raise( ) use “software to put a 1 into the interrupt latch register – making the processor think that a hardware interrupt has happened Event table information can be found in the Blackfin Hardware Manual What happens if the device does take away its “I’m ready” signal during an interrupt? CONTINUE AS BEFORE DO ISR yes CHECK IF AN INTERRUPT REQUEST HAS OCCURRED Interrupt Latch (Capture) Processor clock signal causes load of the latch to capture the transient interrupt Interrupt Buffer 16-bits Acknowledge done EXTERNAL HARDWARE CONTROL SIGNAL DATA READY SIGNAL Tackled today • Three ways of handling hardware requests for service • Wait till the device signals “ready” then process the data • If device 1 ready – process its data • Else If device 2 ready – process its data POLL • Interrupt – start processing the data from a “specific device NOW!