- Feladat törlése a FreeRTOS Arduino alkalmazásban
- Mi a sor a FreeRTOS-ban?
- Sor létrehozása a FreeRTOS-ban
- Kördiagramm
- FreeRTOS várólista megvalósítása az Arduino IDE-ben
Az előző oktatóanyagban bevezettük a FreeRTOS-t az Arduino Uno-ban, és létrehoztunk egy feladatot a villogó LED-hez. Most ebben az oktatóanyagban többet merítünk az RTOS API-k előzetes koncepcióiban, és megismerhetjük a különböző feladatok közötti kommunikációt. Itt megismerhetjük a Queue adatait egyik feladattól a másikig, és bemutatjuk a sor API-k működését a 16x2 LCD és LDR összekapcsolásával az Arduino Uno-val.
Mielőtt megvitatnánk a várólistákat, nézzünk meg még egy FreeRTOS API-t, amely hasznos lehet a feladatok törlésében, amikor a kijelölt munka befejeződik. Néha a feladatot törölni kell a lefoglalt memória felszabadítása érdekében. Az előző oktatóanyag folytatásaként a vTaskDelete () API függvényt használjuk ugyanabban a kódban az egyik feladat törléséhez. Egy feladat a vTaskDelete () API függvényt használhatja saját maga vagy bármely más feladat törléséhez.
Az API használatához konfigurálnia kell a FreeRTOSConfig.h fájlt. Ezt a fájlt használják a FreeRTOS szabásához az alkalmazásnak megfelelően. Az ütemezési algoritmusok és sok más paraméter megváltoztatására szolgál. A fájl az Arduino könyvtárban található, amely általában a számítógép Dokumentumok mappájában érhető el. Esetemben a \ Documents \ Arduino \ libraries \ FreeRTOS \ src fájlban érhető el , az alábbiak szerint.
Most nyissa meg ezt a fájlt bármilyen szövegszerkesztővel, és keresse meg a #define INCLUDE_vTaskDelete parancsot, és győződjön meg arról, hogy értéke "1" (1 azt jelenti, hogy engedélyezi, és 0: letiltja). Alapértelmezés szerint 1, de ellenőrzi.
Ezt a konfigurációs fájlt gyakran használjuk a következő oktatóanyagokban a paraméterek beállításához.
Most nézzük meg, hogyan törölhetünk egy feladatot.
Feladat törlése a FreeRTOS Arduino alkalmazásban
Egy feladat törléséhez a vTaskDelete () API függvényt kell használnunk. Csak egy érvet igényel.
vTaskDelete (TaskHandle_t pxTaskToDelete);
pxTaskToDelete: A feladatot kell törölni. Ez ugyanaz, mint a 6 -én érv xTaskCreate () API-t. Az előző oktatóanyagban ez az argumentum NULL-ként van beállítva, de bármilyen név használatával átadhatja a feladat tartalmának címét. Mondjuk, ha be akarod állítani a Task2 feladatkezelőjét, amelyet deklarálunk
TaskHandle_t any_name; Példa: TaskHandle_t xTask2Handle;
Most, vTaskCreate () API készlet 6 th argumentumot
xTaskCreate (TaskBlink2, "task2", 128, NULL, 1, & xTask2Handle);
A feladat tartalma az Ön által megadott fogantyúval érhető el.
Ezenkívül egy feladat törölheti magát azáltal, hogy egy érvényes feladatkezelő helyett NULL-t ad át.
Ha törölni akarjuk a 3. feladatot magából a 3. feladatból, akkor meg kell írnod a vTaskDelete (NULL) parancsot; a Task3 függvényen belül, de ha törölni akarja a 3. feladatot a 2. feladatból, írja be a vTaskDelete (xTask3Handle) parancsot; belül a task2 függvény.
A korábbi oktatói kódban a 2. feladat törléséhez magából a task2-ből csak adja hozzá a vTaskDelete (NULL) parancsot; a void TaskBlink2 (void * pvParameters) függvényben. Ekkor a fenti függvény így fog kinézni
void TaskBlink2 (void * pvParameters) { Serial.println (“A 2. feladat fut, és törölni készül”); vTaskDelete (NULL); pinMode (7, OUTPUT); míg (1) { digitalWrite (7, HIGH); vTaskDelay (300 / portTICK_PERIOD_MS); digitalWrite (7, LOW); vTaskDelay (300 / portTICK_PERIOD_MS); } }
Most töltse fel a kódot, és figyelje meg a LED-eket és a soros monitort. Látni fogja, hogy a második LED nem villog, és a task2 törlődik, miután találkozott a törlés API-val.
Tehát ez az API használható az adott feladat végrehajtásának leállítására.
Kezdjük a várólistával.
Mi a sor a FreeRTOS-ban?
A várólista az az adatstruktúra, amely végleges számú rögzített méretű elemet képes tárolni, és a FIFO sémában (First-in First-out) működik. A várólisták feladat-feladat, feladat-megszakítás és megszakítás-feladat kommunikációs mechanizmust biztosítanak.
A sorban elhelyezhető elemek maximális számát „hosszának” nevezzük. Az egyes elemek hosszát és méretét a sor létrehozásakor kell beállítani.
Az itt található FreeRTOS dokumentáció jól szemlélteti a várakozási sor adatátvitelre való felhasználását. Könnyedén megértheti az adott példát.
AA várólisták megértése után próbáljuk megérteni a sor létrehozásának folyamatát, és próbáljuk meg megvalósítani a FreeRTOS kódunkban.
Sor létrehozása a FreeRTOS-ban
Először írja le azt a problémamegállapítást, amelyet a FreeRTOS sor és az Arduino Uno segítségével kell megvalósítani.
Az LDR érzékelő értékét 16 * 2 LCD-re akarjuk nyomtatni. Tehát most két feladat van
- Az 1. feladat az LDR analóg értékeinek beolvasása.
- A 2. feladat az analóg értéket nyomtatja az LCD-re.
Tehát itt a sor játszik szerepet, mert a task1 által generált adatok elküldése a task2 feladatnak. Az 1. feladatban analóg értéket küldünk a várólistára, a 2. feladatban pedig a várólistáról kapjuk.
Három funkció működik a várólistákkal
- Sor létrehozása
- Adatok küldése a várólistára
- Adatok fogadása a várólistáról
A várólista létrehozásához használja az xQueueCreate () függvény API-t. Két érvre van szükség.
xQueueCreate (UBaseType_t uxQueueLength, UBaseType_t uxItemSize);
uxQueueLength: Az elemek maximális száma, amelyeket a létrehozandó sor egyszerre tarthat.
uxItemSize: A sorban tárolható minden adat elem mérete bájtokban.
Ha ez a függvény NULL értéket ad vissza, akkor a sor nem jön létre az elégtelen memória miatt, és ha nem NULL értéket ad vissza, akkor a sor sikeresen létrejön. Tárolja ezt a visszatérési értéket egy változóba, hogy kezelőként használja a sor eléréséhez az alábbiak szerint.
QueueHandle_t queue1; queue1 = xQueueCreate (4, sizeof (int));
Ez létrehoz egy 4 elemű sort az int méretű halom memóriában (minden blokkban 2 bájt), és a visszatérési értéket a queue1 fogantyú változóba tárolja.
2. Adatok küldése a várólistára a FreeRTOS-ban
Az értékek várólistára történő elküldéséhez a FreeRTOS-nak két változata van az API-ról erre a célra.
- xQueueSendToBack (): Adatok küldésére szolgál a sor hátsó részére (farok).
- xQueueSendToFront (): Adatok küldésére szolgál a sor elejére (fejére).
Most , xQueueSend () egyenértékű, és pontosan ugyanaz, mint, xQueueSendToBack ().
Mindezek az API-k 3 argumentumot tartalmaznak.
xQueueSendToBack (QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait);
xQueue: Az a sor, ahová az adatokat küldik (írják). Ez a változó megegyezik az xQueueCreate API visszatérési értékének tárolásával.
pvItemToQueue: A sorba másolandó adatok mutatója.
xTicksToWait: A feladat maximális időtartama blokkolt állapotban kell maradnia ahhoz, hogy megvárja, amíg szabad hely lesz a sorban.
Beállítás xTicksToWait hogy portMAX_DELAY hatására a feladat, hogy meghatározatlan ideig vár (anélkül időtúllépés), feltéve, INCLUDE_vTaskSuspend beállítása 1 FreeRTOSConfig.h mást is használja a makro pdMS_TO_TICKS () kell átalakítani a megadott időt ezredmásodpercben egy meghatározott időben a kullancsokat.
3. Adatok fogadása a várólistáról a FreeRTOS-ban
Elemek várólistáról történő fogadásához (olvasásához) az xQueueReceive () függvényt használják. A beérkezett elem eltávolításra kerül a sorból.
Ennek az API-nak három argumentuma is van.
xQueueReceive (QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait);
Az első és a harmadik argumentum megegyezik az API küldésével. Csak a második érv különbözik.
const pvBuffer: Mutató arra a memóriára, ahová a fogadott adatokat átmásolja.
Remélem, megértette a három API-t. Most ezeket az API-kat megvalósítjuk az Arduino IDE-ben, és megpróbáljuk megoldani a fent leírt problémamegállapítást.
Kördiagramm
Így néz ki a kenyérlapon:
FreeRTOS várólista megvalósítása az Arduino IDE-ben
Kezdjük el írni az alkalmazásunk kódját.
1. Először nyissa meg az Arduino IDE alkalmazást, és mellékelje az Arduino_FreeRTOS.h fejlécfájlt. Most, ha bármilyen kernelobjektumot, például várólistát használ, akkor tartalmazza annak fejlécfájlját. Mivel 16 * 2 LCD-t használunk, a könyvtárat is mellékelje hozzá.
#include #include
2. Inicializálja a sorkezelőt a sor tartalmának tárolásához. Inicializálja az LCD-tűk számát is.
QueueHandle_t queue_1; LiquidCrystal lcd (7, 8, 9, 10, 11, 12);
3. Az érvénytelen beállításban () inicializálja az LCD-t és a soros monitort 9600 baud sebességgel. Hozzon létre egy sort és két feladatot a megfelelő API-k segítségével. Itt létrehozunk egy 4-es méretű sort egész típusú típussal. Hozzon létre egy feladatot azonos prioritásokkal, majd később próbáljon meg játszani ezzel a számmal. Végül indítsa el az ütemezőt az alábbiak szerint.
void setup () { Soros.kezdés (9600); lcdbegin (16, 2); queue_1 = xQueueCreate (4, sizeof (int)); if (queue_1 == NULL) { Serial.println ("Sor nem hozható létre"); } xTaskCreate (TaskDisplay, "Display_task", 128, NULL, 1, NULL); xTaskCreate (TaskLDR, "LDR_task", 128, NULL, 1, NULL); vTaskStartScheduler (); }
4. Most készítsen két funkciót: TaskDisplay és TaskLDR . A TaskLDR funkcióban olvassa el az A0 analóg tűt egy változóban, mivel az LDR az Arduino UNO A0 tűjéhez csatlakozik. Most küldje el a változóban tárolt értéket úgy, hogy továbbítja azt az xQueueSend API-ban, és 1 másodperc múlva küldje el a feladatot a blokkolás állapotához a vTaskDelay () API segítségével az alábbiak szerint.
void TaskLDR (void * pvParameters) { int current_intensity; míg (1) { Soros.println ("1. feladat"); current_intensity = analogRead (A0); Soros.println (jelenlegi_intenzitás); xQueueSend (queue_1, & current_intensity, portMAX_DELAY); vTaskDelay (1000 / portTICK_PERIOD_MS); } }
5. Hasonlóképpen készítsen egy függvényt a TaskDisplay számára, és fogadja az értékeket egy változóban, amelyet átad az xQueueReceive függvénynek. Az xQueueReceive () visszaadja a pdPASS-ot is, ha az adatokat sikeresen meg lehet fogadni a várólistáról, és ha az erõs sor üres, akkor az errQUEUE_EMPTY-t adja vissza.
Most jelenítse meg az értékeket az LCD-n az lcd.print () funkcióval.
void TaskDisplay (void * pvParameters) { int intenzitás = 0; míg (1) { Serial.println ("2. feladat"); if (xQueueReceive (queue_1, & intensitás, portMAX_DELAY) == pdPASS) { lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Intenzitás:"); lcd.setCursor (11, 0); lcd.print (intenzitás); } } }
Ez az. Befejeztük a Queue implementáció kódolási részét. A teljes kód egy működő Videóval a végén található.
Most csatlakoztassa az LCD-t és az LDR-t az Arduino UNO-hoz az áramköri ábra szerint töltse fel a kódot. Nyissa meg a soros monitort, és tartsa be a feladatokat. Látni fogja, hogy a feladatok váltanak, és az LDR értékek a fényintenzitásnak megfelelően változnak.
MEGJEGYZÉS: A FreeRTOS kernel a különböző érzékelőkhöz készített könyvtárak többségét nem támogatja, mivel a könyvtárak belsejében késleltetett funkciók vannak. A késés miatt a CPU teljesen leáll, ezért a FreeRTOS kernel is leáll, és a kód nem hajtódik végre tovább, és rosszul viselkedik. Tehát a könyvtárakat késleltetni kell, hogy működjenek a FreeRTOS-szal.