Sunteți pe pagina 1din 22

MICROCONTROLERE

Laboratorul nr. 3
- Întreruperile – MCBSTR7x -
I Scopul laboratorului
Scopul acestui laborator este acela de:
 a familiariza cititorul cu întreruperile nucleului ARM7TDMI;
 a prezenta extensia întreruperilor utilizând EIC (Enhanced Interrupt Controller)
de la familia STR710x;
 a prezenta întreruperile externe XTI;
 a programa şi utiliza XTI şi EIC în contextul unor aplicaţii date.

II Întreruperi
ARM7 CPU oferă 2 tipuri de întreruperi, FIQ (cererea de întrerupere rapidă)
pentru lucrul rapid, cu întrerupere de latenţă mică şi IRQ (cererea de întrerupere)
pentru mai multe întreruperi generale.
Sistemul de management al întreruperilor pentru STR71x oferă două blocuri
de management al întreruperilor: EIC şi XTI. Urmăriţi Figura II-1:

Figura II-1. Vedere asupra managementului de întreruperi. Cele două controlere pentru
generarea de întreruperi EIC şi XTI.

II.1 Timpul de întâriere (latenţa) al întreruperii


Imediat ce o cerere de întrerupere este generată (fie de la o sursa de
întrerupere externă sau de la un periferic on-chip), cererea propriu-zisă trebuie să
treacă prin trei stadii diferite, înainte ca rutina de tratare a întreruperii să poată
înceapă. Latenţa întreruperii poate fi văzută ca suma a trei contribuţii diferite:

 Latenţa datorată sincronizării etajului de intrare. Această logică poate fi


prezentă (de exemplu, etapa de sincronizare la liniile de intrare a întreruperilor
externe) sau nu (de exemplu, cererea de întrerupere on-chip), în funcţie de
sursa întreruperii. În această etapă, întârzierea poate fi zero sau 2 cicluri de
ceas.
 Latenţa datorată propriului EIC. În această etapă întîrzierea poate fi de două
cicluri de ceas.

-1-
MICROCONTROLERE

 Latenţa datorată logicii de tratare a întreruperii ARM7TDMI (de face referire la


documentaţia disponibilă pe www.arm.com).

Tabelul II-1. Latenţa întreruperii EIC (în cicluri de ceas)

II.2 Controller-ul de extensie a întreruperilor (EIC)

Controller-ul de extensie a întreruperilor (EIC) realizează tratarea hardware a


canalelor de întreruperi multiple, arbitrarea priorităţii şi vectorizarea. Oferă:

 32 canale de întrerupere mascabile care pot fi mapate la linia cererii de


întrerupere IRQ a CPU de tip ARM.
 16 niveluri de prioritate programabile pentru fiecare canal de întrerupere
mapat pe IRQ.
 Suport hardware pentru serializarea întreruperii adică întrerupere în
întrerupere (pot fi setate în serie până la 16 cereri de întrerupere), cu o stivă
hardware de serializare internă.
 2 canale de întrerupere mascabile care pot fi mapate la linia cererii de
întrerupere FIQ a CPU de tip ARM, fără prioritate şi fără vectorizare.
 La offset-ul de registru 0x18h de registru, este plasată instrucţiunea de jump
(salt) la adresa de start (definită de utilizator) a ISR pentru întreruperea cu
prioritatea cea mai mare.
 16 întreruperi externe de la blocul XTI mapate pe IRQ5.

EIC realizează următoarele operaţii, fără ajutorul software:

 Respinge/acceptă o cerere de întrerupere în conformitate cu bitul mască al


canalului respectiv,
 Compară toate cererile IRQ în aşteptare cu nivelul de prioritate curent. IRQ
este asignată la ARM7 dacă prioritatea cererii curente de întrerupere este mai
mare decât prioritatea curentă deja memorată,
 Încarcă vectorul de adresă corespunzător întreruperii IRQ celei mai prioritare
în registrul vectorului de întrerupere (0x18h),
 Salvează prioritatea întreruperii anterioare în stiva de prioritate HW oricând o
nouă IRQ este acceptată,
 Actualizează Registrul Întreruperii de Prioritate Curentă cu noi priorităţi oricând
este acceptată o nouă întrerupere.

Dacă sunt mapate mai multe surse de întreruperi la acelaşi vector de


întrerupere, software-ul trebuie să citească registrul indicator de întrerupere al
perifericelor asociate pentru a determina sursa exactă de întrerupere (a se vedea
coloana Indicatorilor de Întrerupere din Tabelul II-2)

-2-
MICROCONTROLERE

Tabelul II-2. Tabelul vectorilor de întrerupere IRQ

Două surse de întrerupere mascabile pot fi mapate pe vectorul FIQ, conform


prezentării în Tabelul II-3:

-3-
MICROCONTROLERE

Tabelul II-3. Tabelul vectorilor FIQ

Aceste surse sunt de asemenea disponibile şi ca IRQ-uri normale. În


majoritatea cazurilor, trebuie să activaţi o singură sursă FIQ în aplicaţia
dumneavoastră. Dacă veţi activa ambele surse FIQ, atunci puteţi determina sursa
întreruperii prin citirea biţilor FIQ în aşteptare din registrul EIC. Trebuie să reţineţi
faptul că FIQ nu are un mecanism de prioritate, astfel încât dacă au loc evenimente
FIQ simultane, software-ul trebuie să trateze managementul priorităţilor.

CPU de tip ARM7TDMI oferă două niveluri de întrerupere, FIQ (cererea de


întrerupere rapidă) pentru tratarea rapidă şi cu latenţă mică şi nivelul IRQ (cererea de
întrerupere) pentru majoritatea întreruperilor generale.
Tratarea hardware a canalelor de întreruperi multiple, prioritatea întreruperii şi
vectorizarea automată necesită, aşadar, un Controller de Extensie a Întreruperilor
(EIC) separat, figura II-2.

