View
214
Download
0
Tags:
Embed Size (px)
Citation preview
04/18/23 1
ENCM515 -- Interrupts“Review” and “C”-interrupts
M. R. Smith, Electrical and Computer Engineering
University of Calgary, Alberta, Canadasmithmr @ ucalgary,ca
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 2 / 24
To be tackled today Subroutines and Interrupts Example “C” code (68K)
subroutine assembly code interrupt service routine assembly
Example “C” code (21K) The “C” wrapper interrupts using IRQ1 button interrupts using 21K timer
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 3 / 24
Subroutines and Interrupts
Very similar in concept Very different in implementation
Subroutines occur as part of your normal program flow. You tackle a certain task, written as a subroutine, at a certain location in your code.
Time of starting plays no part in the design of a subroutine.
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 4 / 24
WAITING for an event to happen
Sometimes your code must wait for an external event to occur before the code can proceed
float array_in[200], array_out[200];main( ) {
For Ever {Wait till array_in() is filled;Process(array_in,array_out);DoRestOfCode();
} Stupid way to code -- unless this is the only thing the
processor will do
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 5 / 24
POLLING to check for events
int event1, event2, event3;float array_in[200], array_out[200];main( ) {
For Ever {if (event1 is TRUE) Process(array_in,array_out);if (event2 is TRUE) Proce????if (event3 is TRUE) Proce????DoRestofCodef();
}
Problem -- what if many events? Problem -- what if DoRestofCode() takes a long time? Problem -- what if event2 must be handled THE MOMENT it
occurs?
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 6 / 24
Solution -- Interrupts
void InterruptServiceRoutine(void);char isr_count; // Semaphore
float array_in[200], array_out[200];void main() { SetUpInterrupts(pointer to InteruptServiceRoutine() ); ActivateInterrupts(Based on event1); isr_count = 0;
while ( isr_count < 8 ) { // Totally un-exitable normally DoRestofCode();
}}
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 7 / 24
Sub-task as ISR (68K “C”)
void InterruptServiceRoutine(void);extern char isr_count; // Semaphore
#pragma interrupt() -- Signals to 68K compilerthat InterruptServiceRoutine is not a subroutine
void InterruptServiceRoutine(void);{Acknowledge Interrupt(); This is a normal subroutine call isr_count++;Process(array_in, array_out); This is a normal subroutine call
}
HOWEVER -- InterruptServiceRoutine IS NOT a normal subroutine call!!!
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 8 / 24
Subroutines are not interrupts!
Subroutines occur when the programmer wants them to occur Specific location in program code where
called Specific location in code program where
will return to Can prepare for when they will occur so
can pass parameters to them Rules are -- save non-volatile registers to
stack IF you are going to use them, otherwise use scratch (volatile) registers.
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 9 / 24
Interrupts are not subroutines
Interrupts occur when the interrupt wants to occur NO Specific location in program code where called NO Specific location in program code where will
return to Can’t prepare for when interrupts will occur so
can’t pass normal parameters to them -- need to use semaphores and messages instead
Interrupts may not want to stop Interrupts may want to use volatile registers
but subroutines are already using them!
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 10 / 24
Interrupt response must be fast
68K interrupt -- not too fast to get into Finish current instruction (8 cycles) Save next instruction address (12 cycles) Save status register (4 cycles at least) Look in “Vector Table” to find the starting address
of the ISR routine (8 cycles to fetch) Fetch the first instruction in ISR Save registers
Just as slow to get out of the interrupt service routine! Reverse of above
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 11 / 24
Interrupts on 21K -- designed to be fast
Finish current instruction (1 cycle) (but what about pipeline issues?)
Save next instruction address (hardware) Save status register???? Starting address of the ISR routine at fixed location
(0 cycles) Alternate set of registers available (sometimes) Some interrupts simply steal cycles on the bus
(DMA) and don’t cause “interrupts” as we know them!
Other issues -- Remember 3 PC’s in sequencer?
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 12 / 24
Rough Code for 68K style main( )
#define SIZE 200float buffer1[SIZE], buffer2[SIZE], buffer3[SIZE];int event1 =1, event2 = 1, event3 = 1;
main( ) { SetUpInterrupts(pointer to ISR() ); ActivateInterrupts(Based on Timer); forever {
while (event1 = = 1) /* Do nothing */ ;Process(buffer1); /* ISR is filling buffer2 at this time */while (event2 = = 1) /* Do nothing */;Process(buffer2);etc;
}
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 13 / 24
The ISR routine (68K style “C”)
int count = 0;float *whichbuff = buffer1;int *whichevent = &event1;
#pragma interrupt()void ISR(void) {
*whichbuff = ReadD2A();whichbuff++;count++;if (count = = SIZE) {
count = 0;whichbuff = buffer2;*whichevent = 0;etc;
}}
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 14 / 24
SECTION codeXDEF _ISR
_ISRMOVEM.L D0/D1/A0/A1,-(A7)
_81 BSR _ReadD2A ; *whichbuff = ReadD2A();
MOVE.L _whichbuff,-(A7)BSR __sltos
_82 ADDQ.L #4,_whichbuff ; whichbuff++;_83 ADDQ.L #1,_count ; count++;_84 CMP.L #0xC8,_count ; if (count == SIZE) {
BNE _10_85 CLR.L _count ; count = 0;_86 MOVE.L #_buffer2,_whichbuf; whichbuff = buffer2;_87 MOVE.L _whichevent,A0 ; *whichevent = 0;
CLR.L (A0)_10 MOVEM.L (A7)+,D0/D1/A0/A1
RTE
68K ISR code (defined with #pragma)
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 15 / 24
The ISR built as subroutine Unintentional Error
int count = 0;float *whichbuff = buffer1;int *whichevent = &event1;
// #pragma interrupt() --- Now becomes a subroutinevoid ISR(void) {
*whichbuff = ReadD2A();whichbuff++;count++;if (count = = SIZE) {
count = 0;whichbuff = buffer2;*whichevent = 0;etc;
}}
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 16 / 24
SECTION codeXDEF _ISR
_ISR No volatile register saves made since compiler thinks is subroutine_81 BSR _ReadD2A ; *whichbuff = ReadD2A();
MOVE.L _whichbuff,-(A7)BSR __sltos
_82 ADDQ.L #4,_whichbuff ; whichbuff++;_83 ADDQ.L #1,_count ; count++;_84 CMP.L #0xC8,_count ; if (count == SIZE) {
BNE _10_85 CLR.L _count ; count = 0;_86 MOVE.L #_buffer2,_whichbuf; whichbuff = buffer2;_87 MOVE.L _whichevent,A0 ; *whichevent = 0;
CLR.L (A0)No volatile register recovery made since compiler thinks is subroutineRTS --- HOWEVER -- WRONG THINGS ON THE STACK
68K ISR code AS A SUBROUTINE (no #pragma was used) -- BIG PROBLEMS
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 17 / 24
“C” interrupts running on 21K
We KNOW that exactly the same thing must be happening on 21K as 68K Need to set up interrupt vector equivalent Need to enable interrupts Need to do RTE equivalent
HOWEVER, EVERYTHING IS HIDDEN BY A “C” WRAPPER
Details on 21K interrupts are only needed if we want to go for “REAL SPEED”
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 18 / 24
The ISR subroutine (21K style)Only works because of hidden “C” wrapper
int count = 0;float *whichbuff = buffer1;int *whichevent = &event1;
void ISR(void) {*whichbuff = ReadD2A();whichbuff++;count++;if (count = = SIZE) {
count = 0;whichbuff = buffer2;*whichevent = 0;etc;
}}
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 19 / 24
Remember “SOMEWHERE” In the 21K “C” model, there is some TRUE ISR code
that is executed when the interrupt occurs. In that ISR Registers are saved Then your “ISR” is called as a SUBROUTINE Registers are recovered Interrupt is cleared Equivalent to RTE occurs
AND YOU KNOW NOTHING ABOUT IT (and you don’t normally care -- unless speed is important!)
And I think there is a bug in “earlier “C” wrapper -- funny code experiences and also phone messages from Alberta Users
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 20 / 24
Setting up an interrupt to occur on the 21K IRQ1 flag -- one of the buttons on the board
main( ) { asm(“include <def21060.h>”); asm(“bit set mode2 IRQ1E;”); interrupt(SIG_IRQ1, irq1_handler);
forever {while (event1 = = 1) /* Do nothing -- ISR is filling Buffer 1 */ ;Process(buffer1); /* ISR is filling buffer2 at this time */while (event2 = = 1) /* Do nothing */;Process(buffer2);etc;
}}
void irq1_handler(int sig_num) { /* This is still a subroutine */ISR( );
}
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 21 / 24
Setting up an interrupt to occur on the 21K internal Timer
main( ) { int data; interruptf(SIG_TMZ, timer_int); /* There’s intterupt, interruptf and interrupts */ data = 20000; /* Every 20000 ticks */ timer_set(data, data); /* That’s the first and reload values */ timer_on();forever {
while (event1 = = 1) /* Do nothing */ ;Process(buffer1); /* ISR is filling buffer2 at this time */while (event2 = = 1) /* Do nothing */;Process(buffer2);etc;
}}void timer_int(int sig_num) { /* This is still a subroutine */
ISR( ); /* Being used to fill a buffer -- perhaps 1 point at a time)}
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 22 / 24
Setting up the SPORTs interrupt is nasty
Have to set up the CODEC to the right values, sample rate etc
Set up the CODEC to cause interrupts on the SPORT lines
Theninterruptf(SIG_SPTOI, spt0_asserted); /*
transmit */interruptf(SIG_SPROI, spr0_asserted); /*
receive */ And everything works like magic -- Not going to
worry about the details in this lab.
04/18/23 ENCM515 -- Interrupts Review -- Part 1
Copyright [email protected] 23 / 24
Tackled today Subroutines and Interrupts Example “C” code (68K)
subroutine assembly code interrupt service routine assembly
Example “C” code (21K) The “C” wrapper interrupts using IRQ1 button interrupts using 21K timer