Po małej dyskusji oraz przejrzeniu Cortex ™-M3 TechnicalReference Manual, Revision: r1p1, nasuwa się takie ciekawe pytanie. Wiadomo, że zewnętrzne przerwania od układów peryferyjnych są podłączane pod odpowiednie linie IRQ_n, w tym przypadku mamy numery od 0-239, czyli IRQ0-239. Natomiast poziom priorytetów można ustalić dla wszystkich przerwań od 0 do 255 w rejestrze Interrupt Priority Registers. Dla systemowych przerwań (SysTick...) mamy specjalny rejestr System Handler Priority Registers, który spełnia podobną rolę, ale z dopiskiem: System handlers are a special class of exception handler that can have their priority set to any of the priority levels. Do czego zmierzam ? Cierpliwości...
W opisie na temat rejestrach IP widniej coś takiego:
Czyli rejestry IP dotyczy wszystkich przerwań, nawet systemowych, to by się zgadzało że jest 240 sztuk IRQ dla układów peryferyjnych oraz 16 systemowych. Ciekawostką jest, że konfiguracja dla zewnętrznych przerwań zaczyna się od 0 do 239, czyli ostatnie 16 mogą należeć do systemowych.Wynika to z chociażby funkcji CMSIS NVIC_SetPriority i przykładowych wartości IRQ_n, dla przykładu STM32F1, WWDG_IRQn = 0 i tak dalej. Natomiast przerwania systemowe są zapisywane do rejestru SHP. I wszystko jest cacy, bo działa zgodnie z tabelką 5.2. Exception types. Natomiast podejrzewam, że przerwania systemowe (jeśli faktycznie dobrze zgaduje) mają zawsze w IP wartość zero, bo CMSIS je pomija, ale najlepiej w ogóle nie są tam podłączone i poziom zależy od SHP, ale z cytatu wynika że dotyczy to tylko względem reszty przerwań systemowych. Czyli zawsze będą miały wyższy priorytet niż te zewnętrzne, taka sztuczka hardware. Druga sprawa to optymalizacja sprzętu, bo taki zabieg wymaga tylko 8 32-bitowych rejestrów do podtrzymania wartości przerwań (240 IRQ + 16).
Teraz sprawa priorytetów na grupy i ich podgrupy za pomocą rejestru Application Interrupt and Reset Control Register:
Widać, że dotyczą wszystkich pól IP. Czyli całego zakresu 0-255, mimo że przerwania zewnętrzne mają zakres 0-239. Idąc tym tropem, rejestr AIRCR i pole PRIGROUP nie ma żadnego wpływu na zachowanie rejestrów SHP. A jeśli przerwania systemowe faktycznie są zaszyte w rejestrach IP, to CMSIS je sprytnie pomija. Nawet ujemne wartości w IRQ_n to potwierdzają. To mamy zawsze przerwania systemowe o większym priorytecie niż zewnętrzne (co jest logiczne), bo ich wartość w IP jest zawsze teoretycznie równa 0 (zakładając, że są tam podłączone, ciągle przypominam o 0-255 pól po 8 bitów według Reference Cortex). Natomiast w rejestrze SHP możemy uwzględnić priorytety względem przerwań systemowych, a przerwania zewnętrzne zawsze można jeszcze podzielić na grupy i odpowiednie podgrupy.
Więc teoretycznie można ustalić przerwania systemowe na równi z zwykłymi przerwaniami poza rdzeniem ? (nie wliczając tych HardFault bo one zawsze mają najwyższy priorytet i nie są typu Configurable) Jeszcze tego nie stosowałem, ale w weekend to sprawdzę, taki hacking rdzenia Cortex
Ale się zdziwię, jeśli moje domysły są prawdziwe, może ktoś to testował już ?
W opisie na temat rejestrach IP widniej coś takiego:
5.3.1. Priority levels wrote:The NVIC supports software-assigned priority levels. You can assign a priority level from 0 to 255 to an interrupt by writing to the eight-bit PRI_N field in an Interrupt Priority Register, see Interrupt Priority Registers. Hardware priority decreases with increasing interrupt number. Priority level 0 is the highest priority level, and priority level 255 is the lowest. The priority level overrides the hardware priority. For example, if you assign priority level 1 to IRQ[0] and priority level 0 to IRQ[31], then IRQ[31] has higher priority than IRQ[0].
Note
Software prioritization does not affect reset, Non-Maskable Interrupt (NMI), and hard fault. They always have higher priority than the external interrupts.
When multiple interrupts have the same priority number, the pending interrupt with the lowest interrupt number takes precedence. For example, if both IRQ[0] and IRQ[1] are priority level 1, then IRQ[0] has higher priority than IRQ[1]
Interrupt Priority Registers wrote:Use the Interrupt Priority Registers to assign a priority from 0 to 255 to each of the available interrupts. 0 is the highest priority, and 255 is the lowest.
Czyli rejestry IP dotyczy wszystkich przerwań, nawet systemowych, to by się zgadzało że jest 240 sztuk IRQ dla układów peryferyjnych oraz 16 systemowych. Ciekawostką jest, że konfiguracja dla zewnętrznych przerwań zaczyna się od 0 do 239, czyli ostatnie 16 mogą należeć do systemowych.Wynika to z chociażby funkcji CMSIS NVIC_SetPriority i przykładowych wartości IRQ_n, dla przykładu STM32F1, WWDG_IRQn = 0 i tak dalej. Natomiast przerwania systemowe są zapisywane do rejestru SHP. I wszystko jest cacy, bo działa zgodnie z tabelką 5.2. Exception types. Natomiast podejrzewam, że przerwania systemowe (jeśli faktycznie dobrze zgaduje) mają zawsze w IP wartość zero, bo CMSIS je pomija, ale najlepiej w ogóle nie są tam podłączone i poziom zależy od SHP, ale z cytatu wynika że dotyczy to tylko względem reszty przerwań systemowych. Czyli zawsze będą miały wyższy priorytet niż te zewnętrzne, taka sztuczka hardware. Druga sprawa to optymalizacja sprzętu, bo taki zabieg wymaga tylko 8 32-bitowych rejestrów do podtrzymania wartości przerwań (240 IRQ + 16).
Teraz sprawa priorytetów na grupy i ich podgrupy za pomocą rejestru Application Interrupt and Reset Control Register:
5.3.2. Priority grouping wrote:To increase priority control in systems with large numbers of interrupts, the NVIC supports priority grouping. You can use the PRIGROUP field in the Application Interrupt and Reset Control Register to split the value in every PRI_N field into a pre-emption priority field and a subpriority field.
Widać, że dotyczą wszystkich pól IP. Czyli całego zakresu 0-255, mimo że przerwania zewnętrzne mają zakres 0-239. Idąc tym tropem, rejestr AIRCR i pole PRIGROUP nie ma żadnego wpływu na zachowanie rejestrów SHP. A jeśli przerwania systemowe faktycznie są zaszyte w rejestrach IP, to CMSIS je sprytnie pomija. Nawet ujemne wartości w IRQ_n to potwierdzają. To mamy zawsze przerwania systemowe o większym priorytecie niż zewnętrzne (co jest logiczne), bo ich wartość w IP jest zawsze teoretycznie równa 0 (zakładając, że są tam podłączone, ciągle przypominam o 0-255 pól po 8 bitów według Reference Cortex). Natomiast w rejestrze SHP możemy uwzględnić priorytety względem przerwań systemowych, a przerwania zewnętrzne zawsze można jeszcze podzielić na grupy i odpowiednie podgrupy.
Więc teoretycznie można ustalić przerwania systemowe na równi z zwykłymi przerwaniami poza rdzeniem ? (nie wliczając tych HardFault bo one zawsze mają najwyższy priorytet i nie są typu Configurable) Jeszcze tego nie stosowałem, ale w weekend to sprawdzę, taki hacking rdzenia Cortex