Figura II-2.Diagrama bloc a EIC

 32 canale de întrerupere ce pot fi mascate, mapate pe pinul IRQ al cererii de


întrerupere a ARM.
 16 niveluri de prioritate programabile pentru fiecare canal de întrerupere
mapat pe IRQ.
 Suport hardware pentru înlănţuirea întreruperilor (15 niveluri).
 2 canale de întrerupere ce pot fi mascate, mapate pe pinul FIQ al cererii de
întrerupere a ARM, fără prioritate sau vectorizare.

-4-
MICROCONTROLERE

II.3 Mecanismul IRQ

EIC este compus dintr-un decodor de prioritate, un automat cu stări finite şi o


stivă.

II.3.1 Decodorul de prioritate

Decodorul de prioritate reprezintă un bloc combinaţional ce calculează în mod


continuu întreruperea IRQ care aşteaptă a fi servită cu prioritate cea mai mare. Dacă
există un câştigător, acesta va actualiza EIC_IVR (registrul vectorului de întrerupere)
cu adresa rutinei de întrerupere IRQ ce a câştigat arbitrarea, setând semnalul intern
nIRQ pe 0. Semnalul intern nIRQ Ored (SAU) cu bitul de activare EIC IRQ inversat
(IRQ_EN) formează semnalul corespunzător nIRQ ce generează întreruperea pentru
ARM7TDMI®.
Fiecare canal are un câmp pe 4 biţi, SIPL (nivelul de prioritate al sursei de
întrerupere) din EIC_SIRn (registrul 0-31 al sursei de întrerupere) definind nivelul de
prioritate al canalului în domeniul cuprins între 0 (prioritatea cea mai slabă) la 15 (cea
mai mare).
În situaţia în care mai multe canale sunt adresate cu acelaşi nivel de prioritate,
o conectare internă hardware în cascadă (daisy chain - înlînţuită) fixează prioritatea
cea mai mare dintre acestea. Cu cât adresa canalului este mai mare cu atât
prioritatea este mai mare. În situaţia în care canalul 2 şi canalul 6 sunt programate cu
acelaşi nivel de prioritate, şi dacă pentru acestea apare o întrerupere în acelaşi
moment de timp, canalul 6 va fi primul servit.
În conformitate cu declararea unui canal câştigător, acesta trebuie să:
 Să fie în aşteptare (EIC_IPR0-1 – Registrul de întrerupere în aşteptare, există
32 biţi în aşteptare, unul pe fiecare canal). Pentru a fi în aşteptare, un canal
trebuie să fie activat (EIC_IPR0-1 – Registrul de activare a întreruperii, 32 biţi
în aşteptare, unul pe fiecare canal).
 Să aibă nivelul de prioritate cel mai mare, mai mare decât cel prezent
(EIC_CIPR – Registrul de întrerupere pentru prioritatea actuală) şi mai mare
decât oricare altă întrerupere în aşteptare.
 Are poziţia cea mai mare din lanţul canalului de întrerupere, dacă există mai
multe canale de întrerupere în aşteptare cu acelaşi nivel de prioritate.

Registrul EIC_CIPR oferă prioritatea rutinei de întrerupere servite curent. La


reset, EIC_CIPR este şters. În timpul unei rutine de întrerupere, prioritatea poate fi
modificată prin software de la valoarea de prioritate iniţializată şi stocată în EIC_SIRn
(registrul 0-31 al sursei de întrerupere) până la 15. Încercarea de a scrie o valoare
mai mică decât cea din EIC_SIRn nu va produce nici un efect. Cu alte cuvinte pot
mări prioritatea canalului.
Pentru funcţionarea sigură, se recomandă dezactivarea IRQ globală înainte de
modificarea EIC_CIPR, EIC_SIR sau EIC_IPR cu scopul achitării întreruperii în
aşteptare pentru a evita condiţiile de cursă (blocaje, deadlock). Mai mult, dacă
IRQ_EN este şters (eliberat) în rutină de tratare a întreruperii, bitul de aşteptare
referitor la întreruperea curentă nu trebuie şters (eliberat); în caz contrar, nu va mai fi
posibilă recuperarea stării EIC înaintea descărcării stivei EIC.

-5-
MICROCONTROLERE

II.3.2 Automatul cu stări finite

Automatul cu stării finite (FSM) prezintă 2 stări: READY (pregătit) şi WAIT


(aşteptare). Cele 2 stări corespund liniei nIRQ de la nucleul ARM7TDMI®, linia fiind
activată adică există cerere de întrerupere (WAIT) sau nu (READY). Starea lui nIRQ
poate fi mascată necondiţionat de către bitul de activare globală a EIC, IRQ_EN fiind
şters. După o resetare, FSM se va afla în starea READY (linia EIC nIRQ va fi setată
la valoare HIGH- 1 logic). Atunci când decodorul de prioritate va alege un nou
câştigător, FSM va comuta din starea READY în starea WAIT, iar linia EIC nIRQ va
fi setată la valoare LOW.
Pentru a comuta FSM înapoi în starea Ready, este obligatoriu să se citească
registrul EIC_IVR sau să se reseteze celula EIC. EIC poate fi resetat printr-un reset
total, resetând întregul dispozitiv sau prin ştergerea bitului 14 din registrul
APB2_SWRES.
Citind EIC_IVR, se va comuta întotdeauna FSM din starea WAIT în starea
READY, presupunând că FSM a fost în starea WAIT, acest lucru eliberând automat
şi linia nIRQ a EIC.
Nu există indicator care să indice starea FSM.

