Si të konfiguroni telefonat inteligjentë dhe PC. Portali informativ

Ndërprerje dhe raste të veçanta. Ndërprerja e shembujve

Mekanizmi i përparësisë (PM) tregon se cilat pajisje duhet të servisohen më parë. MP zgjidh detyrat e mëposhtme:

    Rregullon prioritetin e çdo programi të ekzekutuar nga procesori.

    Identifikon RFP-në nga VU me prioritetin më të lartë.

    Lejon që programi të ndërpritet kur ndodh një kërkesë me prioritet të lartë.

Ndërprerja e rutinës së shërbimit të ndërprerjes quhet ndërprerje e mbivendosur.

Oriz. 6.4 Një shembull i punës së CPU-së në modalitetin e ndërprerjeve të ndërlidhura.

Figura 6.4 tregon një shembull të një ndërprerjeje të ndërthurur:

    Përpara t 1 pa rrogë

    t 1 → RFP nga VU4

    t 2 → RFP nga VU3

    t 3 → RFP nga VU2

    t 4 → ka përfunduar mirëmbajtja e VU2

    t 5 → RFP nga VU1

    t 6 → ka përfunduar mirëmbajtja e VU1

    t 7 → mirëmbajtja e përfunduar e VU3

    t 8 → Mirëmbajtja e VU4 ka përfunduar

Disavantazhi: Me një frekuencë të lartë të marrjes së pagës, CPU nuk funksionon në mënyrë efikase, sepse shumë kohë CPU shpenzohet në ZP, duke rivendosur regjistrat e procesorit, duke lëvizur nga një program në tjetrin.

Ju mund të zvogëloni frekuencën e ZP duke ndezur memorien e tamponit.

Gjatë caktimit të prioriteteve për VU-në, merren parasysh kushtet e mëposhtme:

    Sa më e shpejtë të jetë pajisja, aq më i lartë i jepet përparësi.

    Prioriteti më i lartë i caktohet pajisjes nga e cila të dhënat nuk mund të rikuperohen (zakonisht një kohëmatës).

    Në familjen e kompjuterëve Macintosh prioriteti i programit tregohet në fjalën e dytë të VI.

    Në familjen e kompjuterëve IBMPC prioriteti i programit caktohet duke përdorur një LSI të veçantë (qark i madh i integruar) - një kontrollues ndërprerës i programueshëm.

Zbatimi teknik i ndërprerjeve të vektorit prioritar të mbivendosur në shumë nivele në një kompjuter të bazuar në një kanal të vetëm të shkëmbimit të të dhënave.

Zbatimi i VI-ve me shumë nivele në kompjuterët e familjesIBM .

Për zbatimin e VI shumënivelësh në një kompjuter të familjes IBM aplikuar LSI Intel 8259A.

Specifikimet bis Intel 8259a.

    Numri i niveleve të RFP = 8.

    Numri i niveleve mund të zgjerohet në 64 me anë të mikroqarqeve kaskadë

    Modaliteti i shërbimit të pagës, nivelet e përparësisë, WUA janë vendosur në mënyrë programore.

    Zbatimi teknik i ndërprerjeve të vektorit prioritar në një kompjuter me kanale të izoluara të shkëmbimit të të dhënave të trungut (familje IBMAT): mënyrat e funksionimit të kontrolluesit të ndërprerjeve të programueshme (SCP),

diagrami i lidhjes së panelit të kontrollit me autobusin e sistemit,

Skema e lidhjes së panelit të kontrollit me autobusin e sistemit VU.

Oriz. 6.7 Skema e lidhjes së panelit të kontrollit me autobusin e sistemit dhe panelin e kontrollit.

Caktimi i pinit LSI:

    D7- D0 - Daljet e motorit stepper, përdoren për të marrë informacion kontrolli nga CPU dhe për të transmetuar informacionin e statusit në CPU.

    A0 - futja e adresës, adresimi i regjistrave të brendshëm të kontrollorit (2 adresa).

    ~ Cs (çip zgjidhni) - zgjedhja e një kristali, mundëson ose çaktivizon komunikimin e kontrolluesit me autobusin e sistemit.

    • ~Cs= 0 - ka një lidhje, ~ Cs= 1 - nuk ka lidhje.

Paneli i parë i kontrollit përdor adresat - 20 h, 21 h.

Paneli i dytë i kontrollit përdor adresat - A0 h, A1 h.

    ~ RD, ~ WR- hyrja, dalja (sinjalet ShU), lidhen me linjat kryesore ~ IORdhe ~IOW.

    INT(dalje) - sinjal ZP në CPU.

    ~ INTA (ndërprerja e pranimit)- Sinjali RP nga CPU.

    CAS2, CAS1, CAS0 - autobus kaskadë. Për kontrolluesin kryesor të ndërprerjes, këto linja janë dalje, dhe për skllavin, ato janë hyrje.

    ~ PS/~ RU- tregon masterin (1) ose skllaven (0) të panelit të kontrollit.

    IR0... IR7 - hyrjet e kërkesave për ndërprerje nga VU.

