Skocz do zawartości

[STM32] Przerwania


slawek7

Pomocna odpowiedź

Cześć.

Mam nadzieję że mi jakoś pomożecie.

Próbuję zrozumieć mechanizm przerwań i kontroler NVIC w STM32F103..

W przykładach jak ustawiane jest zgłaszanie przerwań np przez którąś linię GPIO poprzez przerwania EXTI korxysta się ze struktury NVIC_InitTypeDef i ustawia się kanał przerwania, priorytet i inne takie.

Ale dlaczego nie robi się tego podczas ustawiania licznika SysTick?

Czy NVIC dotyczy tylko źródeł zewnętrznych, czy co?

Link do komentarza
Share on other sites

Zaczniemy od tego, że NVIC jak i SysTick są zawsze dostarczane z rdzeniem Cortex i to nie zależnie od producenta uC. Wszystkie te informacje oraz dokumentację na temat NVIC i SysTick musisz szukać na stronie ARM: infocenter.arm.com

Teraz powołując się na: NVIC register map, 8.2.2. NVIC register descriptions, masz ogólne rejestry IRQ oraz od SysTick. Dlatego jest to rozwiązane tak żeby dowolny producent uC (STMicro, NXP, Atmel) podpiął Swój ulubiony układ peryferyjny i przepisał mu przerwanie i tak pod IRQ23 załóżmy będą przerwania od UART0, które przejdą najpierw przez prosty układ kombinacyjny (bramki AND czy OR, zależnie jak jest przerwanie aktywowane, niskim lub wysokim staniem) zaimplementowanym przez producenta w tymże układzie peryferyjnym zanim dojdzie wspólny, pojedynczy sygnał do tego IRQ23. I w ten sposób przerwanie od pustego bufora czy kończąc nadawanie, NVIC to odbierze (po aktywowaniu pod IRQ23 w NVIC), wykonana co trzeba i skoczy pod adres funkcji przepisany pod IRQ23.

Dlatego, że UART zależy od implementacji producenta uC, a SysTick jest zawsze gwarantowane z rdzeniem, dlatego zamiast aktywować przerwanie pod IRQ0-255, to ma specjalny bit w osobnym rejestrze w NVIC, czyli control. Bo po co marnować przestrzeń na jeden bit w 32 bitowych rejestrach ? Jak zawsze wiadomo, że SysTick tam będzie. Druga sprawa, w SysTick można ustawić priorytet: 5.2. Exception types. External Interrupts oznacza poza rdzeniem...

Aby ułatwić producentom uC oraz użytkownikom życie, ARM stworzył CMSIS, są to wspólne funkcje dla dowolnego uC z rdzeniem Cortex. I tak żeby aktywować przerwanie lub zmienić priorytet przerwania, należy skorzystać z funkcji:

NVIC_EnableIRQ(NUMER_IRQ_PRZERWANIA)
NVIC_SetPriority(NUMER_IRQ, PRIORYTET)

Które są zawarte w core_cm3.h. Tak samo wszystko co związane z SysTick jest w tym pliku.

Teraz o filozofii SysTick. On w założeniu nie ma służyć jako timer, tylko jako systemowy timer. To oznacza, że ma współpracować z jakimś shedulerem, czyli RTOS. Najlepszym przykładem niech będzie CoOS, gdzie dzięki SysTick, rdzeniowi Cortex, można ten OS portować między różnych producentów uC bez zmiany nawet pojedynczej linijki kodu (w *.c) w tym RTOS ! Ściągasz, rozpakowujesz i używasz jak zwykłą bibliotekę, a sam SysTick zawsze będzie tak samo skonfigurowany. O to dlatego to wszystko zostało tak rozwiązane i dlaczego Cortex wymiata 😉

  • Lubię! 2
Link do komentarza
Share on other sites

Dziękuję Tobie, zaczynam jakoś to rozumieć.

Naszło mnie natomiast kilka wątpliwości. Skąd ja mam wiedzieć które układy wymagają konfiguracji z użyciem struktury NVIC_InitTypeDef a które poprzez np NVIC_SetPriority? Z opisu funkcji właśnie NVIC_SetPriority wynika że może ona służyć nie tylko do SysTick ale nawet także do EXTI, czy to prawda, a skoro tak to dlaczego jest NVIC_InitTypeDef.