II.3.3 Stiva
Stiva poate conţine până la 15 evenimente, corespunzând numărului maxim
de întreruperi înlănţuite. Este utilizată pentru a salva şi restaura starea anterioară a
EIC. Datele salvate pe stivă stivă sunt EIC_CICR (Registrul Canalului Curent de
Întreruperi) şi EIC_CIPR (Registrul Priorităţii Întreruperii Curente).
Atunci când FSM se află în starea WAIT, citirea lui EIC_IVR porneşte un
indicator intern. Acesta adaugă EIC_CICR şi EIC_CIPR anterioare la stiva EIC. Acest
eveniment are loc la următorul ciclu de ceas intern, după citirea EIC_IVR. Între timp,
indicatorul (flag-ul) intern este eliberat. EIC_CICR şi EIC_CIPR sunt actualizate cu
valoarea corespunzătoare canalului citit în EIC_IVR.
Dacă EIC_IVR este citit în timp ce FSM se află în starea READY, flag-ul
(indicatorul) intern nu este pornit şi nu se realizează nici o operaţie cu stiva internă a
EIC.
O rutină de tratarea a întreruperii poate fi întreruptă printr-un eveniment de
prioritate mai mare (figura II-3). Corespunzător, numărul maxim de întreruperi
înlănţuite este 15, corespunzătoar celor 15 niveluri de prioritate, de la 1 la 15. O
întrerupere cu nivel de prioritate 0 nu poate fi executată niciodată. Pentru ca stiva să
fie plină, trebuie activate înlănţuit până la 15 întreruperi şi fiecare eveniment de
întrerupere trebuie să apară secvenţial de la nivelul de prioritate 1 până la 15.
Programul principal trebuie să aibă nivelul de prioritate 0.
Având toate sursele de întrerupere cu nivel de prioritate 0, se poate folosi
interogarea selectivă în anumite aplicaţii.

Pentru a goli stiva, bitul în aşteptare EIC corespunzător întreruperii din


registrul EIC_CICR trebuie să fie şters (eliberat). Ştergerea oricăror altor biţi nu va
goli stiva. Trebuie să aveţi grijă de a nu şterge un bit în aşteptare corespunzător unui
eveniment din stivă; în caz contrar, nu va fi posibilă golirea stivei în cazul în care se

-6-
MICROCONTROLERE

ajunge la acest pas din stivă. Atunci când stiva e golită, EIC_CICR şi EIC_CIPR sunt
stocate cu valori corespunzătoare evenimentului de întrerupere anterior.

Figura II-3. Exemplu de secvenţă de cererii de întrerupere înlănţuite (nested)

II.3.4 Vectorizarea întreruperii EIC

Atunci când ARM7TDMI acceptă cererea de întrerupere de tip IRQ, se


execută instrucţiunea de la adresa 0x18. În acest timp, registrul EIC_IVR este
actualizat cu adresa rutinei de întrerupere în aşteptare cu prioritatea cea mai mare.
Pentru a obţine avantajul maxim din mecanismul EIC, instrucţiunea de la adresa
0x18 poate încărca numărătorul de program cu adresa localizată în EIC_IVR. În
acest sens, vectorul CPU se îndreaptă direct către rutina de întrerupere corectă, fără
un supracontrol software.
Deoarece decodorul de prioritate este întotdeauna activ, arbitrarea nu este
oprită niciodată. Se poate întâmpla ca un eveniment de tip întrerupere să activeze,
starea low (joasă), linia nIRQ de şi dacă între momentul în care linia nIRQ setată low
şi operaţiala ARM7TDMI de citire EIC_IVR, apare un nou eveniment de prioritate
mai mare, atunci când va fi citit EIC_IVR acesta va avea valoarea corespunzătoare
întreruperii în aşteptare cu prioritatea cea mai mare.
Nu este obligatorie citirea EIC_IVR şi saltul direct către rutina de întrerupere
corectă citind instrucţiune la adresa 0x18. O soluţie alternativă ar consta în
ramificarea la un singur punct de întrerupere şi citirea mai târziu a registrului
EIC_IVR. Sigurele funcţii obligatorii sunt de a citi prima oară EIC_IVR o singură dată,
apoi de a elibera bitul în aşteptare corespunzător. Din punctul de vedere al EIC,
întreruperea este recunoscută atunci când este citit EIC_IVR şi este completată
atunci când bitul corespunzător în aşteptare este şters (eliberat). Din punctul de
vedere al nucleului ARM7TDMI, întreruperea este recunoscută atunci când linia
ARM7TDMI nIQR este activată în starea low şi este completată atunci când este
executată secvenţa de revenire din excepţie.
Linia EIC nIRQ este echivalentă liniei nIRQ din ARM7TDMI dar în plus este
mascată de către bitul de activare total EIC (IRQ_EN). Linia EIC nIRQ poate fi setată

-7-
MICROCONTROLERE

în starea low, dar dacă bitul de activare EIC global nu este setat, linia nIRQ din
ARM7TDMI nu va fi activată în starea low.
EIC_IPR este un registru de citire/ştergere, astfel încât scrierea unui „0” nu va
avea efect, în timp ce scrierea unui „1” va reseta bitul corespunzător. Astfel, trebuie
să existe o reţinere în folosirea instrucţiunilor citire-modificare pentru a evita alterarea
stării EIC_IPR. Majoritatea biţilor în aşteptare EIC sun legaţi de un bit în aşteptare de
la nivelul perifericului. Bitul periferic în aşteptare trebuie şters înainte de ştergerea
bitului în aşteptare din EIC. În caz contrar, bitul în aşteptare EIC va fi setat din nou,
iar rutina de întrerupere va fi executată de două ori.

