- Paano gumagana ang RTOS?
- Mga madalas na ginamit na termino sa RTOS
- Pag-install ng Arduino FreeRTOS Library
- Diagram ng Circuit
- Halimbawa ng Arduino FreeRTOS- Lumilikha ng mga gawain ng FreeRTOS sa Arduino IDE
- Pagpapatupad ng Gawain ng FreeRTOS sa Arduino IDE
Ang OS na nasa loob ng mga naka-embed na aparato ay tinatawag na isang RTOS (Real-Time Operating System). Sa mga naka-embed na aparato, ang mga real-time na gawain ay kritikal kung saan ang tiyempo ay may napakahalagang papel. Ang mga gawaing real-time ay Oras na Deterministic nangangahulugang ang oras ng pagtugon sa anumang kaganapan ay palaging pare-pareho upang masiguro na ang anumang partikular na kaganapan ay magaganap sa isang takdang oras. Ang RTOS ay idinisenyo upang magpatakbo ng mga application na may napaka tumpak na tiyempo at isang mataas na antas ng pagiging maaasahan. Tumutulong din ang RTOS sa multi-tasking na may isang solong core.
Natakpan na namin ang isang tutorial sa kung paano gamitin ang RTOS sa mga naka-embed na system kung saan maaari mong malaman ang higit pa tungkol sa RTOS, ang pagkakaiba sa pagitan ng pangkalahatang layunin na OS at RTOS, iba't ibang uri ng RTOS, atbp.
Sa tutorial na ito, magsisimula kami sa FreeRTOS. Ang FreeRTOS ay isang klase ng RTOS para sa mga naka-embed na aparato na kung saan ay maliit na sapat upang patakbuhin sa 8/16-bit microcontrollers, bagaman ang paggamit nito ay hindi limitado sa mga microcontroller na ito. Ito ay isang ganap na open-source at ang code na ito ay magagamit sa github. Kung alam natin ang ilang pangunahing mga konsepto ng RTOS, kung gayon napakadaling gamitin ang FreeRTOS sapagkat mayroon itong dokumentadong mahusay na mga API na maaaring direktang magamit sa code nang hindi alam ang backend na bahagi ng pag-coding. Ang kompletong dokumentasyon ng FreeRTOS ay matatagpuan dito.
Tulad ng FreeRTOS ay maaaring tumakbo sa 8-bit MCU kaya maaari din itong patakbuhin sa Arduino Uno board. Kailangan naming i-download lamang ang library ng FreeRTOS at pagkatapos ay simulang ipatupad ang code gamit ang mga API. Ang tutorial na ito ay inilaan para sa isang kumpletong nagsisimula, sa ibaba ay ang mga paksa, sasakupin namin ang Arduino FreeRTOS tutorial na ito:
- Paano gumagana ang RTOS
- Ang ilang madalas na ginagamit na mga termino sa RTOS
- Pag-install ng FreeRTOS sa Arduino IDE
- Paano lumikha ng Mga Gawain ng FreeRTOS na may halimbawa
Paano gumagana ang RTOS?
Bago magsimula sa pagtatrabaho ng RTOS, tingnan natin kung ano ang isang Gawain. Ang gawain ay isang piraso ng code na maiiskedyul sa CPU upang maipatupad. Kaya, kung nais mong magsagawa ng ilang gawain, dapat itong naka-iskedyul gamit ang pagkaantala ng kernel o paggamit ng mga pagkagambala. Ang gawaing ito ay ginagawa ng scheduler na naroroon sa kernel. Sa isang solong-core na processor, tinutulungan ng tagapag-iskedyul ang mga gawain upang maipatupad sa isang partikular na hiwa ng oras ngunit tila ang iba't ibang mga gawain ay sabay na naisakatuparan. Tumatakbo ang bawat gawain alinsunod sa prioridad na ibinigay dito.
Ngayon, tingnan natin kung ano ang nangyayari sa kernel ng RTOS kung nais naming lumikha ng isang gawain para sa LED na kumikislap na may isang segundo na agwat at ilagay ang gawaing ito sa pinakamataas na priyoridad.
Bukod sa gawaing LED, magkakaroon pa ng isang gawain na nilikha ng kernel, kilala ito bilang isang idle na gawain. Ang idle task ay nilikha kapag walang gawain na magagamit para sa pagpapatupad. Ang gawaing ito ay palaging tumatakbo sa pinakamababang priyoridad hal 0 priyoridad. Kung pag-aralan namin ang graph ng tiyempo na ibinigay sa itaas, makikita na ang pagpapatupad ay nagsisimula sa isang gawaing LED at tumatakbo ito para sa isang tinukoy na oras pagkatapos para sa natitirang oras, ang idle na gawain ay tumatakbo hanggang sa maganap ang isang tick tick. Pagkatapos ay magpapasya ang kernel kung aling gawain ang kailangang isagawa ayon sa priyoridad ng gawain at kabuuang lumipas na oras ng gawain na LED. Kapag nakumpleto ang 1 segundo, pipiliin muli ng kernel ang pinangunahang gawain upang maipatupad dahil mayroon itong mas mataas na priyoridad kaysa sa idle na gawain, maaari din nating sabihin na ang gawain ng LED ay pauna-unahin ang idle na gawain. Kung mayroong higit sa dalawang mga gawain na may parehong priyoridad pagkatapos ay tatakbo sila sa round-robin fashion para sa isang tinukoy na oras.
Sa ibaba ng diagram ng estado habang ipinapakita nito ang paglipat ng hindi tumatakbo na gawain sa tumatakbo na estado.
Ang bawat bagong nilikha na gawain ay napupunta sa Ready state (bahagi ng hindi pagpapatakbo ng estado). Kung ang nilikha na gawain (Gawain1) ay may pinakamataas na priyoridad kaysa sa iba pang mga gawain, pagkatapos ay lilipat ito sa tumatakbo na estado. Kung ang pagpapatakbo ng gawain na ito ay preempts ng iba pang mga gawain, pagkatapos ito ay bumalik sa handa na estado muli. Iba pa kung ang task1 ay naharang sa pamamagitan ng paggamit ng pag-block sa API, kung gayon ang CPU ay hindi makikipag-ugnay sa gawaing ito hanggang sa ang pag-timeout na tinukoy ng gumagamit.
Kung ang Task1 ay nasuspinde sa pagpapatakbo ng estado gamit ang mga Suspend na API, pagkatapos ang Task1 ay pupunta sa Suspendeng estado at hindi ito magagamit muli sa tagapag-iskedyul. Kung ipagpatuloy mo ang Task1 sa nasuspindeng estado pagkatapos ay babalik ito sa handa na estado tulad ng nakikita mo sa block diagram.
Ito ang pangunahing ideya kung paano tatakbo at baguhin ng Mga Gawain ang kanilang mga estado. Sa tutorial na ito, ipapatupad namin ang dalawang gawain sa Arduino Uno gamit ang FreeRTOS API.
Mga madalas na ginamit na termino sa RTOS
1. Gawain: Ito ay isang piraso ng code na naka-iskedyul sa CPU upang maisagawa.
2. Tagapag-iskedyul: Ito ay responsable para sa pagpili ng isang gawain mula sa handa na listahan ng estado sa tumatakbo na estado. Ang mga tagapag-iskedyul ay madalas na ipinatupad upang mapanatili nilang abala ang lahat ng mga mapagkukunan ng computer (tulad ng sa pagbabalanse ng load).
3. Pag-iingat: Ito ay kilos ng pansamantalang nakakagambala sa isang naisakatuparan na gawain na may hangaring alisin ito mula sa tumatakbo na estado nang wala ang kooperasyon.
4. Paglipat ng Konteksto: Sa pag- iingat na nakabatay sa priyoridad, inihahambing ng tagapag -iskedyul ang priyoridad ng pagpapatakbo ng mga gawain na may isang priyoridad ng handa na listahan ng gawain sa bawat systra na nakakagambala . Kung mayroong anumang gawain sa listahan na ang priyoridad ay mas mataas kaysa sa pagpapatakbo ng gawain pagkatapos maganap ang switch ng konteksto. Talaga, sa prosesong ito ang mga nilalaman ng iba't ibang mga gawain ay nai-save sa kani-kanilang stack memory.
5. Mga uri ng mga patakaran sa Pag-iskedyul:
- Preemptive scheduling : Sa ganitong uri ng pag-iiskedyul, tumatakbo ang mga gawain na may pantay na hiwa ng oras nang hindi isinasaalang-alang ang mga priyoridad.
- Pauna- unahang Batay sa Pag-iingat: Ang gawain ng mataas na priyoridad ay tatakbo muna.
- Pag-iskedyul ng Co-operative: Ang paglipat ng konteksto ay magaganap lamang sa kooperasyon ng mga pagpapatakbo ng gawain. Patuloy na tatakbo ang gawain hanggang sa tawagin ang ani ng gawain.
6. Mga Kernel na Bagay: Para sa pag-sign ng gawain na magsagawa ng ilang trabaho, ginagamit ang proseso ng pag-synchronize. Upang maisagawa ang prosesong ito ginagamit ang mga bagay sa Kernel. Ang ilang mga bagay sa Kernel ay Mga Kaganapan, Semaphore, Queue, Mutex, Mailboxes, atbp. Makikita natin kung paano gamitin ang mga bagay na ito sa mga paparating na tutorial.
Mula sa talakayan sa itaas, nakakuha kami ng ilang pangunahing mga ideya tungkol sa konsepto ng RTOS at maaari naming ipatupad ang proyekto ng FreeRTOS sa Arduino. Kaya, magsimula tayo sa pamamagitan ng pag-install ng mga FreeRTOS na aklatan sa Arduino IDE.
Pag-install ng Arduino FreeRTOS Library
1. Buksan ang Arduino IDE at pumunta sa Sketch -> Isama ang Library -> Pamahalaan ang Mga Aklatan . Maghanap para sa FreeRTOS at i-install ang library tulad ng ipinakita sa ibaba.
Maaari mong i-download ang library mula sa github at Idagdag ang.zip file sa Sketch-> Isama ang Library -> Magdagdag ng.zip file.
Ngayon, i-restart ang Arduino IDE. Nagbibigay ang library na ito ng ilang halimbawa ng code, na maaari ding makita sa File -> Mga Halimbawa -> FreeRTOS tulad ng ipinakita sa ibaba.
Isusulat namin ang code mula sa simula upang maunawaan ang gumagana, sa paglaon maaari mong suriin ang mga halimbawa ng mga code at gamitin ang mga ito.
Diagram ng Circuit
Nasa ibaba ang circuit diagram para sa paglikha ng gawain na Blinking LED gamit ang FreeRTOS sa Arduino:
Halimbawa ng Arduino FreeRTOS- Lumilikha ng mga gawain ng FreeRTOS sa Arduino IDE
Tingnan natin ang isang pangunahing istraktura upang magsulat ng isang proyekto ng FreeRTOS.
1. Una, isama ang Arduino FreeRTOS header file bilang
# isama
2. Bigyan ang function na prototype ng lahat ng mga pagpapaandar na sinusulat mo para sa pagpapatupad na nakasulat bilang
walang bisa ang Task1 (walang bisa * pvParameter); walang bisa ang Task2 (walang bisa * pvParameter); .. ….
3. Ngayon, sa walang bisa na pag- andar () pag- andar, lumikha ng mga gawain at simulan ang tagapag-iskedyul ng gawain.
Para sa paglikha ng gawain, ang xTaskCreate () API ay tinawag sa pag- andar ng pag- setup na may ilang mga parameter / argument.
xTaskCreate (TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, walang bisa * pvParameter, UBaseType_t uxPriority, TaskHandle_t * pxCreatedTask);
Mayroong 6 na mga argumento na dapat ipasa habang lumilikha ng anumang gawain. Tingnan natin kung ano ang mga argumentong ito
- pvTaskCode: Ito ay simpleng isang pointer sa pagpapaandar na nagpapatupad ng gawain (sa epekto, ang pangalan lamang ng pagpapaandar).
- pcName: Isang mapaglarawang pangalan para sa gawain. Hindi ito ginagamit ng FreeRTOS. Isinasama ito pulos para sa mga layuning pag-debug.
- usStackDepth: Ang bawat gawain ay may sariling natatanging stack na inilalaan ng kernel sa gawain kapag nilikha ang gawain. Tinutukoy ng halaga ang bilang ng mga salitang maaaring hawakan ng stack, hindi ang bilang ng mga byte. Halimbawa, kung ang stack ay 32-bits ang lapad at ang usStackDepth ay naipasa bilang 100, pagkatapos ay 400 bytes ng stack space ang ilalaan (100 * 4 bytes) sa RAM. Gamitin ito nang matalino dahil ang Arduino Uno ay mayroon lamang mga 2Kbytes ng RAM.
- pvParameter: Parameter ng pag-input ng gawain (maaaring NUL).
- uxPriority: Priority ng gawain (0 ang pinakamababang priyoridad).
- pxCreatedTask: Maaari itong magamit upang maipasa ang isang hawakan sa gawaing nilikha. Ang hawakan na ito ay maaaring magamit upang tukuyin ang gawain sa mga tawag sa API na, halimbawa, baguhin ang priyoridad ng gawain o tanggalin ang gawain (maaaring NUL).
Halimbawa ng paggawa ng gawain
xTaskCreate (task1, "task1", 128, NULL, 1, NULL); xTaskCreate (task2, "task2", 128, NULL, 2, NULL);
Dito, ang Task2 ay may mas mataas na priyoridad at kung gayon muna ang pagpapatupad.
4. Matapos likhain ang gawain, simulan ang tagapag -iskedyul sa isang walang bisa na pag-setup gamit ang vTaskStartScheduler (); API
5. Ang Void loop () na pagpapaandar ay mananatiling walang laman dahil hindi namin nais na magpatakbo ng anumang gawain nang manu-mano at walang hanggan. Sapagkat ang pagpapatupad ng gawain ay pinangangasiwaan ngayon ng scheduler.
6. Ngayon, kailangan naming ipatupad ang mga pagpapaandar ng gawain at isulat ang lohika na nais mong ipatupad sa loob ng mga pagpapaandar na ito. Ang pangalan ng pag-andar ay dapat na kapareho ng unang argument ng xTaskCreate () API.
void task1 (void * pvParameter) { habang (1) { .. ..//your logic } }
7. Karamihan sa mga code ay nangangailangan ng pagkaantala ng pagpapaandar upang ihinto ang pagpapatakbo ng gawain ngunit sa RTOS hindi iminungkahi na gamitin ang pagka- antala () na pagpapaandar habang pinahinto nito ang CPU at samakatuwid ang RTOS ay tumitigil din sa paggana. Kaya't ang FreeRTOS ay may isang kernel API upang harangan ang gawain para sa isang tukoy na oras.
vTaskDelay (const TickType_t xTicksToDelay);
Maaaring magamit ang API na ito para sa mga hangarin na pagkaantala. Ang API na ito ay nagpaantala ng isang gawain para sa isang naibigay na bilang ng mga ticks. Ang aktwal na oras kung saan nananatiling naka-block ang gawain ay nakasalalay sa rate ng tick. Ang pare-pareho na portTICK_PERIOD_MS ay maaaring magamit upang makalkula ang real-time mula sa tick rate.
Nangangahulugan ito kung nais mo ang isang pagkaantala ng 200ms, isulat lamang ang linyang ito
vTaskDelay (200 / portTICK_PERIOD_MS);
Kaya para sa tutorial na ito, gagamitin namin ang mga FreeRTOS API na ito upang magpatupad ng tatlong mga gawain.
Gagamitin ang mga API:
- xTaskCreate ();
- vTaskStartScheduler ();
- vTaskDelay ();
Gawain ang gawain para sa tutorial na ito:
- LED blink sa Digital pin 8 na may dalas ng 200ms
- LED blink sa Digital pin 7 na may 300ms dalas
- I-print ang mga numero sa serial monitor na may dalas na 500ms.
Pagpapatupad ng Gawain ng FreeRTOS sa Arduino IDE
1. Mula sa pangunahing paliwanag sa pangunahing istraktura, isama ang Arduino FreeRTOS header file. Pagkatapos ay gumawa ng mga prototype ng pag-andar. Tulad ng mayroon kaming tatlong mga gawain, kaya gumawa ng tatlong mga pag-andar at ito ay mga prototype.
# isama ang walang bisa na TaskBlink1 (walang bisa * pvParameter); walang bisa ang TaskBlink2 (walang bisa * pvParameter); walang bisa ang Taskprint (walang bisa * pvParameter);
2. Sa pag- andar ng void setup () , simulan ang serial komunikasyon sa 9600 bits bawat segundo at likhain ang lahat ng tatlong mga gawain gamit ang xTaskCreate () API. Sa una, gawin ang mga priyoridad ng lahat ng mga gawain bilang '1' at simulan ang tagapag-iskedyul.
void setup () { Serial.begin (9600); xTaskCreate (TaskBlink1, "Task1", 128, NULL, 1, NULL); xTaskCreate (TaskBlink2, "Task2", 128, NULL, 1, NULL); xTaskCreate (Taskprint, "Task3", 128, NULL, 1, NULL); vTaskStartScheduler (); }
3. Ngayon, ipatupad ang lahat ng tatlong mga pagpapaandar tulad ng ipinakita sa ibaba para sa task1 LED blink.
walang bisa ang TaskBlink1 (walang bisa * pvParameter) { pinMode (8, OUTPUT); habang (1) { digitalWrite (8, TAAS); vTaskDelay (200 / portTICK_PERIOD_MS); digitalWrite (8, LOW); vTaskDelay (200 / portTICK_PERIOD_MS); } }
Katulad nito, ipatupad ang pagpapaandar ng TaskBlink2. Ang pagpapaandar ng Task3 ay isusulat bilang
walang bisa ang Taskprint (walang bisa * pvParameter) { int counter = 0; habang (1) { counter ++; Serial.println (counter); vTaskDelay (500 / portTICK_PERIOD_MS); } }
Ayan yun. Matagumpay naming nakumpleto ang isang proyekto ng FreeRTOS Arduino para sa Arduino Uno. Maaari kang makahanap ng buong code kasama ang isang video sa pagtatapos ng tutorial na ito.
Panghuli, ikonekta ang dalawang LEDs sa digital pin 7 at 8 at i-upload ang code sa iyong Arduino board at buksan ang Serial monitor. Makakakita ka ng isang counter na tumatakbo nang isang beses sa 500ms na may pangalan ng gawain tulad ng ipinakita sa ibaba.
Gayundin, obserbahan ang mga LED, kumikislap sila sa iba't ibang mga agwat ng oras. Subukang maglaro kasama ang priyoridad na argument sa xTaskCreate function. Baguhin ang numero at obserbahan ang pag-uugali sa serial monitor at LEDs.
Ngayon, maaari mong maunawaan ang unang dalawang halimbawa ng mga code kung saan nilikha ang mga gawain na binasa ng analog at digital na basahin. Sa ganitong paraan, makakagawa ka ng mas maraming mga advance na proyekto gamit ang Arduino Uno at mga FreeRTOS API.