Podejrzewam że jest jakiś podział na te układy które są częścią rdzenia Cortex a innymi, które konkretny producent może zaimplementować.

Po drugie jak funkcja NVIC_SetPriority ma sie do NVIC_IRQChannelPreemptionPriority?

Link do komentarza
Share on other sites

Ja osobiście używam tylko to, co dostarcza CMSIS (core_cm3.c, core_cm3.h) oraz STMicro w postaci nagłówka stm32f10x.h i nic więcej. Ta struktura NVIC_InitTypeDef, należy do biblioteki StdPeriphDriver do której mam negatywne zdanie. Wszystko co możesz zrobić w tej bibliotece (StdPeriph) z NVIC, znajdziesz to samo w CMSIS i nawet więcej. W dodatku nie tworzysz dziwnej struktury do funkcji, które marnują czas na mielenie i pamięć uC. Te funkcje co podałem wcześniej, wystarczą Tobie spokojnie do konfiguracji NVIC. Numery IRQ znajdziesz w stm32f10x.h lub podobnym (bo są jeszcze STM32F2 oraz STM32F4). Dokładnie w typedef enum IRQn. Za pomocą CMSIS i funkcji NVIC_* zrobisz wszystko, z każdym IRQ z SystTick włącznie. Nawet jest SysTick_Config, który robi co trzeba.

static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ 
 if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */

 SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
 NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */
 SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
 SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 
                  SysTick_CTRL_TICKINT_Msk   | 
                  SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
 return (0);                                                  /* Function successful */
}

Pamiętaj: CMSIS jest dobry, StdPeriph to zło w czystej postaci 😉

Podejrzewam że jest jakiś podział na te układy które są częścią rdzenia Cortex a innymi, które konkretny producent może zaimplementować.

Częścią pakietu Cortex jest: sam rdzeń 🙂, magistrale, NVIC, SysTick, DWT czy ITM. Reszta, jak RCC, UART, I2C, USB, GPIO, zależą już od producenta uC i ich przerwania są mapowane pod IRQx w NVIC.

Wybacz, ale NVIC_IRQChannelPreemptionPriority należy poza CMSIS i jest to jakiś wytwór programisty. Lepiej wziąć się za czytanie Reference Manaul, bo i tak musisz czasem do niego zajrzeć, a teraz musisz jeszcze zmarnować czas na to śmieszne API (StdPeriph).

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Tak samo jak kolega tymon_x radzę zrezygnować z tej biblioteki stma i działanie bezpośrednio na rejestrach oraz studiowanie odpowiednich rozdziałów reference manuala procesora i rdzenia. Tam wszystko jest opisane. Pomijając fakt, że ta biblioteka StdPeriphLibrary jest napisana w bardzo nieefektywny sposób, te funkcje nieraz mogą być mylące i powodować bardzo trudne do wyeliminowania błędy. Natomiast kiedy używasz rejestrów wszystko jest od razu oczywiste. Układy i rejestry pogrupowane są w odpowiednie struktury. Możesz też korzystać z definicji poszczególnych bitów.

Link do komentarza
Share on other sites

Masz rację. Ja mam jednak ten problem że jak czytam Reference Manual to im bardziej się zagłębiam tym więcej mnie nachodzi pytań na które nie mogę tam znaleźć odpowiedzi. Poza tym jest mało źródeł jest na temat tych uC.

A wracając do przerwań. Jak się ma ustawienie przerwania dla SysTick (nawet funkcją NVIC_SetPriority bo to tylko zapis do rejestru) z tym podziałem na Preemption i Sub -Priority.

Zakładając że nie korzystasz z bibliotek to powiedz jak Ty ustawiasz priorytety przerwań czy to dla układu licznikowego, czy USART'a.

Tak czytam note 0056 i teraz znowu się pogubiłem. Z góry przepraszam, może za laickie pytania, teraz to już na prawde nie wiem o co chodzi z tymi przerwaniami. Doczytałem się istnienia rejestru SCB->AIRCR potem NVIC->IP i z tego co widzę to są oddzielne priorytety dla układów peryferyjnych oraz wewnętrznych. Ale czy to prawda? Czyżby każdy znich miał osobne ustawienia?

Link do komentarza
Share on other sites