II.3.5 Menţiuni EIC IRQ

Citind EIC_IVR, în timp ce FSM se află în starea READY, nu se va produce


nici un efect. Valoarea citită va fi imprevizibilă. De fapt, EIC setează adresele rutinei
IRQ ca default (implicit) la EIC_IVR.
Ca rezultat a unei procedurii proaste de programare, EIC_IVR poate avea de
asemenea o valoare imprevizibilă, în timp ce FSM este în starea WAIT. Acest caz
trebuie evident evitat, deoarece CPU, la execuţia ulterioară a unei subrutine de
întrerupere, deoarece o va executa în timp ce valoarea registrului EIC_IVR nu este
relevantă. Aceasta ar conduce la o alterare a stivei EIC, deoarece bitul în aşteptare
EIC ar putea fi resetat.
Există câteva situaţii când se poate întâmpla acest lucru:
 La micşorarea nivelului de prioritate a canalului în aşteptare din registrul
EIC_IVR la o valoare egală sau mai mică decât prioritatea curentă a
programului.
 Atunci când software-ul şterge (eliberează) câţiva biţi corespunzători
întreruperilor în aşteptare fără a lua în considerare execuţia secvenţei rutinei
de întrerupere standard (a se vedea în continuare).
În astfel de cazuri, decodorul de prioritate pierde câştigătorul, în timp ce linia
EIC nIRQ este încă activă. Numai citirea EIC_IVR va elibera linia EIC nIRQ
CPU va executa rutina de întrerupere fără a avea o valoare relevantă în
registrul EIC_IVR, şi este posibilă alterarea stivei. Dacă bitul în aşteptare
corespunzător este resetat, nu va fi posibilă executarea operaţiei de golire a stivei
EIC.
Calea normală de a procesa un eveniment de tip întrerupere este de a citi
registrul EIC_IVR o singură dată, într-o rutină de întrerupere. Înainte de a ieşi din
rutina de întrerupere, perifericul corespunzător şi bitul în aşteptare EIC trebuie să fie
eliberaţi (achitaţi). Imediat ce EIC_IVR este citit, aplicaţia software poate citi registrul
EIC_CICR, pentru a cunoaşte care rutină de întrerupere este curent în aplicare, atât
timp cât registrul EIC_IVR nu este utilizat ca pointer de rutină.
Dacă EIC_IVR nu este citit în rutina de întrerupere, linia nIRQ nu va fi
eliberată şi întreruperea va fi executată de două ori. Dacă bitul în aşteptare este deja
eliberat, stiva EIC va fi alterată deoarece nu va fi capabilă de a realiza operaţia de
golire.
În interiorul rutinei de întrerupere, nu este o problemă faptul de a elibera biţii în
aşteptare având un nivel de prioritate mai mică decât cel prezent, deoarece linia
nIRQ nu este setată low în acest caz. Poate reprezenta o problemă faptul de a
elibera un bit în aşteptare ce are nivelul de prioritate mai mare, deoarece linia EIC
nIRQ este deja setată low, iar când întreruperile sunt re-activate, stiva EIC va fi
coruptă (alterată).

-8-
MICROCONTROLERE

Eliberarea unui bit în aşteptare a unei întreruperi deja în stivă va altera sitva.
În programul principal, dacă întreruperile totale sunt dezactivate, toate sursele
de întrerupere sunt dezactivate şi toţi biţii în aşteptare sunt şterşi. Dacă nIRQ a fost
deja setată low, imediat ce întreruperile totale sunt activate, CPU execută o rutină de
întrerupere. În această situaţie, citirea EIC_IVR va avea o valoare imprevizibilă,
alterând stiva EIC.
Există o singură cale sigură de a elibera biţii în aşteptare, fără executarea
rutinei de întrerupere corespunzătoare. Aceasta ajuta la eliberarea acestora dacă se
realizează dintr-o rutină IRQ ce are un nivel de prioritate mai mare. În acest sens,
linia EIC nIRQ este garantat eliberată.
Toţi biţii în aşteptare EIC pot fi şterşi (eliberaţi), incluzând pe cei pe care
aplicaţia utilizator doreşte să îi folosească ulterior. Codul utilizator trebuie să asigure
faptul că pentru aceste întreruperi, bitul în aşteptare asociat de la periferic nu este
şters/ eliberat. În acest, biţii în aşteptare EIC corespunzători vor fi setaţi din nou.
Deoarece toţi biţii în aşteptare EIC sunt şterşi în acest moment, se garantează că
stiva EIC va fi eliberată corespunzător. O soluţie alternativă constă în asigurarea
faptului că bitul în aşteptare EIC corespunzător citirii EIC_IVR va fi şters.

II.4 Mecanismul FIQ


Comparativ cu mecanismul EIC IRQ, mecanismul EIC FIQ nu oferă nici o
vectorizare automată sau nivel de prioritate software pentru fiecare sursă de
întrerupere FIQ. Oferă un bit de activare totală a FIQ, un bit de aşteptare şi unul de
activare pentru fiecare canal FIQ.
Există câteva diferenţe între bitul global F din registrul CPSR ARM din nucleu
şi bitul de activare total FIQ din EIC. Bitul F nu poate fi modificat în modul utilizator, în
timp ce bitul activ FIQ total din EIC este întotdeauna accesibil în toate modurile. În
plus, bitul F nu modifică nivelul intern al semnalului nFIQ. Acesta doar maschează
semnalul la nivelul nucleului, în timp ce bitul FIQ global EIC acţionează la nivelul
semnalului nFIQ. Semnalul nFIQ este întotdeauna inactiv imediat ce bitul de activare
globală EIC FIQ este resetat şi este activ imediat ce bitul de activare globală EIC FIQ
este setat împreună cu cel puţin un bit de aşteptare FIQ.
Pentru ca o sursă a canalului FIQ să fie în aşteptare, bitul de activare FIQ
corespunzător trebuie să fie setat. Ştergerea bitului de activare a canalului FIQ, în
timp ce bitul în aşteptare corespunzător este setat, nu va elibera canalul în aşteptare
şi canalul va rămâne activ până ce va fi şters (eliberat) bitul de aşteptare.
Pentru ca CPU să realizeze vectorizarea la adresa 0x1C (adresa vectorului
excepţie FIQ), bitul F şi bitul de activare EIC FIQ trebuie sa fie activaţi şi cel puţin un
singur bit de aşteptare FIQ trebuie să fie activ. În caz contrar, CPU nu va activa
rutina de excepţie FIQ.

