- Uzdevuma dzēšana programmā FreeRTOS Arduino
- Kāda ir rinda FreeRTOS?
- Rindas izveide FreeRTOS
- Ķēdes shēma
- RealRTOS rindas ieviešana Arduino IDE
Iepriekšējā apmācībā mēs ieviesām FreeRTOS ar Arduino Uno un izveidojām uzdevumu mirgojošajam LED. Tagad šajā apmācībā mēs vairāk iedziļināsimies iepriekšējās RTOS API koncepcijās un uzzināsim par saziņu starp dažādiem uzdevumiem. Šeit mēs arī uzzinām par rindu, lai pārsūtītu datus no viena uzdevuma uz otru, un parādām rindas API darbību, saskaroties ar 16x2 LCD un LDR ar Arduino Uno.
Pirms diskusijas par rindām, apskatīsim vēl vienu FreeRTOS API, kas noder uzdevumu dzēšanai, kad tas ir pabeigts ar piešķirto darbu. Dažreiz uzdevums ir jāizdzēš, lai atbrīvotu atvēlēto atmiņu. Iepriekšējās apmācības turpinājumā mēs izmantosim vTaskDelete () API funkciju tajā pašā kodā, lai izdzēstu vienu no uzdevumiem. Uzdevums var izmantot API funkciju vTaskDelete (), lai izdzēstu sevi vai jebkuru citu uzdevumu.
Lai izmantotu šo API, jums jākonfigurē FreeRTOSConfig.h fails. Šis fails tiek izmantots, lai pielāgotu FreeRTOS atbilstoši lietojumprogrammai. To izmanto, lai mainītu plānošanas algoritmus un daudzus citus parametrus. Fails ir atrodams Arduino direktorijā, kas parasti ir pieejams datora mapē Dokumenti. Manā gadījumā tas ir pieejams \ Documents \ Arduino \ libraries \ FreeRTOS \ src, kā parādīts zemāk.
Tagad atvērt šo failu, izmantojot jebkuru teksta redaktoru, un meklēt to #define INCLUDE_vTaskDelete un pārliecinieties, ka tā vērtība ir "1" (1 nozīmē iespēju un 0 nozīmē atslēgt). Pēc noklusējuma tas ir 1, bet to pārbauda.
Nākamajās apmācībās parametru iestatīšanai mēs bieži izmantosim šo konfigurācijas failu.
Tagad redzēsim, kā izdzēst uzdevumu.
Uzdevuma dzēšana programmā FreeRTOS Arduino
Lai izdzēstu uzdevumu, mums jāizmanto funkcija vTaskDelete () API. Tas prasa tikai vienu argumentu.
vTaskDelete (TaskHandle_t pxTaskToDelete);
pxTaskToDelete: Tas ir uzdevuma rokturis, kas ir jādzēš. Tas ir tas pats, kas 6 th arguments xTaskCreate () API. Iepriekšējā apmācībā šis arguments ir iestatīts kā NULL, taču uzdevuma satura adresi varat nodot, izmantojot jebkuru vārdu. Teiksim, ja vēlaties iestatīt uzdevuma rokturi Task2, kas tiek deklarēts kā
TaskHandle_t any_name; Piemērs: TaskHandle_t xTask2Handle;
Tagad, vTaskCreate () API noteikts 6 th arguments par
xTaskCreate (TaskBlink2, "task2", 128, NULL, 1, & xTask2Handle);
Tagad šī uzdevuma saturam var piekļūt, izmantojot jūsu norādīto rokturi.
Arī uzdevums var pats izdzēst, nododot NULL derīga uzdevuma roktura vietā.
Ja mēs vēlamies izdzēst 3. uzdevumu no paša 3. uzdevuma, jums jāuzraksta vTaskDelete (NULL); iekš Task3 funkcijas, bet, ja vēlaties izdzēst 3. uzdevumu no 2. uzdevuma, ierakstiet vTaskDelete (xTask3Handle); iekšā task2 funkcija.
Iepriekšējā apmācības kodā, lai izdzēstu Task2 no paša task2, vienkārši pievienojiet vTaskDelete (NULL); in void TaskBlink2 (void * pvParameters) funkcija. Tad iepriekš minētā funkcija izskatīsies šādi
void TaskBlink2 (void * pvParameters) { Serial.println (“2. uzdevums darbojas un gatavojas dzēst”); vTaskDelete (NULL); pinMode (7, OUTPUT); kamēr (1) { digitalWrite (7, HIGH); vTaskDelay (300 / portTICK_PERIOD_MS); digitalWrite (7, LOW); vTaskDelay (300 / portTICK_PERIOD_MS); } }
Tagad augšupielādējiet kodu un novērojiet gaismas diodes un sērijas monitoru. Jūs redzēsiet, ka otrais indikators tagad nemirgo un uzdevums2 tiek izdzēsts pēc saskaršanās ar dzēšanas API.
Tātad šo API var izmantot, lai apturētu konkrētā uzdevuma izpildi.
Tagad sāksim ar rindu.
Kāda ir rinda FreeRTOS?
Rinda ir datu struktūra, kurā var turēt noteiktu skaitu fiksēta izmēra elementu, un tā tiek darbināta FIFO shēmā (First-in First-out). Rindas nodrošina komunikācijas mehānismu starp uzdevumu, uzdevumu pārtraukt un pārtraukumu starp uzdevumu.
Maksimālo rindā esošo elementu skaitu sauc par tā “garumu”. Gan katra elementa garums, gan lielums tiek iestatīts, izveidojot rindu.
Piemērs tam, kā rinda tiek izmantota datu pārsūtīšanai, ir labi parādīts šeit FreeRTOS dokumentācijā. Jūs varat viegli saprast sniegto piemēru.
Pēc rindu izpratnes mēģināsim izprast rindas izveidošanas procesu un mēģināsim to ieviest mūsu FreeRTOS kodā.
Rindas izveide FreeRTOS
Vispirms aprakstiet problēmas izklāstu, kas jāievieš ar FreeRTOS rindas un Arduino Uno palīdzību.
Mēs vēlamies izdrukāt LDR sensora vērtību uz 16 * 2 LCD. Tātad tagad ir divi uzdevumi
- 1. uzdevums iegūst LDR analogās vērtības.
- 2. uzdevums drukā analogo vērtību uz LCD.
Tātad šeit rinda spēlē savu lomu, jo, lai nosūtītu uzdevuma1 ģenerētos datus uz uzdevumu2. 1. uzdevumā mēs nosūtīsim analogo vērtību rindai un 2. uzdevumā to saņemsim no rindas.
Ir trīs funkcijas darbam ar rindām
- Rindas izveide
- Datu sūtīšana uz rindu
- Notiek datu saņemšana no rindas
Lai izveidotu rindu, izmantojiet xQueueCreate () funkcijas API. Tam nepieciešami divi argumenti.
xQueueCreate (UBaseType_t uxQueueLength, UBaseType_t uxItemSize);
uxQueueLength: Maksimālais vienumu skaits, ko vienlaikus var izveidot izveidojamā rinda.
uxItemSize: Katra rindā saglabājamā datu vienuma lielums baitos.
Ja šī funkcija atgriež NULL, rinda netiek izveidota nepietiekamas atmiņas dēļ, un, ja tā atgriež vērtību NULL, rinda tiek veiksmīgi izveidota. Saglabājiet šo atgriešanās vērtību mainīgajā, lai to izmantotu kā rokturi piekļuvei rindai, kā parādīts zemāk.
QueueHandle_t queue1; rinda1 = xQueueCreate (4, sizeof (int));
Tas izveidos 4 elementu rindu kaudzes atmiņā ar int lielumu (2 baiti katrā blokā) un saglabās atgriešanās vērtību queue1 roktura mainīgajā.
2. Datu sūtīšana uz rindu FreeRTOS
Lai nosūtītu vērtības rindā, FreeRTOS šim nolūkam ir 2 API varianti.
- xQueueSendToBack (): tiek izmantots, lai nosūtītu datus uz rindas aizmuguri (asti).
- xQueueSendToFront (): tiek izmantots, lai nosūtītu datus uz rindas priekšpusi (galvu).
Tagad , xQueueSend () ir līdzvērtīgs, un tieši tāds pats kā, xQueueSendToBack ().
Visiem šiem API ir nepieciešami 3 argumenti.
xQueueSendToBack (QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait);
xQueue: Rindas rokturis, uz kuru dati tiek sūtīti (rakstīti). Šis mainīgais ir tāds pats kā izmantots, lai saglabātu xQueueCreate API atgriešanās vērtību.
pvItemToQueue: rādītājs datiem, kas kopējami rindā.
xTicksToWait: Maksimālais laiks, kamēr uzdevumam jāpaliek stāvoklī Bloķēts, lai gaidītu, kamēr rindā būs pieejama vieta.
Iestatot xTicksToWait uz portMAX_DELAY , uzdevums tiks gaidīts bezgalīgi (bez taimauta), ja vien INCLUDE_vTaskSuspend ir iestatīts uz 1 FreeRTOSConfig.h, pretējā gadījumā jūs varat izmantot makro pdMS_TO_TICKS (), lai milisekundēs norādīto laiku pārvērstu ērcēs norādītajā laikā.
3. Datu saņemšana no rindas FreeRTOS
Lai saņemtu (lasītu) vienumu no rindas, tiek izmantots xQueueReceive (). Saņemtais vienums tiek noņemts no rindas.
Šajā API ir arī trīs argumenti.
xQueueReceive (QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait);
Pirmais un trešais arguments ir tāds pats kā API sūtīšana. Tikai otrais arguments ir atšķirīgs.
const pvBuffer: Norāde uz atmiņu, kurā tiks kopēti saņemtie dati.
Ceru, ka sapratāt trīs API. Tagad mēs šos API ieviesīsim Arduino IDE un mēģināsim atrisināt iepriekš aprakstīto problēmas izklāstu.
Ķēdes shēma
Tas izskatās uz maizes dēļa:
RealRTOS rindas ieviešana Arduino IDE
Sāksim rakstīt kodu mūsu lietojumprogrammai.
1. Vispirms atveriet Arduino IDE un iekļaujiet galvenes failu Arduino_FreeRTOS.h . Tagad, ja tiek izmantots kāds kodola objekts, piemēram, rinda, iekļaujiet tā galvenes failu. Tā kā mēs izmantojam 16 * 2 LCD, iekļaujiet arī bibliotēku.
# iekļaut # iekļaut
2. Inicializējiet rindas rokturi, lai saglabātu rindas saturu. Inicializējiet arī LCD adatu numurus.
QueueHandle_t queue_1; LiquidCrystal lcd (7, 8, 9, 10, 11, 12);
3. Tukšajā iestatījumā () inicializējiet LCD un sērijveida monitoru ar 9600 bitu pārraides ātrumu. Izveidojiet rindu un divus uzdevumus, izmantojot attiecīgos API. Šeit mēs izveidosim 4. lieluma rindu ar vesela skaitļa tipu. Izveidojiet uzdevumu ar vienādām prioritātēm un vēlāk mēģiniet spēlēt ar šo numuru. Visbeidzot, palaidiet plānotāju, kā parādīts zemāk.
void setup () { Sērijas.sākt (9600); lcd.begin (16, 2); rinda_1 = xQueueCreate (4, sizeof (int)); if (rinda_1 == NULL) { Serial.println ("Rindu nevar izveidot"); } xTaskCreate (TaskDisplay, "Display_task", 128, NULL, 1, NULL); xTaskCreate (TaskLDR, "LDR_task", 128, NULL, 1, NULL); vTaskStartScheduler (); }
4. Tagad izveidojiet divas funkcijas TaskDisplay un TaskLDR . In TaskLDR funkciju, izlasiet analogo pin A0 mainīgajā jo mēs esam LDR saistīts ar A0 pin Arduino Uno. Tagad nosūtiet mainīgajā saglabāto vērtību, nododot to xQueueSend API un nosūtiet uzdevumu bloķēt stāvokli pēc 1 sekundes, izmantojot vTaskDelay () API, kā parādīts zemāk.
void TaskLDR (void * pvParameters) { int current_intensity; kamēr (1) { Serial.println (" 1. uzdevums"); strāvas intensitāte = analogRead (A0); Serial.println (pašreizējais_intensitāte); xQueueSend (rinda_1, & pašreizējā_intensitāte, portMAX_DELAY); vTaskDelay (1000 / portTICK_PERIOD_MS); } }
5. Līdzīgi izveidojiet funkciju TaskDisplay un saņemiet vērtības mainīgajā, kas tiek nodots funkcijai xQueueReceive . Arī xQueueReceive () atgriež pdPASS, ja datus var veiksmīgi saņemt no rindas, un atgriež errQUEUE_EMPTY, ja rinda ir tukša.
Tagad parādiet vērtības LCD, izmantojot funkciju lcd.print () .
void TaskDisplay (void * pvParameters) { int intensitāte = 0; kamēr (1) { Serial.println ("2. uzdevums"); if (xQueueReceive (rinda_1, & intensitāte, portMAX_DELAY) == pdPASS) { lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Intensitāte:"); lcd.setCursor (11, 0); lcd.print (intensitāte); } } }
Tieši tā. Mēs esam pabeiguši rindas ieviešanas kodēšanas daļu. Pilnīgu kodu ar darbojošos video var atrast beigās.
Tagad savienojiet LCD un LDR ar Arduino UNO saskaņā ar shēmas augšupielādes kodu augšupielādējiet. Atveriet sērijveida monitoru un ievērojiet uzdevumus. Jūs redzēsiet, ka uzdevumi mainās, un LDR vērtības mainās atkarībā no gaismas intensitātes.
PIEZĪME. FreeRTOS kodols neatbalsta lielāko daļu bibliotēku, kas izveidotas dažādiem sensoriem, jo kavēšanās funkciju ieviešana bibliotēkās. Aizkavēšanās liek CPU pilnībā apstāties, tāpēc arī FreeRTOS kodols pārstāj darboties, un kods vairs netiks izpildīts, un tas sāk nepareizi rīkoties. Tātad, mums ir jāpadara bibliotēkas bez kavēšanās strādāt ar FreeRTOS.