Mikrokontrolery STM32 - Praca pod kontrolą FreeRTOS.pdf

(1252 KB) Pobierz
116-122_stm32_i_system_operacyjny_FreeRTOS_1.indd
PODZESPOŁY
Dodatkowe materiały >>
Mikrokontrolery STM32
Praca pod kontrolą FreeRTOS
System operacyjny
Zadaniem każdego systemu operacyjnego
jest zarządzanie sprzętem w taki sposób, aby
zadania stawiane przez użytkownika były
wykonane przy optymalnym wykorzystaniu
zasobów i mocy obliczeniowej. Z systemami
operacyjnymi stykamy się praktycznie co-
dziennie używając komputerów osobistych.
Współczesne komputery mają bardzo duże
zasoby sprzętowe i szybkie, wielordzeniowe
mikroprocesory. W związku z tym, że po-
jęcie systemu operacyjnego jest najczęściej
kojarzone właśnie z takimi komputerami, to
trudno jest sobie wyobrazić, że tak niewielki
układ jak mikrokontroler, może również pra-
cować pod kontrolą systemu operacyjnego.
Złożoność zadań, z jakimi ma do czynienia
system operacyjny urządzenia embedded ,
jest przeważnie mniejsza, niż w przypadku
komputerów osobistych. Niemniej, nawet te
mocno uproszczone OS ( Operating System )
są bardzo zaawansowane. Z tego powodu
powstało wiele firm, których głównym zada-
niem jest pisanie i rozwijanie wbudowanych
systemów operacyjnych.
W przeciwieństwie do świata komputerów osobistych, gdzie panują
pewne standardy, w świecie mikrokontrolerów jest ogromna
różnorodność dostępnych opcji i rozwiązań układowych. W konsekwencji,
każda rodzina mikrokontrolerów wymaga przygotowanej specjalnie dla
niej dystrybucji systemu operacyjnego. Sytuacja jest trochę lepsza, gdy
używany jest mikrokontroler z rdzeniem wykorzystywanym przez wielu
producentów, czyli na przykład z rdzeniem firmy ARM. Informacje
podane w artykule dotyczą przede wszystkim mikrokontrolerów STM32,
wyposażonych w rdzeń Cortex M3.
stu, przeglądarkę internetową, odtwarzacz
muzyki itp. Z punktu widzenia sprzętu, sys-
tem operacyjny ma do dyspozycji jeden pro-
cesor (współcześnie stosowane są procesory
wielordzeniowe, ale w tym opisie użyjemy
uproszczonej, jednordzeniowej, wersji), a za-
tem jak to się dzieje, że tyle zadań realizo-
wanych jest równocześnie? Odpowiedź jest
bezpośrednio związana z prędkością, z którą
pracują współczesne procesory. Dzięki dużej
częstotliwości taktowania rdzeni każde zada-
nie uruchomione w systemie otrzymuje do
swojej dyspozycji procesor tylko na pewien
czas. Jeśli ten czas będzie dostatecznie krót-
ki, czyli przełączanie pomiędzy uruchamia-
nymi zadaniami będzie dostatecznie szybkie,
to użytkownik korzystający z komputera od-
niesie wrażenie, że wszystkie jego programy
pracują jednocześnie.
Na rys. 1 przedstawiono diagram pracy
wielozadaniowego OS z uruchomionymi jed-
nocześnie kilkoma zadaniami. Na rys. 1a po-
kazano, że wszystkie trzy zadania są pozornie
wykonywane jednocześnie. Dopiero rys. 1b ,
który przedstawia w dużym powiększeniu
zachowanie się procesów pokazuje, że każde
zadanie wykonywane jest tylko przez pewien
czas, a pozostałe są wstrzymane i czekają na
swoją kolej. Jest to najprostsza forma systemu
operacyjnego, gdzie kolejkowanie odbywa się
przy pomocy algorytmu karuzelowego, omó-
wionego w dalszej części tego artykułu.
Wymagania stawiane systemom wbudo-
wanym wymusiły powstanie systemów ope-
racyjnych czasu rzeczywistego (RTOS – Real
Time Operating System ). W przeciwieństwie
do dużych komputerów, w systemie mikro-
procesorowym często zdarza się, że wykona-
nie danego zadania musi mieścić się w ściśle
określonym przedziale czasu. Ma to znacze-
nie m.in. dla procesów przemysłowych, ale
przede wszystkim wszędzie tam, gdzie od
maszyn zależy życie i bezpieczeństwo ludzi.
RTOSy dzielą się dodatkowo na grupy,
w zależności od tego, w jakim stopniu jest
się w stanie ocenić czas wykonywania ope-
racji. Z tej perspektywy można rozróżnić
miękkie i twarde systemy operacyjne czasu
rzeczywistego. Pierwsze pozwalają określić
czas wykonywania zadania z pewną dokład-
nością, natomiast drugie mają do spełnienia
najwyższe wymagania i muszą być całkowi-
cie przewidywalne.
Wielozadaniowy system
operacyjny czasu rzeczywistego
Pracując z komputerem często korzysta
się z wielu programów pracujących jedno-
cześnie. Można mieć włączony edytor tek-
Rys. 1.
System operacyjny czasu
rzeczywistego z wywłaszczeniami
zadań
Zazwyczaj schemat pracy systemów
mikroprocesorowych polega na wykonaniu
instrukcji przez jakąś funkcję (zadanie) i cze-
kaniu na wystąpienie zdarzenia. Podczas
oczekiwania na zdarzenie lub upłynięcie
116
ELEKTRONIKA PRAKTYCZNA 5/2009
652389588.051.png 652389588.062.png 652389588.072.png 652389588.083.png 652389588.001.png 652389588.002.png 652389588.003.png 652389588.004.png 652389588.005.png 652389588.006.png 652389588.007.png 652389588.008.png 652389588.009.png 652389588.010.png 652389588.011.png 652389588.012.png 652389588.013.png 652389588.014.png 652389588.015.png 652389588.016.png 652389588.017.png 652389588.018.png 652389588.019.png 652389588.020.png 652389588.021.png 652389588.022.png
Praca pod kontrolą FreeRTOS
Rys. 2.
a więc wtedy, gdy obsługiwane zadanie jest
przerywane podczas pracy na rzecz innego
zadania o wyższym priorytecie, nie tolerują-
cego zwłoki w obsłudze.
W czasie pracy mikrokontroler może
nie mieć żadnych zadań do obsługi, z te-
go powodu w systemie operacyjnym wy-
stępuje ważny proces nazywany procesem
bezczynności systemu – Idle task . Idle task
jest uruchamiany zawsze wtedy, gdy system
nie ma żadnych zadań do realizacji. Proces
bezczynności systemu zajmuje się czyszcze-
niem pamięci po zakończonych zadaniach,
oraz, gdy faktycznie nie ma nic do zrobienia,
może wprowadzać tryby obniżonego poboru
mocy. Zazwyczaj priorytet tego zadania jest
najniższy z możliwych ( rys. 4 ).
określonego czasu, mikrokontroler nie robi
nic, poza wykonywaniem pustych instrukcji.
W układach z wbudowanym systemem ope-
racyjnym w czasie oczekiwania na zdarzenie
będą uruchomione pozostałe, oczekujące na
czas procesora, zadania. Sytuację taką przed-
stawiono na rys. 2 . Nie można opisanego
powyżej zachowania wprost nazwać wy-
właszczeniem, ponieważ w tym przypadku
przerywane zadanie tak naprawdę nie jest
wstrzymywane, bo i tak bezproduktywnie
oczekuje na jakieś zdarzenie lub po prostu
odlicza określony czas.
Rys. 2 ilustruje przerwanie ZADANIA A
w momencie jego oczekiwania, aż upłynie
czas 100 ms. W tym czasie RTOS oddaje pro-
cesor do dyspozycji ZADANIA B, o niższym
priorytecie, niż ZADANIE A. Można sobie
to wyobrazić w taki sposób, że ZADANIE
A zajmuje się sterowaniem procesu wyko-
nawczego (np. silnika) i tutaj nie mogą wy-
stąpić fluktuacje czasu, natomiast ZADANIE
B zajmuje się interfejsem użytkownika, który
nie ma narzuconych krytycznych ram czaso-
wych i może być wykonywane „w wolnych
chwilach” procesora.
Z prawdziwymi wywłaszczeniami ( pre-
emptive ) zadań mamy zaś do czynienia wte-
dy, gdy system operacyjny zachowuje się
podobnie, jak to przedstawiono na rys. 3 ,
Algorytm szeregowania
Algorytm szeregowania ( scheduler – pla-
nista), jest częścią jądra systemu i ma za za-
danie optymalnie rozdzielić czas procesora
oraz zasoby systemu mikroprocesorowego
pomiędzy uruchomione zadania. Uwzględ-
nia przy tym priorytety zadań i wymagania
związane z czasem ich realizacji.
Implementacja dobrego algorytmu sze-
regowania nie należy do łatwych, a jego
skomplikowanie rośnie wraz z wymaganiami
stawianymi przed systemem operacyjnym.
Generalnie można rozróżnić kilka podsta-
wowych rodzajów algorytmów szeregowa-
nia. Najprostszym jest algorytm karuzelowy,
którego zasadę działania przedstawiono na
rys. 5 . Nazwa tego rodzaju planisty bardzo
dobrze oddaje jego faktyczne zachowanie.
Zadania wykonywane są w ustalonej kolej-
ności, po czym proces się powtarza, czyli
mamy swoistą karuzelę.
W systemach operacyjnych czasu rzeczy-
wistego algorytm karuzelowy w swej czystej
postaci nie jest specjalnie użyteczny. Zgod-
nie z tym, co zostało już wcześniej napisane,
w RTOS krytyczne zadania nie mogą czekać
na swoją kolejkę, tylko muszą być wykony-
wane natychmiast, czyli muszą wywłaszczać
procesy o niższych priorytetach.
Rys. 3.
System operacyjny FreeRTOS
FreeRTOS to system operacyjny czasu
rzeczywistego z wywłaszczeniami. Jest to
darmowe narzędzie open source i może być
wykorzystywany w aplikacjach komercyj-
nych. Wszystkie niezbędne informacje do
Rys. 4.
Rys. 5.
ELEKTRONIKA PRAKTYCZNA 5/2009
117
652389588.023.png 652389588.024.png 652389588.025.png 652389588.026.png 652389588.027.png 652389588.028.png 652389588.029.png 652389588.030.png 652389588.031.png 652389588.032.png 652389588.033.png 652389588.034.png 652389588.035.png 652389588.036.png 652389588.037.png 652389588.038.png 652389588.039.png 652389588.040.png 652389588.041.png 652389588.042.png 652389588.043.png 652389588.044.png
PODZESPOŁY
Struktura plików systemu
FreeRTOS
Wszystkie projekty wykorzystujące sys-
tem operacyjny FreeRTOS mają podobną
strukturę plików, a przynajmniej progra-
mista powinien dążyć do jej standaryzacji.
Powyższa filozofia pisania aplikacji dotyczy
oczywiście wszystkich prac związanych
z jakimkolwiek dojrzałym projektowaniem.
Standaryzacja działań projektowych zawsze
pozwala zaoszczędzić mnóstwo czasu i pie-
niędzy. Na rys. 6 zamieszczono zrzut ekrano-
wy przedstawiający drzewo plików projektu
wykorzystującego system FreeRTOS.
System operacyjny FreeRTOS w swej
podstawowej formie jest niezależny od
sprzętu. Aby jądro systemu mogło nawią-
zać współpracę z danym mikrokontrole-
rem należy mu zaimplementować interfejs.
We wszystkich przykładach, dostępnych
na stronie domowej systemu FreeRTOS,
kod zapewniający poprawną pracę z da-
ną architekturą umieszczono w pliku port.
c . Również we własnych projektach i przy
tworzeniu nowej dystrybucji FreeRTOSa
na nową platformę, należy stosować ten
sam standard. Zadaniem kodu w pliku port.
c jest konfiguracja do pracy oraz obsługa
przerwań i wyjątków systemowych, o któ-
rych była mowa w EP04/09, a które są ściśle
związane z architekturą rdzeni Cortex M3
(np. timer SysTick, wyjątek PendSV).
Rys. 7.
Rys. 6.
rozpoczęcia pracy z tym systemem, aktualna
wersja do pobrania oraz forum dyskusyjne są
dostępne na stronie internetowej www.freer-
tos.org .
W swojej podstawowej konfiguracji sys-
tem FreeRTOS składa się z trzech plików
źródłowych, które są wspólne dla wszyst-
kich architektur mikrokontrolerów. Te pliki
to: tasks.c, queue.c, list.c.
Powyższe pliki to jądro systemu opera-
cyjnego. Do poprawnej pracy w docelowym
mikrokontrolerze wymagane są jeszcze pliki
programów zapewniających komunikację
pomiędzy sprzętem, a jądrem systemu.
W sumie przygotowanych jest prawie 20
dystrybucji tego systemu (każda z przykła-
dową aplikacją). Innymi słowy – FreeRTOS
można zaimplementować w niemal 20 róż-
nych mikrokontrolerach. Oprócz mikrokon-
trolerów STM32, przygotowane są wersje
systemu FreeRTOS dla: Atmel AVR, NXP
(LPC2106, LPC2124, LPC2129), Microchip
(PIC18, PIC24, dsPIC, PIC32), Freescale (Cold-
Fire), Xilinx (Microblaze, PowerPC – „mięk-
kie” procesory do implementacji w układach
FPGA), Texas Instruments (MSP430), Lumi-
naryMicro (LM3Sxxxx – rdzeń Cortex M3).
Zaletą narzędzi open source jest dostęp-
ność wszystkich kodów źródłowych i możli-
wość ich edycji. W takim przypadku należy
jednak swój kod również publikować. Wadą
jest brak pewności, co do stabilności działa-
nia i braku błędów.
Argumentem przemawiającym za stoso-
waniem w swoich aplikacjach systemu Fre-
eRTOS jest dostępność również jego wersji
komercyjnych (OpenRTOS i SafeRTOS).
Dzięki temu, jeśli projekt stanie się bardziej
wymagający, można skorzystać z systemów
operacyjnych z pełnym wsparciem i certy-
fikatami bezpieczeństwa. System FreeRTOS
jest w pełni skalowalny, co oznacza, że moż-
na dopasowywać jego stopień zaawanso-
wania do wymagań (bardziej – ograniczeń)
projektu.
Rys. 8.
różniamy cztery możliwe stany, w których
zadanie może być:
– Wykonywane ( Running ), zadanie aktual-
nie korzysta z zasobów mikrokontrolera.
– Gotowe do wykonywania ( Ready ), może
być wykonywane, ale czeka na zwolnie-
nie zasobów przez inne zadanie.
– Zablokowane ( Blocked ), zadanie czeka
na zdarzenie, przykładowo upłynięcie
zadanego czasu lub zewnętrzne przerwa-
nie.
– Wstrzymane ( Suspended ), zadanie, które
zostało wstrzymane nie jest uwzględnia-
ne przez planistę, ale może być wzno-
wione.
Możliwe przejścia pomiędzy wszystki-
mi stanami przestawiono na rys. 7 . Zadania
mają przypisany priorytet, przy czym priory-
tet 0 jest domyślnie nadany procesowi bez-
czynności systemu ( Idle task ).
Współprogramy mają trzy dozwolone
stany:
– Gotowe do wykonywania ( Ready ).
– Wykonywane ( Running ).
– Zablokowane ( Blocked ).
Diagram przejść pomiędzy powyższymi
stanami został zamieszczono na rys. 8 .
Zasada działania systemu
FreeRTOS. Zadania ( Tasks )
i współprogramy ( Co-routines )
Procesy w systemie FreeRTOS mogą
być realizowane na dwa sposoby: za po-
mocą zadań ( task ) lub współprogramów
( Co-routines ). Standardowo, zadania wy-
korzystywane są w systemach operacyj-
nych czasu rzeczywistego. Są to zupełnie
niezależne procesy. Każde zadanie posiada
swój własny kontekst, czyli z perspektywy
takiego zadania, wszystkie rejestry i stos
należą tylko do niego. O tym, które zadanie
jest wykonywane w danym momencie, de-
cyduje algorytm szeregowania ( scheduler ).
Planista kontroluje uruchomione zadania,
przerywa je i wznawia, a system operacyj-
ny dba o przełączanie kontekstów. Każde
zadanie posiada swój własny stos, które-
go zawartość umieszczona jest w pamięci
RAM.
Współprogramy działają podobnie do
zadań, choć są pomiędzy nimi istotne róż-
nice. Współprogramy dzielą jeden stos, a co
za tym idzie, do swego działania potrzebu-
ją mniejszej ilości pamięci RAM. Ponadto,
ważne jest, że zadania i współprogramy
nie mogą się komunikować między sobą za
pomocą kolejek i semaforów, a zadania za-
wsze są ważniejsze o współprogramów.
Każde z zadań występujące w systemie
FreeRTOS ma określony stan. W sumie wy-
Konstrukcja i uruchamianie
zadania w systemie FreeRTOS
W dotychczasowych rozważaniach nie
podejmowaliśmy tematu konstrukcji za-
dań. Każde zadanie w systemie operacyj-
nym FreeRTOS jest zazwyczaj funkcją, któ-
ra musi być napisana według określonych
standardów. Przykładowy fragment kodu
zawierający puste zadanie zamieszczono
na list. 1. Zarówno wartość zwracana przez
funkcję, jak i argument są typu void. Ar-
gument przekazywany do funkcji zadania
może służyć do przekazywania informacji
każdego typu.
118
ELEKTRONIKA PRAKTYCZNA 5/2009
652389588.045.png 652389588.046.png 652389588.047.png 652389588.048.png 652389588.049.png
Praca pod kontrolą FreeRTOS
List. 1.
void vTaskX(void * pvParameters)
{
Zadania tworzone są za pomocą funk-
cji xTaskCreate(), a usuwane po wywołaniu
funkcji vTaskDelete(). Literka v przed nazwą
funkcji oznacza, że nie zwraca ona żadnej
wartości. Rzecz jasna, funkcje tworzenia
i usuwania zadania muszą mieć przekazane
odpowiednie parametry. Sposób tworzenia,
a następnie usuwania zadania przestawiono
na list. 2 . Proces bezczynności systemu ( Idle
task ) jest tworzony automatycznie przez al-
gorytm szeregowania, a więc nie wymaga
jawnych operacji włączania.
Komentarza wymaga lista argumentów
funkcji tworzącej zadanie xTaskCreate(). Li-
cząc od lewej strony, najpierw przekazujemy
nazwę funkcji zadania, w tym przykładzie
jest to vTaskLED. Kolejnym argumentem jest
nazwa zadania, która pozwala je zidentyfi-
kować. Następnie określamy rozmiar stosu,
czy będą przekazane jakieś parametry (NUL-
L=brak), priorytet, a na końcu uchwyt do
zadania, który może być dalej wykorzysty-
wany do sterowania jego pracą. Usunięcie
zadania ogranicza się do wywołania funkcji
vTaskDelete() z uchwytem do zadania w ar-
gumencie.
for(;;)
{
// Tutaj kod realizowanego zadania
}
}
List. 2.
void vStartLEDTasks(unsigned portBASE_TYPE uxPriority)
{
xTaskHandle xHandleTaskLED;
// Tworzenie zadania
xTaskCreate(vTaskLED, ( signed portCHAR * ) „LED”,
STACK_SIZE, NULL, uxPriority, &xHandleTaskLED);
// Usuwanie zadania
vTaskDelete(xHandleTaskLED);
}
List. 3.
void vTaskLED(void * pvParameters)
{
// Nieskonczona petla zadania
for(;;)
{
// Wprowadzenie opoznienia 500ms
vTaskDelay(500/portTICK_RATE_MS);
// Zmiana stanu wyprowadzenia PC6 (LD1) na przeciwny
vhToggleLED();
}
}
List. 4.
void vTaskLED(void * pvParameters)
{
portTickType xLastFlashTime;
Podstawowe sterowanie
zadaniami
Poza tworzeniem i usuwaniem zadań,
dobrze by było, gdyby system udostępniał
mechanizmy pozwalające na wprowadzanie
opóźnień czasowych, czy też wstrzymywa-
nie i wznawianie wykonywania zadania.
System operacyjny FreeRTOS udostępnia
kilka funkcji API, pozwalających na sterowa-
nie i kontrolę nad zadaniami.
W celu wprowadzenia opóźnień w wyko-
nywanym zadaniu mogą być użyte dwie funk-
cje: vTaskDelay() i vTaskDelayUntil(). Funkcja
vTaskDelay() przyjmuje jeden argument, który
jest liczbą taktów zegara systemu operacyjne-
go, na jaką dane zadanie zostanie zablokowa-
ne. Czym dokładnie są takty systemu opera-
cyjnego, to będzie opisane w dalszej części
tego artykułu, przy okazji przedstawiania pli-
ku konfiguracyjnego systemu FreeRTOS. Tu-
taj wystarczy wiedzieć, że jest to najmniejszy
kwant czasu rozróżniany przez OS.
Istotne jest, że czas zablokowania jest
ściśle związany z częstotliwością wymie-
nionego wyżej zegara systemowego i zmiana
tego parametru może spowodować zmiany
opóźnień. W celu zabezpieczenia się przed
taką ewentualnością, do wyznaczenia liczby
taktów wykorzystuje się całkowite dzielenie
przez stałą portTICK_RATE_MS, która po-
zwala obliczyć opóźnienia z dokładnością
do jednego taktu. Na list. 3 przedstawiono
zadanie, które zajmuje się cykliczną zmianą
stanu wyprowadzeń mikrokontrolera, gdzie
w roli funkcji opóźnienia wykorzystano vTa-
skDelay(). Fizyczną zmianą stanu wyprowa-
dzenia zajmuje się poniższa funkcja vhTog-
gleLED():
// Odczytanie stanu licznika systemowego
// Nieskonczona petla zadania
for(;;)
{
// Wprowadzenie opoznienia 500ms
vTaskDelayUntil( &xLastFlashTime, 500/portTICK_RATE_MS );
// Zmiana stanu wyprowadzenia PC6 (LD1) na przeciwny
vhToggleLED();
}
}
Ważnym elementem konstrukcji funkcji
zadania jest jego nieskończoność. Innymi
słowy, kod zadania musi być umieszczony
w pętli nieskończonej for lub while, czyli raz
wywołane zdanie nigdy samoczynnie nie po-
wróci do miejsca swojego wywołania.
Rys. 9.
ELEKTRONIKA PRAKTYCZNA 5/2009
119
xLastFlashTime = xTaskGetTickCount();
652389588.050.png 652389588.052.png 652389588.053.png 652389588.054.png 652389588.055.png 652389588.056.png 652389588.057.png 652389588.058.png 652389588.059.png 652389588.060.png 652389588.061.png
 