III Descrierea registrelor


În această secţiune, sunt utilizate următoarele abrevieri:

- software-ul poate citi şi scrie aceşti biţi

-9-
MICROCONTROLERE

- software-ul poate doar citi aceşti biţi


- software-ul poate citi, cât şi reseta acest bit prin scrierea unui „1”. Scriind „0”,
nu se va produce nici un efect asupra valorii bitului.

III.1 Registrul de control al întreruperii (EIC_ICR)


Address Offset: 00h
Reset value: 0000 0000h

Biţi: 31:2 – Rezervaţi, întotdeauna citiţi ca 0.


- FIQ_EN: bitul de activare al ieşirii FIQ
Software-ul poate citi şi scrie acest bit.
0: controller-ul de extensie a întreruperii, cererea de ieşire FIQ către CPU este
dezactivată, chiar dacă EIC a detectat la intrările sale cereri de întrerupere valide
şi active
1: controller-ul de extensie a întreruperii, cererea de ieşire FIQ către CPU este
activată.
- IRQ_EN: bitul de activare al ieşirii IRQ
Software-ul poate citi şi scrie acest bit.
0: controller-ul de extensie a întreruperii, cererea de ieşire IRQ către CPU este
dezactivată, chiar dacă EIC a detectat la intrările sale cereri de întrerupere valide
şi active
1: controller-ul de extensie a întreruperii, cererea de ieşire IRQ către CPU este
activată.

III.2 Registrul canalului de întrerupere curent (EIC_CICR)

Address Offset: 04h


Reset value: 0000 0000h

- 10 -
MICROCONTROLERE

EIC_CICR raportează numărul canalului de întrerupere curent în lucru. Există


32 ID-uri posibile de canal (de la 0 la 31), astfel încât biţii semnificativi ai registrului
sunt doar 5 (de la 4 la 0).
După reset, valoarea EIC_CICR este setată la „0” şi este actualizată de către
EIC doar după ce procesorul a început servirea unei cereri de întrerupere valide IRQ,
de exemplu, un ciclu de ceas după citirea IVR.
Pentru a realiza acest lucru, regiştrii EIC trebuie configuraţi după cum
urmează:
 EIC_ICR IRQ_EN bit =1 (pentru a avea semnalul nIRQ la ARM7TDMI activ)
 EIC_IER0 nu sunt toţi “0” (cel puţin un canal de întrerupere trebuie activat).
 De-a lungul canalelor de întrerupere activate de către regiştrii IERx, cel puţin
unul trebuie să conţină domeniul SIPL al registrului SIR corespunzător nesetat
la 0, deoarece EIC generează o cerere de întrerupere la procesor (setarea
liniei nIRQ) DOAR DACĂ detectează o cerere de întrerupere activată, a cărei
valoare a priorităţii este mai mare decât valoarea EIC_CIPR (registrul
întreruperii de prioritate curentă).

Atunci când semnalul nIRQ la ARM7TDMI este activat, software-ul va citi


EIC_IVR (registrul vectorului de întrerupere). Acestă operaţie de citire va informa
logica EIC de faptul că ISR (rutina serviciului de întrerupere) a fost iniţiată şi că CICR
poate fi actualizat.
Valoarea EIC_CICR nu poate fi modificată prin software (citire doar a
registrului).

- rezervaţi, întotdeauna citiţi cu valoarea 0.


- CIC[4:0]: Canalul de întrerupere current
Numărul întreruperii a cărei rutină de serviciu este current în faza de execuţie.
Aceştia sunt biţi read-only.

III.3 Registrul de întrerupere de prioritate curentă (EIC_CIPR)

Address Offset: 08h


Reset value: 0000 0000h

- 11 -
MICROCONTROLERE

Registrul EIC_CIPR raportează valoarea priorităţii curente a întreruperii ce se


află curent în lucru. Există 16 valori posibile prioritare (de la 0 la 15), astfel încât biţii
semnificativi ai registrului sunt doar 4 (de la 3 la 0).
După reset, valoarea priorităţii întreruperii curente (CIP) este setată la „0” şi
este actualizată de către EIC doar după ce procesorul a început servirea unei cereri
de întrerupere IRQ valide.
Pentru a realiza acest lucru, regiştrii EIC trebuie configuraţi astfel:
 Bitul IRQ_EN din registrul EIC_ICR este setat.
 Nu toţi biţii din regiştrii EIC_IER0 trebui să fie „0” (cel puţin un canal de
întrerupere trebuie activat).
 Cel puţin unul din canalele de întrerupere, activat de registrul EIC_IER, trebuie
să aibă câmpul SIPL corespunzător registrului EIC_SPR nesetat la 0,
deoarece EIC generează o cerere de întrerupere caătre procesor (setând linia
nIRQ) doar dacă detectează o cerere de întrerupere activată, a cărei valoare a
priorităţii este mai mare decât valaorea EIC_CIPR (registrul priorităţii curente a
întreruperii).

