FreeRTOS: taskų stabdymas/paleidimas

Posted: 2016-12-19 in Darbeliai
Žymos:, ,

Aš po truputuką vis dirbu ir krapštausi prie savo gudraus apšvietimo. Kol kas vis dar nesigailiu 😀 Kaip bus vėliau — matysim. Bet pradėjau po truputuką galvot, kaip visą tą plokščių ir kitų laidų bardaką reikės junginėt. Na, fiziškai, gaminti visus valdymo skydus. Iš savo patirties su visokiais maršrutizatoriais žinau vieną dalyką: ateini prie kokio nors kabančio divaiso ir galvok, čia tas ar ne tas, kurio reikia.

Problemos sprendimas yra ganėtinai paprastas, tereikia galimybės kuriam nors įrenginiu pasiųsti žinelę, kad jis kaip nors fiziškai atsilieptų. Tas „fiziškai“ tai galėtų papypsėt arba lempelę pamirksėt. Pypsėjimo aš tikrai nedarysiu, o štai lempelių savo plokštėse nusimačiau tris. Žalia lempelė mirksi visą laiką. Tai tiesiog reiškia, kad FreeRTOS sėkmingai sukasi, niekas neužlūžo ir neužstrigo. Jei užsidegtų raudona, tai reikštų, kad kodas papuolė į vieną iš kritinių handlerių. Stekas ten gal užtrūko, hardwaras kur nors susipainiojo ar dar kažkas. Dar įdėjau mėlyną dioduką būtent „atsiliepimui“.

FreeRTOS logotipas | Darau, blėĮsivaizduokim scenarijų, kad aš padariau valdymo skydelį, visus valdiklius sudėliojau, sujungiau CAN laidelius, paguldžiau kažkur Avietę. Nu ir noriu pradėti dirbti, junginėti reles, jungtukus ir panašiai. Įrenginių programinę konfigūraciją darysiu greičiausiai iš anksto, bent jau priskirsiu jiems adresus. Kas toliau? O toliau aš tiesiog galiu kiekvienam adresuotam įrenginiu nusiųsti žinelę, kad jis mėlynu diodu kelis kartus pamirksėtų. Tada pamatau, kuris mirksi, ir žinau, kad jam reikia laidelius junginėt.

FreeRTOS tam yra funkcijos vTaskSuspend ir vTaskResume. Joms reikia perduoti sukurto tasko „rankenėlę“ (handler). Dar svarbu tai, kad aš savo projekte naudoju paprasčiausią FreeRTOS atminties modelį: viskas inicializuojama vieną kartą ir atmintis negali būti išlaisvinta. Reiškia, kad mirksiuko taskas irgi bus sukurtas iš anksto, o ne kuriamas kaskart atėjus žinelei ir paskui naikinamas. Taigi taskas visą laiką turi „miegoti“ ir būti pažadintas tik atėjus žinelei. Mano minėtos funkcijos gali būti kviečiamos ir iš tasko vidaus su NULL „rankenėle“. Taigi štai paties tasko kodas:

static void vTaskBlueBlink(void *pvParameters)
{
	uint8_t i;
	while(1) {
		vTaskSuspend(NULL);
		for (i=0; i<5; i++) {
			LED_ON(LED_BLUE);
			vTaskDelay(500);
			LED_OFF(LED_BLUE);
			vTaskDelay(500);
		}
	}
}

Taskas įšoka į savo amžiną ciklą ir iškart save užsimigdo. Iš išorės atėjusi mirksėjimo komanda taską pažadina, jis penkis kartus mirkteli diodu, for ciklas baigiasi ir taskas vėl užsimigdo.

Šis taskas inicializuojamas tokia štai eilute, kurios paskutinis argumentas yra handleris į ką tik sukurtą taską:

xTaskCreate(vTaskBlueBlink, ( const char * ) "L8", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, &blue_blink_task);

Handlerio tipas yra TaskHandle_t.

Na, o taskas pažadinamas paprasčiausiai taip:

vTaskResume(blue_blink_task);

Kad funkcijos vTaskSuspend ir vTaskResume veiktų, FreeRTOS konfigūraciniame headeryje turi būti deklaruotas INCLUDE_vTaskSuspend ir nustatytas į vienetuką.

Va tiek šiam kartui trumpai. Problema, kurios neišsprendžiau — gražus kodo organizavimas, kad tas blue_blink_task kintamasis nebūtų kažkoks tai uberglobalus. Nors funkcionalumui tas įtakos neturi.

Advertisements

Parašykite komentarą

Įveskite savo duomenis žemiau arba prisijunkite per socialinį tinklą:

WordPress.com Logo

Jūs komentuojate naudodamiesi savo WordPress.com paskyra. Atsijungti / Keisti )

Twitter picture

Jūs komentuojate naudodamiesi savo Twitter paskyra. Atsijungti / Keisti )

Facebook photo

Jūs komentuojate naudodamiesi savo Facebook paskyra. Atsijungti / Keisti )

Google+ photo

Jūs komentuojate naudodamiesi savo Google+ paskyra. Atsijungti / Keisti )

Connecting to %s