- Брисање задатка у ФрееРТОС Ардуино
- Шта је ред у ФрееРТОС-у?
- Прављење реда у ФрееРТОС-у
- Кружни дијаграм
- Имплементација реда ФрееРТОС у Ардуино ИДЕ
У претходном водичу увели смо ФрееРТОС у Ардуино Уно и креирали задатак за трепћућу ЛЕД диоду. Сада ћемо у овом упутству више заронити у напредне концепте РТОС АПИ-ја и научити о комуникацији између различитих задатака. Овде такође сазнајемо о реду за пренос података са једног задатка на други и демонстрирамо рад АПИ-ја редова повезивањем 16к2 ЛЦД-а и ЛДР-а са Ардуино Уно-ом.
Пре него што разговарамо о редовима, погледајмо још један ФрееРТОС АПИ који је користан при брисању задатака када заврши са додељеним послом. Понекад задатак треба избрисати да бисте ослободили додељену меморију. У наставку претходног водича, користићемо функцију вТаскДелете () АПИ у истом коду за брисање једног од задатака. Задатак може да користи вТаскДелете () АПИ функцију да се избрише или било који други задатак.
Да бисте користили овај АПИ, морате да конфигуришете датотеку ФрееРТОСЦонфиг.х . Ова датотека се користи за прилагођавање ФрееРТОС-а у складу са апликацијом. Користи се за промену алгоритама распореда и многих других параметара. Датотека се може наћи у Ардуино директоријуму који је обично доступан у фасцикли Документи на вашем рачунару. У мом случају је доступан у \ Доцументс \ Ардуино \ либрариес \ ФрееРТОС \ срц као што је приказано доле.
Сада, отворите ову датотеку користећи било који текст едитор и тражити у #дефине ИНЦЛУДЕ_вТаскДелете и уверите се њена вредност је '1' (1 значи омогућити и 0 значи искључити). Подразумевано је 1, али га проверава.
Ову конфигурациону датотеку ћемо често користити у следећим водичима за подешавање параметара.
Сада, да видимо како да избришемо задатак.
Брисање задатка у ФрееРТОС Ардуино
Да бисмо избрисали задатак, морамо да користимо функцију вТаскДелете () АПИ. Потребан је само један аргумент.
вТаскДелете (ТаскХандле_т пкТаскТоДелете);
пкТаскТоДелете: Обриши се ручица задатка. То је исто као и 6 -ог аргумент кТаскЦреате () АПИ. У претходном упутству, овај аргумент је постављен на НУЛЛ, али адресу садржаја задатка можете проследити било којим именом. Рецимо ако желите да поставите ручицу задатка за Таск2 која је декларисана као
ТаскХандле_т било које_име; Пример: ТаскХандле_т кТаск2Хандле;
Сада, у вТаскЦреате () АПИ-сет 6 -ог аргумент као
кТаскЦреате (ТаскБлинк2, "таск2", 128, НУЛЛ, 1, & кТаск2Хандле);
Садржају овог задатка сада се може приступити помоћу ручице коју сте дали.
Такође, задатак се може избрисати прослеђивањем НУЛЛ уместо важећег хватача задатка.
Ако желимо да избришемо задатак 3 из самог задатка 3, треба да напишете вТаскДелете (НУЛЛ); унутар функције Таск3, али ако желите да избришете задатак 3 из задатка 2, онда напишите вТаскДелете (кТаск3Хандле); унутар функције таск2.
У претходном коду туторијала, да бисте избрисали Таск2 из самог таск2 , само додајте вТаскДелете (НУЛЛ); у воид функцији ТаскБлинк2 (воид * пвПараметерс) . Тада ће горња функција изгледати овако
воид ТаскБлинк2 (воид * пвПараметерс) { Сериал.принтлн („Таск2 је покренут и спрема се да га избрише“); вТаскДелете (НУЛЛ); пинМоде (7, ИЗЛАЗ); вхиле (1) { дигиталВрите (7, ХИГХ); вТаскДелаи (300 / портТИЦК_ПЕРИОД_МС); дигиталВрите (7, ЛОВ); вТаскДелаи (300 / портТИЦК_ПЕРИОД_МС); } }
Сада отпремите код и посматрајте ЛЕД диоде и серијски монитор. Видећете да друга ЛЕД лампица сада не трепће и задатак2 се брише након што наиђе на АПИ за брисање.
Дакле, овај АПИ се може користити за заустављање извршавања одређеног задатка.
Сада, кренимо са Редом.
Шта је ред у ФрееРТОС-у?
Ред је структура података која може да садржи коначан број елемената фиксне величине и њоме се управља у ФИФО шеми (Фирст-ин Фирст-оут). Редови пружају механизам комуникације задатак до задатка, задатак до прекида и прекид до задатка.
Максималан број елемената који се у реду може држати назива се његова „дужина“. Дужина и величина сваког елемента постављају се када се креира ред.
Пример примене како се ред користи за пренос података добро је илустрован у ФрееРТОС документацији која се може наћи овде. Можете лако разумети дати пример.
Након разумевања Редова, покушајмо да разумемо процес стварања реда и покушајмо да га применимо у нашем ФрееРТОС коду.
Прављење реда у ФрееРТОС-у
Прво опишите исказ проблема који треба да се примени уз помоћ ФрееРТОС реда и Ардуино Уно.
Вредност ЛДР сензора желимо да одштампамо на ЛЦД екрану 16 * 2. Дакле, сада постоје два задатка
- Задатак 1 је добијање аналогних вредности ЛДР.
- Задатак 2 исписује аналогну вредност на ЛЦД екрану.
Дакле, овде ред игра своју улогу јер за слање података генерисаних таск1 на таск2. У задатку 1 послаћемо аналогну вредност у ред, а у задатку 2 ћемо је примити из реда.
Постоје три функције за рад са редовима
- Прављење реда
- Слање података у ред
- Пријем података из реда
За креирање реда користите АПИ функције кКуеуеЦреате (). Потребна су два аргумента.
кКуеуеЦреате (УБасеТипе_т укКуеуеЛенгтх, УБасеТипе_т укИтемСизе);
укКуеуеЛенгтх: Максималан број ставки које ред који се креира може истовремено да садржи.
укИтемСизе: Величина у бајтовима сваке ставке података која се може сачувати у реду.
Ако ова функција врати НУЛЛ, ред се не креира због недовољне меморије, а ако врати вредност која није НУЛЛ, ред се успешно креира. Спремите ову повратну вредност у променљиву да бисте је користили као хватаљку за приступ реду као што је приказано доле.
КуеуеХандле_т куеуе1; куеуе1 = кКуеуеЦреате (4, сизеоф (инт));
Ово ће створити ред од 4 елемента у меморији гомиле величине инт (2 бајта сваког блока) и сачувати повратну вредност у променљиву ручице куеуе1 .
2. Слање података у ред у ФрееРТОС
Да би вредности послао у ред, ФрееРТОС за ову сврху има 2 варијанте АПИ-ја.
- кКуеуеСендТоБацк (): Користи се за слање података на задњи (реп) реда.
- кКуеуеСендТоФронт (): Користи се за слање података на предњу страну (главу) реда.
Сада , кКуеуеСенд () је еквивалентна, а исто као и, кКуеуеСендТоБацк ().
Сви ови АПИ-ји узимају 3 аргумента.
кКуеуеСендТоБацк (КуеуеХандле_т кКуеуе, цонст воид * пвИтемТоКуеуе, ТицкТипе_т кТицксТоВаит);
кКуеуе: Ручица реда у који се подаци шаљу (записују). Ова променљива је иста као она која се користи за чување повратне вредности кКуеуеЦреате АПИ.
пвИтемТоКуеуе: Показивач на податке који ће се копирати у ред.
кТицксТоВаит: Максимално дуго задатак треба да остане у блокираном стању да сачека да простор постане доступан у реду.
Постављање кТицксТоВаит да портМАКС_ДЕЛАИ ће изазвати задатак да сачека неограничено (без временског од), под условом ИНЦЛУДЕ_вТаскСуспенд је постављен на 1 у ФрееРТОСЦонфиг.х још можете користити макро пдМС_ТО_ТИЦКС () да конвертује време наведен у милисекунди у време наведено у крпеља.
3. Пријем података из реда у ФрееРТОС
За примање (читање) ставке из реда користи се кКуеуеРецеиве (). Ставка која је примљена уклања се из реда.
Овај АПИ такође узима три аргумента.
кКуеуеРецеиве (КуеуеХандле_т кКуеуе, воид * цонст пвБуффер, ТицкТипе_т кТицксТоВаит);
Први и трећи аргумент су исти као и слање АПИ-ја. Само је други аргумент другачији.
цонст пвБуффер: Показивач на меморију у коју ће се копирати примљени подаци.
Надам се да сте разумели три АПИ-ја. Сада ћемо имплементирати ове АПИ-је у Ардуино ИДЕ и покушати да решимо проблем који смо горе описали.
Кружни дијаграм
Ево како изгледа на плочи:
Имплементација реда ФрееРТОС у Ардуино ИДЕ
Почнимо са писањем кода за нашу апликацију.
1. Прво отворите Ардуино ИДЕ и укључите датотеку заглавља Ардуино_ФрееРТОС.х . Ако се користи било који објекат језгра попут реда, укључите његову заглавну датотеку. Како користимо ЛЦД са 16 * 2, укључите и библиотеку за њега.
# инцлуде # инцлуде
2. Иницијализујте хватаљку реда да бисте сачували садржај реда. Такође, иницијализујте бројеве ЛЦД пинова.
КуеуеХандле_т куеуе_1; ЛЦД ЛикуидЦристал (7, 8, 9, 10, 11, 12);
3. У празном подешавању (), иницијализујте ЛЦД и серијски монитор брзином од 9600 бауд. Створите ред и два задатка користећи одговарајуће АПИ-је. Овде ћемо створити ред величине 4 са целобројним типом. Направите задатак са једнаким приоритетима, а касније покушајте да се играте овим бројем. На крају, покрените планер као што је приказано доле.
воид сетуп () { Сериал.бегин (9600); лцд.бегин (16, 2); куеуе_1 = кКуеуеЦреате (4, сизеоф (инт)); иф (куеуе_1 == НУЛЛ) { Сериал.принтлн ("Ред није могуће створити"); } кТаскЦреате (ТаскДисплаи, "Дисплаи_таск", 128, НУЛЛ, 1, НУЛЛ); кТаскЦреате (ТаскЛДР, "ЛДР_таск", 128, НУЛЛ, 1, НУЛЛ); вТаскСтартСцхедулер (); }
4. Сада направите две функције ТаскДисплаи и ТаскЛДР . У функцији ТаскЛДР , прочитајте аналогни пин А0 у променљивој јер имамо ЛДР повезан са А0 пином Ардуино УНО. Сада пошаљите вредност сачувану у променљивој прослеђујући је у кКуеуеСенд АПИ и пошаљите задатак за блокирање стања након 1 секунде помоћу вТаскДелаи () АПИ као што је приказано испод.
воид ТаскЛДР (воид * пвПараметерс) { инт цуррент_интенсити; вхиле (1) { Сериал.принтлн ("Задатак1"); цуррент_интенсити = аналогРеад (А0); Сериал.принтлн (цуррент_интенсити); кКуеуеСенд (куеуе_1, & цуррент_интенсити, портМАКС_ДЕЛАИ); вТаскДелаи (1000 / портТИЦК_ПЕРИОД_МС); } }
5. Слично томе, направите функцију за ТаскДисплаи и примите вредности у променљивој која се прослеђује функцији кКуеуеРецеиве . Такође, кКуеуеРецеиве () враћа пдПАСС ако се подаци могу успешно примити из реда и враћа еррКУЕУЕ_ЕМПТИ ако је ред празан.
Сада прикажите вредности на ЛЦД-у помоћу функције лцд.принт () .
воид ТаскДисплаи (воид * пвПараметерс) { инт интензитет = 0; вхиле (1) { Сериал.принтлн ("Задатак2"); иф (кКуеуеРецеиве (куеуе_1, & интензитет, портМАКС_ДЕЛАИ) == пдПАСС) { лцд.цлеар (); лцд.сетЦурсор (0, 0); лцд.принт ("Интензитет:"); лцд.сетЦурсор (11, 0); лцд.принт (интензитет); } } }
То је то. Завршили смо део кодирања имплементације реда. Комплетни код са функционалним видеом можете пронаћи на крају.
Сада повежите ЛЦД и ЛДР са Ардуино УНО према шеми отпремања кода. Отворите серијски монитор и посматрајте задатке. Видећете да се задаци мењају и вредности ЛДР-а мењају у складу са интензитетом светлости.
НАПОМЕНА: Већина библиотека направљених за различите сензоре не подржава језгро ФрееРТОС због кашњења имплементације функције у библиотекама. Одлагање чини да се ЦПУ потпуно заустави, стога, језгро ФрееРТОС такође престаје да ради и код се неће даље извршавати и почиње да се понаша лоше. Дакле, библиотекама морамо омогућити да без одлагања раде са ФрееРТОС-ом.