Atunci când semnalul nIRQ al ARM7TDMI este activat, procesorul va citi


EIC_IVR. Această operaţie de citire va informa EIC de faptul că ISR a fost iniţiată şi
registrul EIC_CIPR poate fi actualizat în mod corespunzător.
Valoarea EIC_CIPR poate fi modificată prin software doar pentru promovarea
unei ISR în lucru la un nivel mai înalt şi doar în timpul unei ISR. Logica EIC va
permite scrierea câmpului CIP cu oricare altă valoare egală sau mai mare decât
valoarea prioritară asociată cu canalul de întrerupere curent servit.

De exemplu: se că presupune semnalul IRQ este setat datorită unei cereri de


întrerupere activată de canalul #4, a cărui valoare a priorităţii este 7 (de exemplu,
SIPL a lui SIR7 este 7); după ce software-ul citeşte registrul EIC_IVR, EIC va încărca
câmpul CIP cu 7. Cât timp procedura serviciului de întrerupere este activă, va fi
permisă scrierea valorilor de la 7 până la 15, în timp ce încercările de a modifica
conţinutul CIP cu prioritate mai mică decât 7 nu vor avea efect.

Software-ul utilizatorului trebuie să evite situaţia în care FSM este în starea


WAIT, iar EIC_IVR prezintă o valoare imprevizibilă.

- rezervaţi, întotdeauna citiţi cu valoarea 0.


- CIP[3:0]: Prioritatea întreruperii currentă

- 12 -
MICROCONTROLERE

Valoarea priorităţii, a cărei întrerupere este current în faza de execuţie.


Software-ul poate citi şi scrie aceşti biţi.

III.4 Registrul vectorului de întrerupere (EIC_IVR)

Address Offset: 18h


Reset value: 0000 0000h

EIC_IVR este registrul EIC pe care software-ul trebuie să îl citească după


detectarea activării semnalului nIRQ.
Operaţia de citire EIC_IVR informează EIC de faptul că a fost iniţiată rutina
serviciului de (tratare a) întrerupere (ISR) corespunzătoare unei cereri în aşteptare.
Acest lucru semnifică faptul că :
 Semnalul IRQ poate fi re-setat.
 EIC_CIPR şi EIC_CICR pot fi actualizaţi.
 cererile de întrerupere, a căror prioritate este mai mică sau egală decât cea
curentă, nu pot fi procesate.

IVR[31:16]: Vectorul de întrerupere (porţiunea înaltă)


- valoarea acestui registru nu depinde de întreruperile de servit. Trebuie
programată de utilizator (a se vedea Menţiunea) la timpul iniţializării. Este
comună tuturor canalelor de întrerupere. Software-ul poate citi şi scrie aceşti
biţi.
IVR[15:0]: Vectorul de întrerupere (porţiunea joasă)
- această valoare a registrului depinde de întreruperile ce trebuie servite (de
exemplu, una din întreruperile activate cu cea mai mare prioritate), fiind o
copie a valorii vectorului sursei de întrerupere (SIV) a lui EIC_SIR,
corespunzător canalului ce trebuie servit. Aceştia sunt biţi read-only.

Menţiune: EIC nu ţine cont de conţinutul IVR: privind din punctul de vedere al
controller-ului, este o simplă concatenare a două câmpuri de 16 biţi.

IVR = IVR(31:16) & SIRn(31:16)

- 13 -
MICROCONTROLERE

Ceea ce trebuie scris în IVR(31:16) reprezintă partea superioară a adresei


unde începe rutina serviciului de întrerupere (rutina de tratare a întreruperii). Câmpul
SIRn(31:16) va conţine cei mai puţin semnificativi 16 biţi (offset) ai adresei de
memorie legată de ISR specifică respectivului canal.

Citirea lui IVR este cunoscută doar atunci când CPU nu este în modul debug
şi codul utilizator este executat în modul ARM IRQ.

III.5 Registrul de întreruperi rapide (EIC_FIR)


Address Offset: 1Ch
Reset value: 0000 0000h

Pentru ca acest controller să poată reacţiona la 2 canale de întrerupere rapidă


(FIQ) biţii de activare 1 şi 0 trebuie să fie setaţi ca 1. Biţii 3 şi 2 indică ce canal
reprezintă sursa întreruperii.

Rezervaţi, întotdeauna citiţi ca 0.


FIP [1:0]:
0: nu există întrerupe rapidă în aşteptarea pe canalul n
1: există întrerupe rapidă în aşteptarea pe canalul n
FIE [1:0]:
0: cererea întreruperii rapide pe canalul FIQ n dezactivată
1: cererea întreruperii rapide pe canalul FIQ n activată

III.6 Registrul întreruperii active 0 (EIC_IER0)

Address Offset: 20h


Reset value: 0000 0000h

- 14 -
MICROCONTROLERE

IER[31:0]: Biţii întreruperii active pe canalele de la 31 la 0


EIC_IER0 este un registru pe 32 biţi; oferă un bit de activare pentru fiecare din cele
32 canalele de intrare EIC pentru întreruperii.
0: canalul de intrare dezactivat,
1: canalul de intrare activat.

III.7 Registrul întreruperii în aşteptare (EIC_IPR0)

Address Offset: 40h


Reset value: 0000 0000h

IPR[31:0]: Biţii întreruperii de aşteptare pe canal de la 31 la 0

EIC_IPR0 este un registru pe 32 biţi; oferă un bit pentru fiecare întrerupere în


aşteptare pentru fiecare din cele 32 canalele EIC de intrare a întreruperii.

- 15 -
MICROCONTROLERE