Wszystko ładnie jest wytłumaczone w 5.3.2. Priority grouping. Jeśli chcesz ustawić priorytety na grupowe i podgrupy, to najpierw musisz zmienić na odpowiedni tryb. I tak zapis do rejestru: Application Interrupt and Reset Control Register na pozycje bitów PRIGROUP spowoduje odpowiednia interpretację zawartości w polach IP (Interrupts Priority), rejestry Interrupt Priority Registers. Zawartość takiego pola to jeden bajt (8 bitów), więc w jednym rejestrze mieści się cztery takie pola, które każde odpowiada za Swój numer przynależny do IRQ. Pierwszy rejestr IP, zawiera informację na temat priorytetów IRQ0, IRQ1, IRQ2, IRQ3. Kolejne odpowiednio.

Załóżmy, że wpisałeś do Application Interrupt and Reset Control Register na pozycje PRIGROUP wartość binarną 011, to odpowiada bxxxx.yyyy w rejestrze Interrupt Priority Registers czyli masz 16 główne grupy oraz każdy z nich posiada Swoją podgrupę (16). Teraz wracając do przykładowego IRQ23, odnajdujesz jego bajt w rejestrach IP i zapisujesz odpowiednio na przykład 0011_0001, to według PRIGROUP(011) oznacza że jest IRQ23 należy do grupy 3 i w tej grupie ma numer 1. To oznacza, że każdy inny IRQx o innej wartości, będzie odpowiednio albo wywłaszczany względem grupy lub jego podgrupy, albo będzie Sobie niepodzielnie rządził 😉

Wszytko co Ci potrzebne znajdziesz w CMSIS:

NVIC_SetPriorityGrouping(3); // 011
NVIC_SetPriority(USART1_IRQn, 0x31); // 0011_0001
NVIC_EnableIRQ(USART1_IRQn);

I nic więcej, żadnych magicznych struktur, widzisz jakie to proste.NVIC_SetPriorityGrouping ustawiasz jednorazowo, gdzieś na początku programu. PERYFERIA_IRQn to są numery IRQn, znajdziesz je w stm32f10x.h (dla STM32F1x) w typedef enum IRQn.

Dla STM32F1 ściągnij Sobie dokument Cortex ™-M3 TechnicalReference Manual, Revision: r1p1, on zawiera wszystkie informacje o których pisałem wyżej. Dotyczy samego rdzenia Cortex-M3 oraz jego dodatkowych bloków jak NVIC, SysTick i tak dalej...

Link do komentarza
Share on other sites

Uwierz że czytałem to co polecasz. Mniej więcej rozumiem. Nie znalazłem tylko takiej informacji. Dlaczego ARM zrobił podział na stawianie priorytetów dla przerwań zewnętrznych i tzw. systemowych. I czy pomimo że posiadają osobne konfiguracje tych priorytetów to należny traktować je łącznie, mam na myśli np taką sytuację że dla SysTick ustawiam priorytetem np 4 a dla USART np 2 to pomimo że oba priorytety ustawiam w osobnych rejestrach to czyta się je tak że pierwszy będzie wykonywany USART a następnie SysTick?

A co z ustawieniem grupy priorytetów. Czy do tego rejestru SHP też ma zastosowanie jak do zewnętrznych przetrwań? Może pokrętnie napisałem ale chyba wiesz o co mi może chodzić.

Link do komentarza
Share on other sites

The NVIC supports up to 240 dynamically reprioritizable interrupts each with up to 256 levels of priority.

16 systemowych przerwań są zarezerwowane od tyłu (240-255) niż wskazuje to 5.2. Exception types (dlatego mają ujemne wartości w IRQn, ale to wynika z czytelności, przesunięcie o 16 pozycji w dół), reszta układów peryferyjnych podłącza się do IRQ0-239. Widać to po NVIC Register Map. I w każdym można ustawić priorytet, to samo będzie działać dla IRQ23, IRQ5, SysTick czy Usage Fault. Ale niektóre są typu fixed jak Reset, Non-maskable Interrupt, Hard Fault i zawsze będą mieć najwyższy priorytet niż ten który ustawisz dla reszty. Ustawienie grupy oraz podgrup będą obowiązywać dla wszystkich, oprócz tych trzech wymienionych. Wszystkie 256 przerwań (16 systemowych + IRQ0-239) należą do tej samej puli IP (Interrupt Priority). Tu nie ma co się zastanawiać. Na początku mogłem w błąd wprowadzić pisząc IRQ0-255, faktycznie jest IRQ0-239 + 16 systemowych i każdemu można ustawić priorytet tam, gdzie jest napisane Configurable. Dla NVIC, przerwanie od SysTick, IRQ23 czy User Fault to jest to samo. Każde to przerwanie jest tylko numerem w tablicy przerwań, bez wyjątku, nie ma żadnego podziału. I każdemu można ustawić priorytet w PRI_n w Interrupt Priority Registers. Pierwsze to 16 przerwań systemowych, następnie IRQ0-239, razem tworzą wspólną pulę 256 przerwań 😉

