Typy výjimek
Procesor má zabudovanou podporu systémových výjimek, které jsou identifikovány čísly 1 až 15 a dále podporu externích přerušení, které implementuje výrobce mikrokontroléru. Těch může být až 240 a jsou identifikovány čísly od 16 výše.
Přehled výjimek a přerušení zobrazuje tabulka 1.1.
Číslo výjimky | Typ | Adresa (offset) vektoru | Popis |
1 | Reset | 0x00000004 | Reset procesoru |
2 | NMI | 0x00000008 | Nemaskovatelné přerušení |
3 | HardFault | 0x0000000C | Obecná chybová výjimka |
4 | MemManage | 0x00000010 | Chyba přístupu k paměti |
5 | BusFault | 0x00000014 | Chyba sběrnice |
6 | UsageFault | 0x00000018 | Chyba prováděného kódu |
7 - 10 | Reserved | - | Rezervováno |
11 | SVCall | 0x0000002C | Supervisor call |
12 | Debug monitor | - | Rezervováno pro ladění |
13 | Reserved | - | Rezervováno |
14 | PendSV | 0x00000038 | Pendable service call |
15 | SysTick | 0x0000003C | Systémový časovač |
Číslo aktuálně prováděné výjimky je dostupná ve speciálním registru IPSR. Adresa (offset) je místo v paměti (vektor přerušení), na kterém je uložena adresa vstupního bodu rutiny obsluhy přerušení. Vektory pro externí přerušení začínají od adresy (offsetu) 0x00000040 a výjimky jsou číslovány od hodnoty 16. Adresa následujícího vektoru přerušení je vždy o čtyři vyšší než adresa předchozí. Externích přerušení může být až 240 a jsou číslována od nuly. Přiřazení čísla přerušení a tím i čísla výjimky ke konkrétní periferii určuje výrobce daného mikrokontroléru a je specifikováno v datasheetu produktu. Příklad přiřazení přerušení konkrétních periferií ukazuje tabulka 1.2.
Priorita je u prvních tří výjimek pevně dána, u všech dalších může být dynamicky změněna. Čím je hodnota priority nižší, tím má přerušení vyšší důležitost. Výjimky s pevně danou prioritou mají přidělené následující hodnoty priorit:
- Reset má prioritu (-3)
- NMI má prioritu (-2)
- Hard Fault má prioritu (-1)
Obsluha přerušení může být přerušena pouze výjimkou, která má vyšší prioritu. Pokud mají dvě výjimky nastavenou stejnou úroveň priority, přednost při vykonávání má přerušení s nižším číslem výjimky. Když dojde k požadavku na obsluhu výjimky a ta nemůže být právě obsloužena, protože je například prováděna obsluha přerušení s vyšší prioritou, zůstane výjimka v nevyřízeném stavu (pending), dokud nemůže být obsluha výjimky zahájena. Každá výjimka může být právě v jednom ze čtyř stavů:
- Inactive (neaktivní) - výjimka není ani aktivní ani čekající na obsloužení
- Pending (nevyřízená) - výjimka čeká na obsloužení procesorem
- Active (aktivní) - výjimka je právě zpracovávána
- Active and pending (aktivní a nevyřízená) - výjimka je právě zpracovávána a současně stejný zdroj přerušení čeká na obsluhu
Systémové výjimky
Chybové výjimky jsou systémové výjimky, které jsou určeny pro ošetření chybových stavů procesoru.
- HardFault je obecná chybová výjimka, která je generována, pokud dojde k chybovému stavu, který nelze ošetřit žádnou z ostatních výjimek. Výjimka je generována například pokud není povolena obsluha některé z výjimek MemManage, BusFault nebo UsageFault a při provádění kódu dojde k dané chybě.
- MemManage je chyba přístupu k paměti. Vzniká například pokud se uživatelský program snaží přistupovat k regionům paměti, které jsou chráněny nastavením MPU (Memory protection unit) nebo při pokusu o zápis do oblasti, která je pouze pro čtení.
- BusFault je chyba sběrnice a je generována například při pokusu o přístup k paměti, kerá není fyzicky osazena nebo pokud řadič paměti není správně nakonfigurován.
- UsageFault může mít příčinu například v použití chybné instrukce, pokusu o přepnutí do ARM stavu (Cortex-M3 pracuje pouze ve stavu Thumb) nebo třeba pokud register LR při návratu z přerušení obsahuje nekorektní hodnotu.
Chybové výjimky MemManage, BusFault a UsageFault lze povolit v NVIC registru System Handler Control and State Register, jehož adresa je 0xE000ED24. Vedle příznaků povolení chybových výjimek tento registr také obsahuje příznaky jejich aktivity a příznaky nevyřízeného (pending) stavu.
Výjimka typu SVCall je generována při provedení instrukce SVC (Supervisor call). Tato instrukce se používá při volání služeb jádra operačního systému, aby bylo možné oddělit kód s privilegovaným přístupem od uživatelského kódu.