PODZESPOŁY
void vhToggleLED(void)
{
// Zamiana stanu wyprowadzenia PC6 na
przeciwny
GPIO_WriteBit(GPIOC, GPIO_Pin_6,
(BitAction)
((1-GPIO_
ReadOutputDataBit(GPIOC, GPIO_Pin_
6))));
}
List. 5.
void vStartLEDTasks(unsigned portBASE_TYPE uxPriority)
{
xTaskHandle xHandleTaskLED;
unsigned portBASE_TYPE uxTaskLEDPriority;
// Tworzenie zadania
xTaskCreate( vTaskLED, ( signed portCHAR * ) „LED”,
STACK_SIZE, NULL, uxPriority, &xHandleTaskLED);
Tworzenie nowej funkcji dla jednej li-
nii kodu jest uzasadnione tym, że projekt
powinien być tworzony w sposób warstwo-
wy. Przedrostek nazwy funkcji zawierający
literkę h nie jest przypadkowy, a oznacza,
że funkcja działa wprost na sprzęcie. Takie
podejście doskonale wpływa na czytelność
projektu i zabezpiecza przed przypadkowym
odwołaniem się do urządzeń peryferyjnych,
ponieważ wiadomo, że tylko funkcje z przed-
rostkiem h mogą to robić.
Generalnie, wykorzystywanie funkcji
vTaskDelay() do sterowania pracą zadań
cyklicznych, w szczególności takich, w któ-
rych opóźnienia (częstotliwość) muszą być
dokładne, nie jest dobrym pomysłem. Oma-
wiana funkcja nie gwarantuje, że opóźnienia
czasowe wprowadzane za jej pomocą będą
zawsze tym zaprogramowanym. W przy-
padkach zadań, które wymagają dokładno-
ści w generowaniu zwłok czasowych dużo
lepszym rozwiązaniem jest druga z funkcji
opóźniających, a mianowicie vTaskDelay-
Until(). Niedoskonałość funkcji vTaskDelay()
wynika z tego, że od jednego jej wywołania
do drugiego mogą upływać różne czasy, co
nie jest uwzględniane. Problem przedsta-
wiono na rys. 9 . Jeśli w zadaniu wykorzysty-
wane są instrukcje warunkowe, to sam kod
zadania może się wykonywać przez różny
okres czasu. Druga niejednoznaczność czasu
wykonywania kodu zadania może wystąpić
wtedy, gdy wystąpi przerwanie lub wywłasz-
czenie, co przedstawiono na rys. 9c .
Funkcja vTaskDelayUntil() opóźnia wy-
konywanie kodu o czas obliczony na pod-
stawie dwóch przekazanych argumentów.
Pierwszy jest liczbą taktów systemu od chwi-
li uruchomienia planisty, natomiast drugi
liczba taktów, na jaką wykonywanie zadania
ma być wstrzymane. W ten sposób, dodając
do siebie obie wartości, funkcja API otrzy-
muje liczbę, po której osiągnięciu przez licz-
nik taktów systemu operacyjnego, zostanie
wznowione wykonywanie zablokowanego
zadania. Dzięki takiemu podejściu, osiągnię-
to niezależność w stosunku do czasu wyko-
nywania kodu samego zadania, czyli nie są
istotne tutaj wywłaszczenia zadania itd.
Wykorzystanie funkcji vTaskDelayUntil()
przedstawiono na list. 4 . Liczbę taktów sys-
temu operacyjnego otrzymuje się za pomocą
wywołania funkcji xTaskGetTickCount(), na-
tomiast liczbę taktów opóźnienia wyznaczo-
no za pomocą całkowitego dzielenia przez
stałą portTICK_RATE_MS.
Każde zadanie ma swój ustalony priory-
tet. Naturalną konsekwencją tego jest potrze-
ba istnienia w systemie mechanizmów umoż-
vTaskPrioritySet(xHandleTaskLED, 3);
// Odczytanie priorytetu zadania
uxTaskLEDPriority = uxTaskPriorityGet(xHandleTaskLED);
}
List. 6.
#define configUSE_PREEMPTION
1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 72000000 )
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 128 )
#define configTOTAL_HEAP_SIZE
( ( size_t ) ( 17 * 1024 ) )
#define configMAX_TASK_NAME_LEN
( 16 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS
#define configIDLE_SHOULD_YIELD
0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/*Set the following definitions to 1 to include
the API function, or zero to exclude the API function*/
#define INCLUDE_vTaskPrioritySet
1
#define INCLUDE_uxTaskPriorityGet
1
#define INCLUDE_vTaskDelete
1
#define INCLUDE_vTaskCleanUpResources
0
#define INCLUDE_vTaskSuspend
1
#define INCLUDE_vTaskDelayUntil
1
#define INCLUDE_vTaskDelay
1
Rys. 10.
Rys. 11.
120
ELEKTRONIKA PRAKTYCZNA 5/2009
// Ustawienie priorytetu zadania
1
652389588.063.png 652389588.064.png 652389588.065.png 652389588.066.png 652389588.067.png 652389588.068.png 652389588.069.png 652389588.070.png 652389588.071.png 652389588.073.png 652389588.074.png 652389588.075.png 652389588.076.png 652389588.077.png 652389588.078.png 652389588.079.png 652389588.080.png 652389588.081.png 652389588.082.png 652389588.084.png 652389588.085.png
Zgłoś jeśli naruszono regulamin