përbërja funksionale dhe modeli i programit të panelit të kontrollit.

Ndërprisni- ky është një ndryshim në rendin natyror të ekzekutimit të programit, i cili shoqërohet me nevojën që sistemi t'i përgjigjet funksionimit të pajisjeve të jashtme, si dhe gabimeve dhe situatave të veçanta që u shfaqën gjatë ekzekutimit të programit. Ky quhet një program special - mbajtës i ndërprerjeve, specifike për çdo situatë të krijuar, pas ekzekutimit të së cilës rifillon funksionimi i programit të ndërprerë.

Mekanizmi i ndërprerjes sigurohet nga hardueri dhe softveri përkatës i kompjuterit.

Klasifikimi i ndërprerjeve është paraqitur në Fig. 7.1.


Oriz. 7.1.

Kërkesat për ndërprerje të harduerit lindin në mënyrë asinkrone në lidhje me funksionimin e mikroprocesorit dhe shoqërohen me funksionimin e pajisjeve të jashtme.

Kërkesë nga ndërprerje që nuk maskohen arrin në hyrje NMI mikroprocesor dhe nuk mund të kyçet nga softueri. Zakonisht ky hyrje përdoret për të kërkuar ndërprerje nga qarqet e kontrollit të energjisë ose gabime fatale në I/O.

Për pyetje ndërprerjet e maskuara përdoret hyrja INT e mikroprocesorit. Mjekimi kërkesë për ndërprerje në këtë hyrje mund të bllokohet duke pastruar bitin IF regjistri i flamurit mikroprocesor.

Softueri ndërpritet në mënyrë rigoroze quhen përjashtime ose raste të veçanta. Ato shoqërohen me situata të veçanta që lindin gjatë ekzekutimit të programit (mungesa e një faqeje në RAM, shkelje e mbrojtjes, tejmbushja), domethënë me ato situata që programuesi nuk mund t'i parashikojë, ose me praninë e një komande të veçantë INT n në program, i cili përdoret nga programuesi për të thirrur funksione të sistemit operativ ose BIOS që mbështesin punën me pajisje të jashtme. Në vijim, kur diskutojmë punën e sistemit të ndërprerjeve, do të përdorim termin e vetëm "interrupt" për ndërprerjet dhe përjashtimet e harduerit, përveç nëse specifikohet ndryshe.

Ndërprerjet e softuerit janë të llojeve të mëposhtme.

Shkelje (mohim)- një rast i veçantë që mikroprocesori mund ta zbulojë përpara se të ndodhë gabimi aktual (për shembull, mungesa e një faqeje në RAM); pas përpunimit të shkeljes, programi ekzekutohet me rinisjen e komandës që ka shkaktuar shkeljen.

Kurth- një rast i veçantë që zbulohet pas përfundimit të ekzekutimit të komandës (për shembull, prania e komandës INT n në program ose flamuri i vendosur TF në regjistri i flamurit). Pasi të jetë përpunuar ky ndërprerje, ekzekutimi i programit vazhdon me instruksionin vijues.

Përplasje(dalja nga procesi) është një gabim aq i rëndë saqë një pjesë e kontekstit të programit humbet dhe vazhdimi i tij është i pamundur. Është e pamundur të përcaktohet shkaku i aksidentit, kështu që programi hiqet nga përpunimi. Alarmet përfshijnë gabime harduerike dhe vlera të papajtueshme ose të pavlefshme në tabelat e sistemit.

Rendi i trajtimit të ndërprerjes

Ndërprerjet dhe përjashtimet njihen në kufijtë e udhëzimeve dhe programuesi mund të mos kujdeset për gjendjen e regjistrave të brendshëm të punës dhe pajisjeve të tubacionit.

Duke iu përgjigjur kërkesave për ndërprerje, mikroprocesori duhet të identifikojë burimin e tij, të mbajë kontekstin minimal të programit aktual dhe të kalojë në një program të veçantë - mbajtësin e ndërprerjeve. Pas servisimit të ndërprerjes, deputeti kthehet në programin e ndërprerë dhe ai duhet të rifillojë sikur të mos ketë pasur ndërprerje.

Përpunimi i kërkesës për ndërprerje përbëhet nga:

  • Veprimet "refleks" të procesorit, të cilat janë të njëjta për të gjitha ndërprerjet dhe rastet e veçanta dhe që programuesi nuk mund t'i kontrollojë;
  • ekzekutimi i mbajtësit të krijuar nga programuesi.

Në mënyrë që mikroprocesori të identifikojë burimin e ndërprerjes dhe të gjejë mbajtësin që korrespondon me kërkesën e marrë, çdo kërkese për ndërprerje i caktohet numri i vet ( lloji i ndërprerjes).

