Notificacions a tasques

Les notificacions a tasques (en anglès Direct to Task Notifications) son un mecanisme propi de FreeRTOS similar a les cues, semàfors i mútex però més simple i, en alguns casos, més eficient (aquest mecanisme pot ser fins a un 45% més ràpid que un mecanisme basat en un semàfor binari).

Si bé els mecanismes introduïts fins ara eren objectes que existien entre les tasques que comunicaven, les notificacions es fan de forma directe entre ISR i tasques o entre dues tasques sense cap objecte addicional.

Això te l’avantatge que s’estalvia memòria, ja que no cal mantenir tanta informació i que el mecanisme és més ràpid, però comporta certes limitacions:

  • No es pot enviar una notificació cap a una ISR, tot i que si que es pot a l’inversa.
  • Només es pot notificar a una sola tasca, ja que es notifica directament la tasca, no cap mecanisme intermig.
  • No es pot emmagatzemar dades, ja que el mecanisme de notificació pot manegar una i només una dada.

Les funcions de notificació a tasques necessiten conèixer el handler de la tasca a enviar, cosa que s’acostuma a fer mitjançant variables globals.

A la Taula següent es resumeixen les crides a les notificacions i a quins mecanismes poden substituir (també hi ha les funcions per ISRs vTaskNotifyGiveFromISR() i xTaskNotifyFromISR()).

Semàfor binarixTaskNotifyGive() / ulTaskNotifyTake()
Semàfor comptadorxTaskNotifyGive() / ulTaskNotifyTake()
Grup d’esdevenimentsxTaskNotify() / xTaskNotifyWait()
Cua (d’un sol element)xTaskNotify() / xTaskNotifyWait()

Exemple de notificació directa a tasques

Al repositori hi ha l’exemple més senzill on es notifica una tasca que es suspèn esperant un esdeveniment. Aquest esdeveniment ve donat per la pulsació d’un dels botons i la notificació per part de la ISR.

static void TaskLedToggle(void *pParameter) {
(void) pParameter;
while (true) {
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
TriggerToggle();
LedToggle();
}
}

El llistat anterior mostra la tasca, que simplement espera agafar la notificació amb la funció ulTaskNotifyTake() per tot seguit fer toggle del LED. Els paràmetres de la crida fan que es netegi el flag un cop s’ha rebut i s’esperi indefinidament.

Cada una de les ISR tant sols notifica la tasca amb la crida corresponent, tal com es veu al llista següent. En aquest cas s’ha de fer servir la variable taskhandle que emmagatzema el handle a la tasca que està esperant la notificació. Aquesta variable és global a tot el codi i està definida al principi del fitxer main.c.

void GPIO_ODD_IRQHandler(void) {
uint32_t aux;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* clear flags */
aux = GPIO_IntGet();
GPIO_IntClear(aux);
vTaskNotifyGiveFromISR(taskhandle, &xHigherPriorityTaskWoken);
/* Awake a task ? */
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

Un pensament sobre “Notificacions a tasques

Deixa un comentari

Fill in your details below or click an icon to log in:

WordPress.com Logo

Esteu comentant fent servir el compte WordPress.com. Log Out /  Canvia )

Google photo

Esteu comentant fent servir el compte Google. Log Out /  Canvia )

Twitter picture

Esteu comentant fent servir el compte Twitter. Log Out /  Canvia )

Facebook photo

Esteu comentant fent servir el compte Facebook. Log Out /  Canvia )

S'està connectant a %s

Aquest lloc utilitza Akismet per reduir els comentaris brossa. Apreneu com es processen les dades dels comentaris.