Aceşti biţi sunt de tip: citire/ştergere, de exemplu: scrierea unui „0” nu produce
nici un efect, în timp ce scrierea unui „1” şterge bitul.
0: nici o întrerupere în aşteptare
1: întrerupere în aşteptare.

Menţiune: Înainte de ieşirea din ISR, software-ul trebuie să şteargă bitul din
EIC_IPR0 corespunzător rutinei ISR. Această operaţie de ştergere a bitului va fi
interpretată de către EIC ca o secvenţă de sfârşit a întreruperii (EOI) şi va permite
golirea stivei de întreruperi şi procesarea de noi întreruperi.

Menţiune: Biţii de întrerupere în aşteptare trebuie să fie trataţi cu atenţie, deoarece


automatul de stare a EIC şi stiva hardware internă pentru prioritate pot fi forţate să
trecă în stări irecuperabile, în cazul în care se realizează funcţii de ştergere a bitului
de aşteptare.

Exemplul 1:
 Să presupunem că unul sau mai multe canale de întrerupere sunt activate, cu
o prioritate mai mare decât zero. Imediat ce apare o cerere de întrerupere,
EIC FSM procesează noua intrare şi setează semnalul nIRQ. Dacă înainte de
citirea EIC_IVR, din orice motiv, software-ul şterge biţii de aşteptare, semnalul
nIRQ va rămâne setat, chiar dacă nu mai sunt întreruperi în aşteptare.
Singura modalitate de a reseta logica liniei nIRQ constă în citirea registrului
EIC_IVT (0x18) sau de a trimite un reset prin software la EIC.
Exemplul 2
 Să presupunem că unul sau mai multe canale de întrerupere sunt active, cu
prioritate mai mare decât zero. Imediat ce apare o cerere de întrerupere, EIC
FSM procesează noua intrare şi setează semnalul nIRQ. Dacă după citirea
EIC_IVR, din orice motiv, software-ul eliberează biţii de aşteptare legaţi de
canalul servit înainte de completarea ISR, EIC va detecta o comandă a
sfârşitului de întrerupere, va trimite o cerere de golire la stiva de prioritate şi
va fi procesată o nouă întrerupere, chiar de prioritate mai mică. Pentru a
închide secţiunea de tratare a întreruperii (EOI), operaţia de eliberare a
întreruperii în aşteptare trebuie să fie realizată la sfârşitului lui ISR
corespunzătoare, cu bitul de aşteptare referitor la canalul servit. Pe de altă
parte, imediat ce bitul de aşteptare a canalului servit este eliberat (chiar din
greşeală) de către software, secvenţa EOI este introdusă de către EIC.

Menţiune: Pentru a şterge în siguranţă un bit de aşteptare al unei întreruperi IRQ ce


nu este curent în lucru, bitul IRQ_EN din registrul EIC_ICR ar trebuie resetat
primul. Dacă acest lucru nu este realizat, EIC FSM poate intra într-o stare
irecuperabilă. În general, în timpul programului principal, ştergerea unui unui
bit în aşteptare nu prezintă dezavantaje. Atunci când operaţia este realizată în cadrul
unei rutine IRQ, este foarte important să nu se şteargă din greşeală bitul IPR
corespunzător lui IRQ curent servit. Deoarece bitul IRQ_EN îngheaţă stiva, operaţia
de golire pentru IRQ prezent nu va fi realizată şi nu va fi posibil pe viitor să se
realizeze, atunci când IRQ-urile vor fi re-activate.

- 16 -
MICROCONTROLERE

III.8 Regiştrii sursei de întreruperi – canal n (EIC_SIRn)

Address Offset: 60h to DCh


Reset value: 0000 0000h

Există 32 regiştri diferiţi EIC_SIRn pentru fiecare canal de intrare a întreruperii.

- SIV[31:16]: vectorul sursei de întrerupere pentru canalul (n=0...31). Acest


câmp conţine partea dependentă a canalului de întrerupere din vectorul de
întrerupere ce va fi furnizat către procesor atunci când EIC_IVR (adresa 0x18)
este citită.
Depinzând de modul în care procesorul aşteaptă (adresa de 32 biţi sau
opcode, a se vedea descrierea IVR), SIV va trebui să fie încărcat cu offset-ul adresei
canalului de întrerupere sau cu partea cea mai puţin semnificativă (incluzând offset-
ul de salt) a primului opcode al instrucţiunii ISR.
- Rezervaţi, întotdeauna citiţi ca 0.
- SIPL[3:0]: nivelul de prioritate al sursei de întrerupere pentru canalul de
întrerupere (n=0...31)
Aceşti 4 biţi vor permite asocierea canalului de întrerupere la o valoare a
priorităţii între 0 şi 15. Valoarea de reset este 0.

Menţiune: Pentru a fi procesat de logica EIC, un canal de întrerupere trebuie să aibă


nivelul de prioritate mai mare decât prioritatea întreruperii curente (CIP). Valoarea
cea mai mică pe care o poate avea CIP este 0, astfel încât toate sursele de
întrerupere ce au nivelul de prioritate egal cu 0 vor genera o cerere IRQ, dacă sunt
activate corect/ corespunzător.

- 17 -
MICROCONTROLERE

III.9 Harta regiştilor EIC

Tabelul III-4. Harta regiştrilor

- 18 -
MICROCONTROLERE

IV Specificaţii de programare
Se prezintă în continuare un scurt ghid despre modul de programare a
regiştrilor EIC pentru a porni şi rula rapid aplicaţii cu întreruperi. În continuare, se
presupune că tratăm întreruperi standard şi că vrem, de exemplu, să detectăm o
întrerupere pe canalul #22, ce are prioritatea 5.
Mai întâi, trebuie să setaţi prioritatea şi adresa de salt pentru canalul de
întrerupere #22, astfel:
 Scrieţi o valoare binară „0101” în câmpul SIPL a registrului SIR22, de