Te funkcje działają dla każdego przerwania tak samo, ustawienie typu priorytezacji też dotyczy wszystkich równo i bez wyjątku.

Podział na przerwania systemowe i na zewnętrzne, tam gdzie podłączają się układy peryferyjne jest już chyba logiczny ? Dla NVIC to jest to samo, po prostu przerwanie.

Link do komentarza
Share on other sites

Proszę tylko się nie denerwuj na mnie.

Patrzę na taką funkcję:

NVIC_SetPriority(...)

a w niej

if(IRQn < 0) {
   SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
 else {
   NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts  */

Z tego wynika że priorytet dla przerwań systemowych sutawiany jest w rejestrze SCB->SHP natomiast dla zewnętrznych w rejestrze NVIC->IP

To że akurat tutaj przerwania systemowe mają wartości ujemne jest dla mnie zrozumiałe. łatwiej je tu odróżnić niż liczyć do 15. i właśnie o to pytałem, dlaczego różne rejestry skoro zakres priorytetów ten sam?

  • Lubię! 1
Link do komentarza
Share on other sites

To że akurat tutaj przerwania systemowe mają wartości ujemne jest dla mnie zrozumiałe. łatwiej je tu odróżnić niż liczyć do 15. i właśnie o to pytałem, dlaczego różne rejestry skoro zakres priorytetów ten sam?

Już wiem o co chodzi. Nie dogadaliśmy się. Jedynie rozwiązanie jakie mi przychodzi to czytelność oraz optymalizacja zużytej logiki, podejrzewam że informacja o przerwaniu mieści się w jednym bicie, czyli wychodzi po 8 32-bitowych rejestrów. Od strony NVIC będzie widziane to jakie 0-255. Ten SHP dotyczy priorytezacji między systemowymi przerwaniami.

Fajny monolog powstał, bo wczytując się teraz w Reference Manual naprawdę można zgłupieć teraz. Bo według tabelki oraz 5.3.1. Priority levels to jest to samo 0-255 i ustawienie poziomu priorytetu odnosi się do wszystkich przerwań w polach PRI_n. No ale mamy jeszcze rejestry na systemowe priorytety pod innych adresach.

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.
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.

System handlers are a special class of exception handler that can have their priority set to any of the priority levels.
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.

To priorytezacja na główną grupę i podgrupy odnosi się tylko do PRI_n w Application Interrupt and Reset Control Register. Teraz to szczerze sam się zastanawiam, bo nigdy nie stosowałem priorytezacji dla systemowych przerwań, bo dla mnie powinny mieć jak największy poziom, czyli zero w tym wypadku i zależeć od położenia. Ale to jest ciekawe...

Hmm,.. zostaje tylko po prostu praktyczny test 😉 Bo ta funkcja pomija ten problem o który pytasz, ujemne wartości omijają zapis do IP i lecą do SHP. I ten rejestr jest poza działaniem AIRCR, bo tak wynika z przytoczonych cytatów. Najbardziej kluczowe zdanie to jest to: System handlers are a special class of exception handler that can have their priority set to any of the priority levels.. Czyli systemowe przerwania mają w IP zawsze będą miały 0, czyli największy możliwy priorytet niż IRQ (z racji też położenia w tablicy) i niezależnie od ustawień AIRCR. Ale można ustalić poziom priorytezacji między Sobą w rejestrze SHP. Tak wynika z dokumentacji, nigdy szczerze się tak głębiej nie zastanawiałem na tym. Muszę Tobie podziękować 😉 Czyli korzystając z CMSIS, systemowe przerwania zawsze będą miały najwyższy priorytet niż zwykłe, ale w tych zwykłych można ustawić dodatkowy grupy i pod grupy. Ale mogę się mylić 😋

Stworzyłem dodatkowy temat w tej sprawie: [Cortex] NVIC Priorytety przerwań

Link do komentarza
Share on other sites

Cześć ponownie.

Mam do Ciebie prośbę. Ponieważ tam gdzie ten dodatkowy wątek stworzyłeś po czasie on upadł chciałbym Ciebie prosić o wytłumaczenie jednej sprawy, bo jak na razie tylko to mi nie daje spokoju.

Na stronie Hitexa znalazłem wprowadzenie do STM32 i tam jest coś takiego ciekawego napisane.

There are sixteen priority registers. Each priority register is divided into four eight bit priority fields, each field

being assigned to an individual interrupt vector. The STM32 only uses half of this field to implement 16 levels of

priority. However, you should note that the active priority bits are in the upper nibble of each priority field. By

default the priority field defines 16 levels of priority with level zero the highest and 15 the lowest. It is also possible

to format the priority field into priority groups and subgroups. This does not provide extra levels of priority, but

helps management of priority levels when you have a large number of interrupts by programming the PRIGROUP

field in the Application Interrupt and Reset Control Register.

The three bit PRIGROUP field allows you to split the 4-bit priority fields into groups and subgroups. For example,

PRIGROUP value 3 creates two groups, each with four levels of priority. In your application code you can now

define a high priority group of interrupts and a low priority group. Within each group you can specify subgroup

levels of low, medium, high and very high. As mentioned above this does not provide you anything “extra” but

provides a more abstracted view of the interrupt structure which is useful to the programmer when managing a

large number of interrupts.

Wszystko się zgadza i z tym co Ty pisałeś i z pozostałymi wpisami ale to nasunęło mi pytanie, na które niestety nie potrafię doszukać się odpowiedzi. A mianowicie po co tworzyć i zajmować miejsce w rejestrach na tworzenie bitów określających grupowanie? Bo wychodzi na to że te pola PRIGROUP służą jedynie programiście aby pamiętał jaką grupę sobie utworzył. To samo można zrobić na dowolnej zmiennej np 8 bitowej a chyb anie ma problemu z miejscem w pamięci i dodatkową zmienną globalna w programie można utworzyć?

Dalej. Ponieważ priorytety określane są na 4 najstarszych bitach to wartości priorytetów wyglądają tak (od najwyższego 0,32,48,64,80,...224,240 dziesiętnie). Mając takie liczby, które nie są po kolei sprawny programista może łatwo wpisać ja tak aby w danym programie mu one odpowiadały i tak na prawdę grupowanie nie jest mu potrzebne, bo chyba odpowiednie wpisane tych liczb do rejestru priorytetów jest łatwiejsze niż nie jeden program.

Dlatego jaki cel ma ten PRIGROUP?

Link do komentarza
Share on other sites

Podsumowując całą swoją przygodę z przerwaniami w STM32 chciałbym opisać to czego ja się dowiedziałem na ten temat i może będzie to w jakimś stopniu przydatne dla Was.

Muszę zacząć od tego że w Cortexaxh-M3 są dwa główne rodzaje przerwań: przerwania systemowe do których zalicza się głównie wykorzystywany SysTick oraz przerwania zewnętrzne, czy to od portów GPIO, czy od Timerów lub SPI.

Mając dowolny układ w którym chcemy wykorzystać przerwania przed ich ustawieniem musimy odpowiedzieć sobie na pytanie jak ma wyglądać sposób ich pracy. To co najważniejsze to założenie, które przerwania są dla nas na tyle istotne, że muszą za wszelką cenę być obsłużone jako pierwsze i mogą dokonać wywłaszczania innych, czyli przerywania ich pracy, a które mogę spokojnie poczekać na swoją kolej. Nie chcę tu podawać przykładów bo możliwości jest tyle co ludzi i pomysłów więc na pewno każdy znajdzie jakiś przykład koło siebie.

Mając już taki podział przerwań możemy ustalić sobie jedną z pięciu (od 0 o 4) grup priorytetów i w zależności od tej grupy ustalamy przerwania które mogą przerywać inne. Przykładowo w grupie oznaczonej jako nr 1 mamy tylko podział na dwa przerwania grupowe, z tym że oznaczając np IRQ1 jako 0 a IRQ2 jako 1 powodujemy iż IRQ1 zawsze będzie wykonywane jako pierwsze i ma pierwszeństwo nad pozostałymi. Aby jeszcze sobie ułatwić bądź utrudnić życie w zależności jak na to patrzymy możemy stworzyć 8 poziomów przerwań tzw. sub, które nie powodują przerwania innych tylko czkają na swoją kolej. Przykładowo jak ustawimy przerwaniu IRQ3 priorytet na 5 a przerwaniu IRQ4 na 3 to przychodzące przerwania stworzą jakby kolejkę i jeśli zgłoszenie pojawi się w tym samym czasie to IRQ3 zostanie obsłużone jako pierwsze niż IRQ4 które niestety musi poczekać na zakończenie obsługi IRQ3.

Po tym może nudnym opisie chciałbym pokazać coś co znalazłem na stronie Hitexa a co nie do końca zgadza się z oficjalnym przekazem dokumentacji ARM

The STM32 only uses half of this field to implement 16 levels of

priority. However, you should note that the active priority bits are in the upper nibble of each priority field. By

default the priority field defines 16 levels of priority with level zero the highest and 15 the lowest. It is also possible

to format the priority field into priority groups and subgroups. This does not provide extra levels of priority, but

helps management of priority levels when you have a large number of interrupts by programming the PRIGROUP

field in the Application Interrupt and Reset Control Register.

Zapis taki sugerowałby, że grupowanie nie wprowadza niczego do układu i powoduje tylko że grupowanie jest ważne dla programisty. Niestety nie jest to prawdą i w oficjalnej dokumentacji od ARM jest zupełnie inny zapis zgodny z tym który opisałem na początku, bo nawet on się zgadza z przeprowadzonymi testami.

Parę słów jeszcze na temat przerwań systemowych. Ponieważ w głównej mierze tylko z niego przy najmniej ja mogę korzystać. Przede wszystkim dlatego iż z takiego przerwania jak BusFault czy MemManage nie zamierzam korzystać. Pisząc program w C (a nie w asm) nie za bardzo muszę się martwić o to bo kompilator dba o poprawne przekazywanie danych.

Chcąc tera określic wartość piorytetu dla przerwania systemowego, a co za tym czy SysTick będzi wywłaszczał przerwanie zewnetrze czy nie musimy złożyć bity grupujące przerwania zewnętrze w całośc i porównać z wartością przerwania systemowego.

Mam nadzieję że nie zamotałem za mocno opisu, jeśłi tak to prosze o sygnał a postaram sie jakoś w bardziej przystępny sposób opisać.

  • Lubię! 2
Link do komentarza
Share on other sites

Pomieszałeś trochę z tymi grupami priorytetów. Za priorytety przerwań odpowiadają 4bity odpowiedniego rejestru (czyli jest 16 poziomów priorytetów), a przy konfiguracji możemy ustalić ile bitów ma odpowiadać za priorytet grupowy (group priority) a ile za priorytet wewnątrz grupy (subpriority). Dostępnych jest 5 opcji - 0bitów priorytetu grupowego 4sub, 1gr 3 sub itd aż do 4gr 0 sub. Czyli nie ma pięciu grup priorytetów tylko jest 5 możliwości podziału priorytetów na grupowe i podrzędne. Priorytety zapisywane są na czterech kolejnych bitach, więc nawet jeśli nie znamy organizacji grup priorytetów to wiemy który jest ważniejszy przez zwykłe porównanie liczb. W standardowym rdzeniu ARM wszystko jest tak samo tylko, że mamy więcej bitów do wykorzystania.

Teraz czym się różnią poszczególne priorytety. Jeżeli podczas wykonywania danego przerwania wystąpi inne o wyższym priorytecie grupowym - nastąpi wywłaszczenie. Natomiast jeżeli nastąpi inne o takim samym grupowym, ale innym wewnętrznym - nie będzie wywłaszczenia. Za to jeśli te dwa przerwania oczekują na czas procesora (np wykonuje się inne przerwanie o większym priorytecie) to procedurę arbitrażu wygra ten o wyższym priorytecie wewnątrzgrupowym.

Link do komentarza
Share on other sites

Aby było śmieszniej dokładnie to miałem na myśli. A wniosek jest taki że nauczycielem to ja nigdy nie będę.

Ale dobrze że poprawiłeś bo teraz już jest jasne o co chodzi.

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.