590 likes | 743 Views
Övning 7. Interrupt, Exeption, Trap. Polling och Interrupt. Antag att Du sitter i en skön fåtölj och läser en bok. Plötsligt blir Du avbruten av att telefonen ringer , Du markerar med en blyertspenna var i boken Du befann dig och svarar.
E N D
Övning 7 Interrupt, Exeption, Trap William Sandqvist william@kth.se
Polling och Interrupt Antag att Du sitter i en skön fåtölj och läser en bok. Plötsligt blir Du avbruten av att telefonen ringer, Du markerar med en blyertspenna var i boken Du befann dig och svarar. Under samtalet ringer det på dörrklockan och Du ber den Du talar med i telefonen med att dröja kvar medan Du går till dörren. William Sandqvist william@kth.se
Interrupt När Du är färdig med ärendet vid dörren återupptar Du telefonsamtalet. När Du efter ett tag har talat färdigt i telefonen och avslutat telefonsamtalet kan Du återvändatill fåtöljen och fortsätta med att läsa den goda boken - vid blyertsmärket. William Sandqvist william@kth.se
Polling Om inte interrupt funnes vore man tvungen att rusa runt mellan dörren – står någon där? – telefonen – någon där? och soffan. Det som kallas för polling. William Sandqvist william@kth.se
Interruptmekanismer Global och Local Enable Vill Du inte bli störd kan Du sätta på dig öronproppar – Du har då omöjliggjort interrupt, disable interrupt. Tar Du bort öronpropparna har Du åter möjliggjort interrupt, enable interrupt. Detta kallas för Global Enable. Du har även möjlighet på lokal nivå enabla/disabla inter-rupt, Local Enable. Du kan tex. disabla telefonen genom att dra ur jacket. Då hör Du fortfarande dörrklockan. William Sandqvist william@kth.se
Avbrottssystemet i Nios II Det normala programflödet avbryts. Tre tänkbara orsaker: Interrupt, avbrottssignal från enhet utanför processorn Exeption, felavbrott vid exekvering av instruktion division med 0 (ej med labdatorn) oimplementerad instruktion (ej med labdatorn) Trap, instruktionen trap, mjukvaruavbrott William Sandqvist william@kth.se
Återhoppsadress vid avbrott Vid avbrott sparar hårdvaran återhoppsadress i R29, EA exeption return adress register.. Register R31kan innehålla en returadress som det avbrutna programmet behöver. Måste därför sparas. William Sandqvist william@kth.se
Trap-instruktion En trap instruktion leder alltid till avbrott. Alla avbrott hanteras av samma hanteringsrutin, som i vårt labsystem ligger på adressen 0x800020. Eftersom alla avbrott hanteras av samma hanteringsrutinen måste den först av allt ta reda på vad som hänt, för att kunna göra rätt åtgärd. William Sandqvist william@kth.se
Interrupt, avbrotts-signal Ett interrupt, en avbrotts-signal, kan inträffa vid vilken instruktion som helst i programmet. Om hanteringsrutinen upptäcker att det gäller ett interrupt, så måste alla register sparas. Återhoppsadressen är en instruktion för stor, så även detta måste justeras. William Sandqvist william@kth.se
Registeranvändning i avbrottsrutinen Interrupt orsakas av händelser utanför processorn, elektriska signaler Kan hända när som helst under programkörningen Omöjligt att veta vilka register som är lediga Bara R24 får användas (et, exeption temporary) Andra register måste skyddas, sparas på stacken Använd makron PUSHMOST och POPMOST sparar respektive återställer R1…R15 samt R31 skydda även andra register om Du använder dem William Sandqvist william@kth.se
Registerhantering vid Interrupt! Vid interrupt! Skyddar Du de register Du använder. Använder Du dessutom subrutin så måste DU skydda alla dessa register! Makron PUSHMOST POPMOST Skydda! Om Du använder. William Sandqvist william@kth.se
PUSHMOST POPMOST .macro PUSH reg subi sp,sp,4 stw \reg,0(sp).endm .macro POP reg ldw \reg,0(sp) addi sp,sp,4.endm .macro PUSHMOST PUSH r1 # at PUSH r2 . . . PUSH r14 PUSH r15 PUSH r31 # ra.endm .macro POPMOST POP r31 # ra POP r15 . . . POP r3 POP r2 POP r1 # at.endm Observera! Omvänd ordning! William Sandqvist william@kth.se
Exeption, felavbrott I vårt labsystem tar vi inte hand om några felavbrott. Eftersom Nios-II-processorn är en softprocessor där användaren har möjlighet att skapa upp till 256 egna (oprövade?) instruktioner, så är felavbrott i allmänhet en nödvändig del av avbrotts-hanteringen. William Sandqvist william@kth.se
16 st Control-register Bara fyra av de 16 kontrollregistren är av intresse för oss. CTL0 status, med bit 0 PIE CTL1 estatus, med bit 0 EPIE(EPIE är sparad version av PIE) CTL3 ienable, 32 interrupt enable bits CTL4 ipending, 32 pending interrupt bits Kontrollregistren läses med instruktionen rdctl ReadControl, och skrives med instruktionen wrctl WriteControl. William Sandqvist william@kth.se
Interrupt-logiken Device Enable, Local Enable, och Global Enable William Sandqvist william@kth.se
7.1 Avbrottshanteringen Sammanfattning. Hårdvaran gör följande: Programräknarens värde kopieras till R29 (ea, exeption address register) så programmet kan hitta tillbaka. STATUS (CTL0) kopieras till ESTATUS (CTL1) så att programmet kan undersöka värdet STATUS ändras så att PIE = 0, vidare avbrott avstängda Programräknaren sätts till 0x800020, och programkörningen fortsätter därifrån. William Sandqvist william@kth.se
7.2 En ”stub” Vid avbrott styrs exekveringen till adressen 0x800020, men där finns inte plats för någon omfattande hanteringsrutin. Vi måste vidarebefordra anropet från denna adress till en annan adress i vår text-area. William Sandqvist william@kth.se
”Eftersändning” av avbrottet Vi måste placera följande ”eftersändningskod” på adress 0x800020. movia et,exc_handler # adress till hanteringsfunktionenjmp et Observera att ET, exception temporary, R21, är det enda register som får ändras vid avbrott. Först placerar vi denna kod före main (så att den aldrig körs): stub: movia et,exc_handlerjmp et Därefter får main kopiera koden från ”stub” word för word till rätt plats (0x800020). William Sandqvist william@kth.se
stub: movia et,exc_handler # körs ej, det är bara koden jmp et # vi är ute efter! main: movia r8,stub # adressen till stub-koden movia r9,0x800020 # eftersändningsadressen ldw r10,0(r8) stw r10,0(r9) ldw r10,4(r8) stw r10,4(r9) ldw r10,8(r8) stw r10,8(r9) # klart, stubben är tre instruktionermainloop: . . . # här är vårt omfattande main-program br mainloop exc_handler: . . . # här är den omfattande hanteringsfunktionen eret William Sandqvist william@kth.se
Nej! br är självrelativ, hoppet sker relativt där instruktionen står, och det fungerar ju inte om instruktionen flyttas någon annanstans! Tror Du att det skulle gå att använda br i stället för jmp ? stub: br exc_handlermain: movia r8, stub movia r9,0x800020 ldw r10,0(r8) stw r10,0(r9) stub: movia et,exc_handler # körs ej, det är bara koden jmp et # vi är ute efter! main: movia r8,stub # adressen till stub-koden movia r9,0x800020 # eftersändningsadressen ldw r10,0(r8) stw r10,0(r9) ldw r10,4(r8) stw r10,4(r9) ldw r10,8(r8) stw r10,8(r9) # klart, stubben är tre instruktionermainloop: . . . # här är vårt omfattande main-program br mainloop exc_handler: . . . # här är den omfattande hanteringsfunktionen eret William Sandqvist william@kth.se
7.3 Avbrottsrutinen Avbrottsrutinen kontrollerar orsaken Interrupt, trap (eller felavbrott) Om det var Interrupt, dvs. avbrotts-signal: subtrahera 4 från det sparade programräknarvärdet behandla avbrottet (tex. hämta indata) kvittera avbrottet (nollställ enhetens avbrotts-signal) returnera från avbrottet med instruktionen ERET William Sandqvist william@kth.se
Överblick över avbrottsrutinen William Sandqvist william@kth.se
Vad hände? Var det interrupt? Dubbeltest:Är interrupt enablat? Läs ctl1, estatus, (kopia av statusregistret) och biten EPIE (kopia av PIE). Är EPIE =0 så är interrupt inte enablat! – måste varit en Trap (eller annat). Finns väntande interrupts? Läs ctl4 ipending. Är ipending = 0 har inga interrupt skett! – måste varit en Trap (eller annat). Om vi passerar båda testen så rör det sig om ett interrupt! William Sandqvist william@kth.se
Assemblerkod, interrupt? .text .align 2exchand: rdctl et,estatus # ctl1 med bit EPIE andi et,et,0b01 # maska EPIE-biten beq et,r0,not_int # interrupt ej enablat rdctl et,ipending # ctl4 med ev väntande interrupt beq et,r0,not_int # inga väntande interrupt br exc_was_interrupt # det var ett interrupt!not_int: . . . # inget interrupt, testa mer ... William Sandqvist william@kth.se
assemblerkod, Trap? not_int: PUSH r8 movia r8,0x003b683a # detta är maskinkoden för TRAP! ldw et,-4(ea) # läs instruktionen före returadressen cmpeq et,et,r8 # jämför, 1 i et om TRAP-instruktion! POP r8 bne et,r0, exc_was_trap # det var en trap-instruktion spurious: # vi vet inte vad som hände, störning? ... eret exc_was_trap: . . . # trap-action eret William Sandqvist william@kth.se
Vilket interrupt var det? exc_was_interrupt: subi ea,ea,4 #justera returadress först som sist! rdctl et,ipending andi et,et,0b0100 bne et,r0,keys4 rdctl et,ipending andi et,et,0b01000 bne et,r0,toggles18 . . . rdctl et,ipending andi et,et,0b010000000000 bne et,r0,timer1 br spurious # inget känt avbrott ? Delrutinerna för alla de möjliga avbrotten avslutas med eret. William Sandqvist william@kth.se
Interrupt-logiken Device Enable, Local Enable, och Global Enable William Sandqvist william@kth.se
Device Enable KEYS TOGGLES Enable på Device-nivå. Varje IO-enhet har möjlighet att generera interrupt. För KEYS4 och TOGGLES18 kan man enabla varje tryck-knapp eller varje strömställare var för sig. Detta gör man genom att skriva ”1” i motsvarande bitpositioner i interrupt mask registren. Undersöka orsaken till interruptet på device-nivå. Varje förändring (trycka/släppa, byta läge) genererar interrupt. Den/de bitpositioner som förändrats, har ”1” i edge capture registren. Data registren ”1” / ”0” visar om en knapp är uppe/nere. Kvittera interruptet (acknowledge). Genom att skriva vad som helst tilledge capture registret 0-ställs bitarna. William Sandqvist william@kth.se
Device Enable TIMER • Enable på Device-nivå. Varje IO-enhet har möjlighet att generera interrupt. För TIMER1 kan man enabla interrupt vid Timeout. Detta gör man genom att skriva ”1” till ITO biten. • Undersöka orsaken till interruptet på device-nivå. TO Timeoutbiten sätts vid timeout. Kvittera interruptet (acknowledge). Genom att skriva vad som helst till status registret 0-ställs TO biten (flaggan). William Sandqvist william@kth.se
Device Enable UART • Enable på Device-nivå. Varje IO-enhet har möjlighet att generera interrupt. För UART kan man enabla interrupt för mottaget tecken, RxRdy eller för tomt i sändar-registret, TxRdy. Detta gör man genom att skriva ”1” till motsvarande bit i control registret. • Undersöka orsaken till interruptet på device-nivå. Bitarna RxRdy eller TxRdy, i status registret markerar orsaken. Kvittera interruptet (acknowledge). Genom att läsa RxData eller skriva till TxData 0-ställs respektive bitar (flaggor) i status registret. Man behöver inte göra någon ytterligare åtgärd för att kvittera interruptet. William Sandqvist william@kth.se
Local Enable Local Enable. Skriv ”1” i de positioner som skall enablas. Använd instruktionen ori eftersom man inte vill påverka andra bitpositioner oavsiktligt. rdctl et,ctl3ori et,et,0b10000011100wrctl ctl3,et William Sandqvist william@kth.se
IPENDING registret Bitarna i IPENDING registret talar om från vilket device avbrottet kommer. rdctl et,ctl4andi et,et,0b10000000000bne et,r0,TimerInt # det var timern! William Sandqvist william@kth.se
Global Enable Tillåt Globalt Enable först när alla enheter är initialiserade och allt övrigt Enablat. wrctl status,r0 # Disable interrupt PIE=0movi et,0b01 wrctl status,et # Enable interrupt PIE=1 William Sandqvist william@kth.se
timer_1 IRQ index 10 7.4 Interrupt från Timer IO är mappade till minnesadresser. 0x920 … 0x934 William Sandqvist william@kth.se
7.4 main stub: movia et,exchandler jmp etmain: movia r8,stub movia r9,0x800020 ldw r10,0(r8) stw r10,0(r9) ldw r10,4(r8) stw r10,4(r9) ldw r10,8(r8) stw r10,8(r9) # instruktionerna movia och jmp # kopieras till avbrottsadressen! William Sandqvist william@kth.se
(5.6) inittimer() Device Enable .equ timer, 0x920 .text .align 2 .global inittimer # synlig i andra filerinittimer: movia r8,timer # basadressen till timern movia r9,49999 # R9 = 49999 srli r10,r9,16 # 16 höga bitar kvar stw r10,12(r8) # periodh 16 höga bitar andi r9,r9,0xFFFF # behåll 16 låga bitar stw r9,8(r8) # periodl 16 låga bitar movi r9,0b0111 # R9 = 0b0111 (start=1 cont=1 ito=1) stw r9,4(r8) # skriv till control ret Denna gång skall vi ha interrupt vid timeout! William Sandqvist william@kth.se
Ettställ bit 10 i IENABLE (CTL3), men bara denna bit! 7.4 Lokalt Enable i main Här använder vi et i main innan interuptet blivit globalt enablat. rdctl et,ienable # ctl3ori et,et,0b010000000000wrctl ienable,et William Sandqvist william@kth.se
7.4 Globalt Enable i main Här använder vi et i main innan interuptet blivit globalt enablat. Därefter får et endast användas i avbrottsrutinen! movi et,0b01 wrctl status,et # Enable interrupt PIE=1 Ettställ PIE bit 0 i STATUS (CTL0) William Sandqvist william@kth.se
7.4 Huvudloop i main William Sandqvist william@kth.se
7.4 Avbrottsrutinen exchandler: rdctl et,estatus # för att undersöka EPIE andi et,et,1 beq et,r0,noint # interrupt är disablat rdctl et,ipending beq et,r0,noint # inga väntande interrupt inthandler: subi ea,ea,4 # glöm inte justera returadress rdctl et,ipending # vilket interrupt väntar? andi et,et,0b10000000000 bne et,r0,TimerInt # det var timern! noint: # trap-instruktionen ej med i detta exempel error: eret # spurious interrupt? William Sandqvist william@kth.se
7.4 TimerInt TimerInt: PUSHMOST # spara de flesta register movia r8,0x920 # basadress till timer1 # kvittera interruptet genom att ”skriva” # något till device status register stw r0,0(r8) # device acknowledge movia r4,mytime call tick movia r4,mytime call puttime POPMOST # återställ register eret Eftersom vi använder subrutin måste vi skydda de flesta registren med PUSHMOST/POPMOST William Sandqvist william@kth.se
7.8 Avbrott i avbrott? William Sandqvist william@kth.se
7.8 Avbrott i avbrott William Sandqvist william@kth.se
7.8 Avbrott i avbrott William Sandqvist william@kth.se
7.8 Avbrott i avbrott Om rutinen får avbryta sig själv: Spara ESTAUS och EA Kvittera det egna avbrottet (device acknowledge) Sist: ettställ PIE, Globalt Enable … Här kan rutinen bli avbruten … Nollställ PIE, Globalt Disable Återställ ESTATUS och EA ERET Om rutinen får avbrytas av andra (ej sig själv): Spara ESTAUS och EA Kvittera det egna avbrottet (device acknowledge) Förbjud det egna avbrottet i IENABLE, Lokalt Disable Sist: ettställ PIE, Globalt Enable … Här kan rutinen bli avbruten … Nollställ PIE, Globalt Disable Återställ ESTATUS och EA ERET William Sandqvist william@kth.se
7.11 Vektoriserat avbrott William Sandqvist william@kth.se
7.11 Vad gör Alteras ”Wrapper” William Sandqvist william@kth.se