exemplu: prioritate 5 (trebuie să nu fie zero pentru a permite IRQ să fie
generat).
Doi regiştri sunt utilizaţi pentru a furniza vectorul de întrerupere a canalului la
controller-ul IVR([31:16])şi SIR22([31:16]):
 Scrieţi în SIR22[31:16], de exemplu partea mai înaltă a registrului SIR
legat/referitor la canalul #22, offset-ul adresei de memorie (sau offset-ul de
salt), unde începe rutina serviciului de întrerupere, corespunzătoare canalul
de întrerupere #22.
 Introduceţi adresa de salt de bază (sau opcode-ul de salt) în jumătatea cea
mai semnificativă a registrului IVR, de exemplu IVR[31:16].

În final, trebuie să activaţi ambele întreruperi la nivelul global şi la nivelul


canalului de întrerupere. Pentru a realiza acest lucru, urmaţi paşii:
 Setaţi bitul IRQ_EN al ICR la valoarea 1.
 Setaţi bitul #22 al IER la valoarea 1.

Legat de întreruperile FIQ, deoarece aceştia nu au vectorizare sau prioritate,


sunt implicaţi doar primii doi paşi de mai sus. Presupunând că dorim să activăm
canalul FIQ #1:
 Se setează bitul FIQ_EN al ICR la valoarea 1.
 Se setează bitul #1 al FIE din registrul FIR la valoarea 1.

Notă

Fiecare rutina a serviciului de întrerupere (ISR) ar trebuie să includă


următoarele blocuri de cod.

- 19 -
MICROCONTROLERE

 O rutină header pentru a intra în ISR. Aceasta trebuie să fie:

Menţiune: r5 este un registru generic ales în acest exemplu din regiştrii disponibili r0
până la r12. Nu există posibilitatea salvării SPSR direct în stiva ARM, operaţia fiind
executată în 2 paşi, utilizând r5 ca registru temporar.

 Rutinele care implementează corpul ISR (cele de bază, principale)


 O rutină footer (secundară) pentru a ieşi din ISR. Aceasta trebuie să fie:

Următoarele 2 secţiuni oferă câteva comentarii despre codul anterior şi indicii


despre subrutinele de apelare ale ISR.

IV.1 Evitarea pierderii conţinutului lui LR_sys şi a registrului r5

Primul exemplu se referă la problema pierderii conţinutul lui LR_sys: se


presupune că o ISR fără instrucţiunea 5) din rutina header (şi corespunzător fără
instrucţiunea 1 din rutina footer) tocmai a început; se pot întâmpla următoarele:
 Se execută instrucţiunea 4) (astfel, este introdus modul sistem).
 Este apelată o subrutină cu instrucţiunea BL şi LR_sys conţine acum adresa
de return A: prima instrucţiune de subrutină ar trebui să stocheze registrul
LR_sys în stivă (adresa acestei instrucţiuni este numită B).
 O întrerupere de prioritate mai mare începe înainte înainte ca operaţia
anterioară să fie executată.
 Un nou ISR stochează adresa B în LR_irq şi introduce modul sistem.
 A nouă subrutină este apelată cu instrucţiunea BL: LR_sys este încărcată cu
noua adresă de return C (aceasta suprascrie valoarea anterioară A!) ce este
acum stocată în stivă.
 ISR cu prioritatea cea mai mare ia sfârşit şi adresa B este recuperată: acum,
valoarea LR_sys poate fi adăugată în stivă, dar valoarea sa a fost schimbată
cu adresa C (în loc de A).

- 20 -
MICROCONTROLERE

Lucrul efectuat pentru a evita astfel de situaţii periculoase constă în


introducerea liniei 5) la sfârşitul rutinei header şi corespunzător linia 1) la începutul
rutinei footer.
Motive similare ar putea conduce la coruperea registrului r5. Pentru a repara
această problemă ar trebui adăugate, liniile 3) din header şi 4) din footer.

Sugestii pentru apelarea subrutinelor din cadrul ISR

Această secţiune tratează cazurile în care o subrutină este apelată de către


un ISR.
Presupunând că acest tip de procedură începe cu o instrucţiune de tipul:

probabil se va termina cu:

În cazul în care are loc o cerere IRQ de prioritate mai mare între ultimele 2
instrucţiuni, iar noul ISR apelează altă subrutină, conţinutul LR va fi pierdut; atunci
când ultimul IRQ ia sfârşit, subrutina anterioară întreruptă nu se va întoarce la adresa
corectă.
Pentru a evita acest lucru, instrucţiunile anterioare trebuie înlocuite cu o
singură instrucţiune:

ce va muta automat registrul de legătură stocat direct în numărărtorul de rpogram


(program counter), determinând un return corect al subrutinei.

V Echipamente şi dispozitive folosite


Pentru buna desfăşurare a lucrării se vor folosi următoarele dispozitive şi resurse
software
MCBSTR7 placă de evaluare 11
Surse de alimentare 7-9V, max 190 mA 11
Versiunea de evaluare MDK-ARM 11
ULINK 1
Osciloscoape 11
Analizoare logice 11
Osciloscoapele şi analizoarele vor permite vizualizarea semnalelor prin
conectarea la header-e.

VI Teme
1. Se va studia comportamentul controlerului EIC analizând exemplul pentru XTI
(funcţionarea XTI va fi analizată în detaliu în laboratorul următor).

- 21 -
MICROCONTROLERE

2. Se vor analiza şi descrie funcţiile de bibliotecă utilizate.

Notă
Se vor pune sub tensiune echipamentele numai cu acordul cadrului didactic
îndrumător

- 22 -

S-ar putea să vă placă și