Lloji i ndërprerjes për ndërpritet softueri futur nga brenda mikroprocesorit; për shembull, ndërprerja e faqes jashtë kujtesës është e tipit 14. Për ndërprerjet e thirrura nga instruksioni INT n, lloji përmbahet në vetë instruksionin. Për ndërprerjet e maskuara të harduerit, lloji futet nga kontrollues i ndërprerjes prioritare në autobusin e të dhënave. Ndërprerje e pa maskuar lloji 2 i caktuar.

Në total, mikroprocesori dallon 256 llojet e ndërprerjeve... Kështu, të gjitha ato mund të kodohen në 1 bajt.

Veprimet "refleks" të mikroprocesorit në përpunim kërkesë për ndërprerje kryhen nga hardueri MP dhe përfshijnë:

  • përkufizim lloji i ndërprerjes ;
  • ruajtja e kontekstit të programit të ndërprerë (disa informacione që do t'ju lejojnë të ktheheni në programin e ndërprerë dhe të vazhdoni ekzekutimin e tij). Të paktën regjistrat ruhen gjithmonë automatikisht EIP dhe CS, duke përcaktuar pikën e kthimit në programin e ndërprerë, dhe regjistrin e flamujve EFLAGS. Nëse një mbajtës i ndërprerjeve thirret duke përdorur një portë detyrash, atëherë segmenti i gjendjes TSS i detyrës së ndërprerë ruhet plotësisht në memorie;
  • përcaktimi i adresës mbajtës i ndërprerjeve dhe transferimi i kontrollit në komandën e parë të këtij mbajtësi.

Pas kësaj, programi ekzekutohet - mbajtës i ndërprerjeve që korrespondon me kërkesën e pranuar. Ky program shkruhet dhe vendoset në memorie nga një programues aplikacioni ose sistemi. Trajtuesi i ndërprerjeve duhet të përfundojë me komandën I RET, përgjatë të cilit ndodh automatikisht kalimi në vazhdimin e programit të ndërprerë me rivendosjen e kontekstit të tij.

Për të thirrur mbajtësin e ndërprerjeve, mikroprocesorin kur punon në mënyrë reale përdor tabela e vektorit të ndërprerjeve dhe ne modaliteti i mbrojtur - tabela e përshkruesit të ndërprerjeve.


Oriz. 7.3.

Përmbajtja e regjistrit IDTr nuk ruhet në segmentet TSS dhe nuk ndryshohet kur ndërrohet detyra. Programet nuk mund të hyjnë IDT që nga e vetmja grimë e TI treguesi i tabelës v përzgjedhës segmenti ofron një zgjedhje vetëm midis tabelave Gdt dhe LDT.

Kufiri maksimal për tabelën e përshkruesit të ndërprerjeve është 256 * 8 - 1 = 2047.

Është e mundur të vendosni kufirin më të ulët, por kjo nuk rekomandohet. Nëse doreza arrihet jashtë kufijve IDT, procesori hyn në modalitetin e mbylljes derisa të marrë një sinjal në hyrje NMI ose rivendosni.

V IDT mund të ruhen vetëm përshkruesit e llojeve të mëposhtme:

  • porta e kurthit,
  • interrupt gateway, portë detyrash.

Timers roje.

Shpesh, zhurma elektrike e krijuar nga pajisjet përreth bën që mikrokontrolluesi të adresojë adresën e gabuar, pas së cilës sjellja e tij bëhet e paparashikueshme (mikrokontrolluesi është "jashtë kontrollit"). Për të monitoruar situata të tilla, kohëmatësit e rojes shpesh përfshihen në mikrokontrollues.

Kjo pajisje bën që mikrokontrolluesi të rivendoset nëse përmbajtja e tij nuk përditësohet brenda një periudhe të caktuar kohore (zakonisht nga dhjetëra milisekonda në disa sekonda). Nëse ndryshimi në përmbajtjen e numëruesit të programit nuk korrespondon me programin e specifikuar, komanda e modifikimit të kohëmatësit të mbikëqyrësit nuk do të ekzekutohet. Në këtë rast, kohëmatësi i rojes rivendos mikrokontrolluesin, duke e vendosur atë në gjendjen e tij origjinale.

Shumë zhvillues nuk përdorin kohëmatës vëzhgues në aplikacionet e tyre, pasi ata nuk e shohin nevojën për t'i përdorur ato për të luftuar efektet e zhurmës elektrike, për shembull, kur vendosin një mikrokontrollues në një ekran me rreze katodike pranë një transformatori që siguron një amortizimin e rruga e kthimit të rrezes, ose pranë bobinave të ndezjes në makinë. Në elektronikën moderne, shqetësimet elektrike nuk ka gjasa të ndodhin, megjithëse ato ndonjëherë ndodhin në situata si ato të listuara më sipër.

Nuk rekomandohet përdorimi i kohëmatësit të rojës për të maskuar problemet e softuerit. Ndërsa ky kohëmatës mund të zvogëlojë gjasat e gabimeve të softuerit, nuk ka gjasa të eliminojë të gjitha shkaqet e mundshme të gabimeve. Në vend që të mbështeteni te hardueri për të parandaluar defektet e softuerit, është më mirë ta testoni softuerin më tërësisht në situata të ndryshme.

Shumë përdorues besojnë se ndërprerjet janë një pjesë e harduerit që lihet më së miri, pasi përdorimi i tyre kërkon njohuri të shkëlqyera të procesorit për të zhvilluar një mbajtës të ndërprerjeve. Përndryshe, kur ndodh një ndërprerje, sistemi "bie në gjumë" ose "pedalon". Kjo ndjenjë zakonisht vjen tek një zhvillues pas përvojës me ndërprerje për një kompjuter personal, i cili ka një sërë veçorish që e bëjnë të vështirë krijimin e një mbajtësi të ndërprerjeve. Shumë nga këto probleme nuk ndodhin në harduerin e bazuar në mikrokontrollues. Përdorimi i ndërprerjeve në këtë pajisje mund të thjeshtojë shumë dizajnin dhe aplikimin e tij.

Nëse nuk jeni marrë kurrë me ndërprerje, atëherë lind pyetja - çfarë është ajo? Në një sistem kompjuterik, një ndërprerje është lëshimi i një nënprogrami të veçantë (i quajtur "përpunues i ndërprerjeve" ose "rutinë shërbimi i ndërprerjes") që shkaktohet nga një sinjal harduer. Gjatë ekzekutimit të kësaj nënprograme ndërpritet zbatimi i programit aktual. Termi kërkesë për ndërprerje përdoret sepse ndonjëherë programi refuzon të pranojë ndërprerjen dhe të ekzekutojë menjëherë mbajtësin e ndërprerjes (Figura 2.19).


Ndërprerjet në një sistem kompjuterik janë të ngjashme me ndërprerjet në jetën e përditshme. Një shembull klasik i një ndërprerjeje të tillë është një telefonatë gjatë shikimit të një programi televiziv. Kur bie zilja e telefonit, keni tre opsione. E para është të injoroni thirrjen. E dyta është t'i përgjigjeni telefonatës, por thoni që do të telefononi më vonë. E treta është t'i përgjigjeni thirrjes, duke shtyrë të gjitha çështjet aktuale. Sistemi kompjuterik ka gjithashtu tre përgjigje të tilla që mund të përdoren në përgjigje të një kërkese të jashtme harduerike.

Përgjigja e parë e mundshme - "mos iu përgjigj një ndërprerjeje derisa të përfundojë detyra aktuale" - zbatohet duke çaktivizuar (maskuar) shërbimin e kërkesës për ndërprerje. Pas përfundimit të detyrës, një nga dy opsionet është e mundur: rivendosja e maskës dhe aktivizimi i shërbimit, i cili do të çojë në një thirrje te mbajtësi i ndërprerjeve, ose analizimi i vlerës së biteve ("votimi"). që tregon ardhjen e kërkesave për ndërprerje dhe ekzekutimin e drejtpërdrejtë të programit të shërbimit pa thirrur mbajtësin e ndërprerjeve. Kjo metodë e trajtimit të ndërprerjeve përdoret kur kërkohet të sigurohet një kohë e caktuar ekzekutimi e programit kryesor, pasi çdo ndërprerje mund të cenojë zbatimin e ndërfaqes së kërkuar.

Oriz. 2.18 - Ekzekutimi i një ndërprerjeje.

Nuk rekomandohet maskimi afatgjatë i ndërprerjeve, pasi gjatë kësaj kohe disa ngjarje që shkaktojnë ndërprerje mund të mbivendosen dhe vetëm një do të njihet. Kohëzgjatja e lejueshme e maskimit varet nga aplikimi specifik i mikrokontrolluesit dhe nga lloji dhe shpeshtësia e ngjarjeve të tilla. Nuk rekomandohet çaktivizimi i ndërprerjeve për një kohë më të gjatë se gjysma e periudhës minimale të pritshme të sekuencës së ngjarjeve që kërkojnë ndërprerje.

Trajtuesi i ndërprerjeve siguron gjithmonë sekuencën e mëposhtme të veprimeve:

2. Rivendos kontrolluesin e ndërprerjes dhe harduerin që shkaktoi kërkesën.

3. Përpunoni të dhënat.

4. Rivendosni përmbajtjen e regjistrave të kontekstit.

5. Kthehuni te programi i ndërprerë.

Regjistrat e kontekstit janë regjistra që përcaktojnë gjendjen aktuale të ekzekutimit të programit kryesor. Zakonisht këto përfshijnë numëruesin e programit, regjistrat e statusit dhe akumulatorët. Regjistra të tjerë të procesorit, si regjistrat e indeksit, mund të përdoren gjatë përpunimit me ndërprerje, kështu që përmbajtja e tyre gjithashtu duhet të ruhet. Të gjithë regjistrat e tjerë janë specifikë për një mikrokontrollues të veçantë dhe aplikimin e tij.

Pas rivendosjes, kontrolluesi i ndërprerjes është gati të pranojë kërkesën e radhës dhe pajisja që shkakton ndërprerjen është gati të dërgojë kërkesën kur është e përshtatshme. Nëse vjen një kërkesë e re për ndërprerje, regjistri i maskimit të ndërprerjeve të procesorit do të parandalojë përpunimin e ndërprerjeve, por regjistri i statusit të ndërprerjes do ta kapë këtë kërkesë, i cili do të presë shërbimin e tij. Pas përfundimit të përpunimit të ndërprerjes aktuale, maska ​​e ndërprerjes do të pastrohet dhe kërkesa e sapo pranuar do të dërgohet për përpunim.

Ndërprerjet e ndërlidhura janë të vështira për t'u zbatuar me disa lloje mikrokontrolluesish që nuk kanë një pirg. Këto ndërprerje mund të shkaktojnë gjithashtu probleme të tejmbushjes së pirgut. Problemi i tejmbushjes është i rëndësishëm për mikrokontrolluesit për shkak të sasisë së kufizuar të memories dhe grumbullit të tyre të të dhënave: një sekuencë ndërprerjesh të ndërlidhura mund të çojë në faktin se më shumë të dhëna do të futen në pirg sesa lejohet.

Më në fund përpunohet ndërprerja. Shembulli i dytë televiziv tregon se mund t'i përgjigjeni shpejt një kërkese për ndërprerje duke pranuar të dhënat e nevojshme, të cilat më pas do të përdoren pas zgjidhjes së problemit aktual. Në mikrokontrolluesit, kjo zbatohet duke ruajtur të dhënat e marra në një grup memorie dhe më pas duke i përpunuar ato kur të përfundojë ekzekutimi i programit origjinal. Kjo mënyrë shërbimi është një kompromis i mirë midis trajtimit të menjëhershëm të ndërprerjes plotësisht, i cili mund të zgjasë shumë, dhe injorimit të ndërprerjes, i cili mund të çojë në humbjen e informacionit për ngjarjen që shkaktoi ndërprerjen.

Rivendosja e regjistrave të kontekstit dhe ekzekutimi i komandës së kthimit të ndërprerjes e kthen procesorin në gjendjen në të cilën ishte përpara se të ndodhte ndërprerja.

Konsideroni se çfarë ndodh me përmbajtjen e regjistrave të ndryshëm kur përpunohet një ndërprerje. Përmbajtja e regjistrit të statusit zakonisht ruhet automatikisht me përmbajtjen e numëruesit të softuerit përpara se të përpunohet ndërprerja. Kjo eliminon nevojën për ta ruajtur atë në mënyrë programore në memorie duke përdorur udhëzimet e transferimit dhe më pas ta rivendosni kur të ktheheni në programin origjinal. Sidoqoftë, një kursim i tillë automatik nuk zbatohet në të gjitha llojet e mikrokontrolluesve, prandaj, vëmendje e veçantë duhet t'i kushtohet organizimit të trajtimit të ndërprerjeve.

Nëse përmbajtja e regjistrit të statusit ruhet përpara se të fillojë ekzekutimi i mbajtësit të ndërprerjeve, atëherë në komandën e kthimit ai rikthehet automatikisht.

Nëse përmbajtja e regjistrave të tjerë të procesorit ndryshon kur ekzekutohet shërbimi i ndërprerjes, atëherë ai gjithashtu duhet të ruhet në memorie përpara ndryshimit dhe të rikthehet përpara se të kthehet në programin kryesor. Është praktikë e zakonshme që të ruhen të gjithë regjistrat e procesorëve për të shmangur gabimet e paparashikueshme që janë shumë të vështira për t'u lokalizuar.

Adresa që ngarkohet në numëruesin e programit kur kalon te mbajtësi i ndërprerjeve quhet "vektori i ndërprerjes". Ka disa lloje vektorësh. Adresa që ngarkohet në numëruesin e programit kur mikrokontrolluesi fillon (rivendos) quhet "vektori i rivendosjes". Vektorë të ndryshëm mund të specifikohen për ndërprerje të ndryshme, duke eliminuar nevojën që rutina e shërbimit të përcaktojë shkakun e ndërprerjes. Përdorimi i një vektori nga ndërprerje të ndryshme zakonisht nuk shkakton probleme për mikrokontrolluesit, pasi më shpesh mikrokontrolluesi ekzekuton një program të vetëm. Kështu ndryshon mikrokontrolluesi nga një kompjuter personal, gjatë funksionimit të të cilit mund të shtohen burime të ndryshme ndërprerjesh. (Nëse keni lidhur ndonjëherë dy pajisje me COM1 dhe COM3, atëherë e dini se për çfarë bëhet fjalë). Në një mikrokontrollues ku hardueri është i njohur, nuk duhet të ketë ndonjë problem në ndarjen e vektorëve të ndërprerjeve.

Gjëja e fundit që mbetet për t'u marrë parasysh janë ndërprerjet e softuerit. Ka udhëzime të procesorit që mund të përdoren për të simuluar ndërprerjet e harduerit. Përdorimi më i dukshëm i këtyre komandave është thirrja e rutinave të sistemit që ndodhen në një vendndodhje arbitrare në memorie, ose kërkojnë kërcime ndërsegmentesh për t'i aksesuar ato. Kjo veçori zbatohet në familjen e mikroprocesorëve Intel i86 dhe përdoret në sistemin bazë të hyrjes/daljes (BIOS) dhe sistemin operativ DOS të kompjuterëve personalë për të thirrur rutinat e sistemit pa pasur nevojë të rregulloni pikën e hyrjes. Në vend të kësaj, vektorë të ndryshëm të ndërprerjes përdoren për të zgjedhur instruksionin që do të ekzekutohet kur ndodh një ndërprerje e tillë e softuerit.

Ndoshta pas leximit të këtij kapitulli, mekanizmi i ndërprerjes do të bëhet më i kuptueshëm për ju, ose anasjelltas. Ju vetëm do të hutoheni më shumë. Përshkrimi i secilit mikrokontrollues do të tregojë se si përdorimi i ndërprerjeve mund të thjeshtojë aplikimin e tij.

Ekziston një situatë kur duhet të varni shumë detyra të ndryshme në një pajisje periferike, por ka vetëm një dhe diçka duhet bërë për të.

Një shembull i thjeshtë është një kohëmatës dhe ndërprerja e tejmbushjes së tij.
Mund të vendosim shpejtësinë e diafragmës dhe të ndërpresim për të bërë disa operacione. Por nëse në një moment në kohë duam që kohëmatësi i ndërprerjes të bëjë një operacion, dhe pastaj një tjetër, një të tretë. Po, aq sa duhet, në varësi të shtetit. Dhe ka vetëm një vektor.

Ose, për shembull, USART. Mund të na duhet lehtësisht të ekzekutojmë kode të ndryshme në varësi të mënyrës së ndërprerjes në mbërritjen e një bajt. Në një mënyrë - lëshimi i një përshëndetjeje, në tjetrën - dërgimi i turpshme në banjë. Në të tretën, një goditje në kokë. Dhe ka vetëm një vektor.

Sigurisht, mund të shtoni një strukturë të rastit të ndërprerës në mbajtësin e ndërprerjeve dhe, duke zgjedhur modalitetin, të shkoni në seksionin e dëshiruar të kodit, por kjo është mjaft e rëndë, dhe më e rëndësishmja, koha e tranzicionit do të jetë e ndryshme, në varësi të renditja në të cilën do të shkojë strukturat sondazhi i krahasimit të rasteve.

Kjo do të thotë, në një ndërrim të formës:

1 2 3 4 5 6 7 çelësi (x) (1: Veprimi 1 2: Veprimi 2 3: Veprimi 3 4: Veprimi 4)

çelësi (x) (1: Veprimi 1 2: Veprimi 2 3: Veprimi 3 4: Veprimi 4)

Do të ketë një krahasim sekuencial të x, fillimisht me 1, pastaj me 2, pastaj me 3, dhe kështu me radhë derisa të numërohen të gjitha opsionet. Në këtë rast, reagimi ndaj veprimit 1 do të jetë më i shpejtë se reagimi ndaj veprimit 4. Kjo është veçanërisht e rëndësishme kur llogaritni intervalet e sakta kohore në kohëmatës.

Por ekziston një zgjidhje e thjeshtë për këtë problem - një kërcim indeksi. Mjafton para se të fillojmë të presim që ndërprerja të ngarkohet paraprakisht në variablat (ose mundeni direkt në regjistrin e indeksit Z) drejtimi ku duhet të ridrejtojmë vektorin tonë dhe të fusim kërcimin e indeksit në mbajtësin e ndërprerjeve. Dhe voila! Tranzicioni do të jetë aty ku duhet, pa asnjë krahasim të opsioneve.

Në memorie, krijoni variabla për një vektor lundrues:

Timer0_Vect_L: .byte 1; Dy bajt të adresës, Timer i lartë dhe i ulët0_Vect_H: .byte 1

Përgatitja për të pritur për një ndërprerje është e thjeshtë, ne marrim dhe ngarkojmë në variablin tonë me adresën e dëshiruar

CLI; Pjesa kritike. Ndërpret OFF LDI R16, i ulët (Timer_01); Merrni adresën dhe ruani STS Timer0_Vect_L, R16; atë në një qelizë memorie. LDI R16, i lartë (Timer_01); Në mënyrë të ngjashme, por me vektorin e vjetër STS Timer0_Vect_H, R16 SEI; Ndërpret AKTIV

Kjo është e gjitha, ju mund të filloni kohëmatësin dhe të prisni për ndërprerjen tonë. Është e njëjta gjë me rastet e tjera.

Dhe mbajtësi është si ky:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 ; ===============================; Futja e një ndërprerjeje të tejmbushjes nga Timer0; ============================ TIMER_0: PUSH ZL; ruajeni regjistrin e indeksit në pirg PUSH ZH; që nga viti ne e përdorim atë PUSH R2; kurseni R2, sepse e prishim edhe ne R2, SREG; Merrni dhe ruani regjistrin e flamurit PUSH R2; Nëse nuk e bëni këtë, atëherë 100% do të merrni defekte LDS ZL, Timer0_Vect_L; ngarkoni adresën e vektorit të ri LDS ZH, Timer0_Vect_H; të dy bajtë. CLR R2; Ne pastrojmë R2 OSE R2, ZL; Kontrollimi i vektorit për zero. Përndryshe, le të kuptojmë analogun e OR R2, ZH; rivendosja "a. Kontrolli kalon përmes operacionit OSE BREQ Exit_Tm0; me akumulimin e rezultatit në R2; kështu që ne nuk e prishim përmbajtjen e Z dhe nuk kemi pse ta bëjmë; e ngarkojmë përsëri IJMP; Ne largohemi me një vektor të ri Dil nga ndërprerja Exit_Tm0: POP R2 Ne heqim dhe rivendosim regjistrin e flamurit OUT SREG, R2 POP R2; rivendosim R2 POP ZH; Rivendosim Z POP ZL RETI; Vektor shtesë 1 Timer_01: NOP; Këta janë vektorët tanë të rinj NOP; këtu mund të bëjmë çdo gjë NOP; mundësisht jo për shumë kohë - në ndërprerjen NOP; Nëse përdorim ndonjë NOP tjetër; regjistra, atëherë i ruajmë ato edhe në raft RJMP Exit_Tm0; Ky është një kalim për të dalë nga ndërprerja; i bërë posaçërisht përmes RJMP në mënyrë që; Vektor shtesë 2; ruaj dhjetë bajt në kodin e kthimit :))) Timer_02: NOP NOP NOP NOP NOP RJMP Exit_Tm0; Vektor shtesë 3 Timer_03: NOP NOP NOP NOP NOP NOP RJMP Exit_Tm0

; ===============================; Futja e një ndërprerjeje të tejmbushjes nga Timer0; ============================ TIMER_0: PUSH ZL; ruajeni regjistrin e indeksit në pirg PUSH ZH; që nga viti ne e përdorim atë PUSH R2; kurseni R2, sepse e prishim edhe ne R2, SREG; Merrni dhe ruani regjistrin e flamurit PUSH R2; Nëse nuk e bëni këtë, atëherë 100% do të merrni defekte LDS ZL, Timer0_Vect_L; ngarkoni adresën e vektorit të ri LDS ZH, Timer0_Vect_H; të dy bajtë. CLR R2; Ne pastrojmë R2 OSE R2, ZL; Kontrollimi i vektorit për zero. Përndryshe, le të kuptojmë analogun e OR R2, ZH; rivendosja "a. Kontrolli kalon përmes operacionit OSE BREQ Exit_Tm0; me akumulimin e rezultatit në R2; kështu që ne nuk e prishim përmbajtjen e Z dhe nuk kemi pse ta bëjmë; e ngarkojmë përsëri IJMP; Ne largohemi me një vektor të ri Dil nga ndërprerja Exit_Tm0: POP R2 Ne heqim dhe rivendosim regjistrin e flamurit OUT SREG, R2 POP R2; rivendosim R2 POP ZH; Rivendosim Z POP ZL RETI; Vektor shtesë 1 Timer_01: NOP; Këta janë vektorët tanë të rinj NOP; këtu mund të bëjmë çdo gjë NOP; mundësisht jo për shumë kohë - në ndërprerjen NOP; Nëse përdorim ndonjë NOP tjetër; regjistra, atëherë i ruajmë ato edhe në raft RJMP Exit_Tm0; Ky është një kalim për të dalë nga ndërprerja; i bërë posaçërisht përmes RJMP në mënyrë që; Vektor shtesë 2; ruaj dhjetë bajt në kodin e kthimit :))) Timer_02: NOP NOP NOP NOP NOP RJMP Exit_Tm0; Vektor shtesë 3 Timer_03: NOP NOP NOP NOP NOP NOP RJMP Exit_Tm0

Zbatimi për RTOS
Por, çka nëse programi ynë është ndërtuar në atë mënyrë që i gjithë kodi të rrotullohet nëpër zinxhirët e detyrave përmes menaxherit RTOS? Është shumë e vështirë të llogaritësh në kokën tënde se si kryhen këto zinxhirë në raport me njëri-tjetrin. Dhe secili prej tyre mund të përpiqet të marrë në zotërim kohëmatësin (sigurisht, jo në mënyrë arbitrare, nga paraqitja jonë, ne po shkruajmë programin, por do të jetë e vështirë të gjurmosh në kohë se sa e vështirë do të jetë gjithçka).
Në akset kryesore moderne, ekziston një mekanizëm i përjashtimit të ndërsjellë për këtë rast - mutex. ato. është një lloj flamuri i zënë. Nëse një proces komunikon, për shembull, me një UART, atëherë një proces tjetër nuk guxon të ngjitë një bajt atje dhe pret me kujdes derisa procesi i parë të lëshojë UART, i cili do të tregohet nga një flamur.

Në rastin tim, nuk ka mekanizma të përjashtimit të ndërsjellë, por ato mund të zbatohen. Të paktën të bëjë një pamje minimale. Unë nuk dua të bëj një implementim të plotë të gjithë kësaj junk, sepse Qëllimi im është të mbaj madhësinë e kernelit në 500-800 bajt.
Mënyra më e lehtë për të rezervuar një bajt më shumë në memorie është ndryshorja e zënë. Dhe kur një proces kap një burim, atëherë në këtë variabël ai shkruan kohën kur përafërsisht e lëshon atë. Koha shkon në tik-ta të kohëmatësit të sistemit, të cilin e kam 1ms.
Nëse ndonjë proces tjetër përpiqet të aksesojë të njëjtin burim harduer, ai së pari do të shikojë gjendjen e punës së tij, do të numërojë kohën gjatë së cilës do të jetë i zënë dhe do të lihet të pijë duhan për këtë periudhë - do të ngarkohet në radhën e kohëmatësit. Atje ai do të kontrollojë përsëri dhe kështu me radhë. Ky është opsioni më i thjeshtë.

Problemi këtu është se nëse ka shumë njerëz të interesuar për një vektor, atëherë proceset do të vazhdojnë të ecin vërdallë, si një rini që tundet rreth tualetit të vetëm në shesh gjatë festave festive. Fshikëza e dikujt nuk do ta durojë - algoritmi do të prishë. Dhe kush ka fiq këtu mund ta merrni me mend, tk. do të jetë e vështirë të simulohet.

Zgjidhja e problemit është shtimi i një zinxhiri tjetër të rregullt, këtë herë për akses në burim. Që të mos rrijë fare kot. ato. njëri u hodh jashtë, pastaj një i dyti, një i tretë, e kështu me radhë derisa të gjitha proceset të lehtësojnë nevojën e tyre për një lloj USART.
Disavantazhi është i dukshëm - një radhë tjetër është memorie shtesë, kod shtesë, kohë shtesë. Ju, sigurisht, mund të jeni të çoroditur dhe të vendosni kodin e dispeçerit të zinxhirit kryesor në radhë në vektor. Por këtu duhet të korrigjoni me kujdes gjithçka, sepse do të thirret në ndërprerje! Po, dhe e rëndë, kërkohet vetëm kur kemi shumë aplikantë.

Zgjidhja e dytë është të hidhni poshtë variablin e kohës së zënë, duke lënë vetëm flamurin Busy! Dhe procesi që po përpiqet të kontaktojë nuk ikën për të pirë duhan, por hidhet pas disa hapa - deri në fund të radhës së detyrës dhe menjëherë shpërthen përsëri. Njerëzit përreth tualetit nuk vrapojnë përreth, por shtyjnë bërrylat në hyrje sipas parimit se kush kalon i pari.
Një tjetër pengesë është një ngarkesë e madhe në tubacionin kryesor, një sërë kërkesash për radhitje kaq të shpejta rriten në të gjithë RAM-in dhe plotësojnë pirgun, dhe kjo është e mbushur me një apokalips global.

Sigurisht, kohëmatësi këtu është dhënë si shembull, shumica e detyrave mund të zgjidhen me kohëmatësin e sistemit RTOS, por nëse papritur ju nevojitet më pak diskrete ose një shkallë e lartë reagimi ndaj një ngjarjeje (dhe jo ndërsa tubacioni kryesor e zvarrit detyrën deri në ekzekutim), më pas mekanizmi i ndërprerjeve të kontrolluara, IMHO, pastaj që i ka përshkruar mjeku.

Artikujt kryesorë të lidhur