Task Notifications: Comunicação Rápida e Eficiente entre Threads
As Task Notifications são um dos mecanismos mais eficientes do FreeRTOS para sinalização e comunicação direta entre tasks. Elas funcionam como um canal de 32 bits embutido em cada task, eliminando a necessidade de estruturas auxiliares como semáforos ou filas quando a comunicação ocorre ponto a ponto. Do ponto de vista arquitetural, são frequentemente a melhor escolha para sinalizar eventos simples entre threads ou entre uma ISR e uma task.
Cada task possui internamente um campo de notificação e um estado associado. Quando uma notificação é enviada, o kernel pode automaticamente desbloquear a task alvo, tornando o mecanismo extremamente rápido — muitas vezes mais rápido que semáforos binários e filas de tamanho 1.
Modelo Conceitual
Uma notificação pode ser usada de quatro formas principais:
- Evento simples (equivalente a um semáforo binário)
- Contador (equivalente a um semáforo de contagem)
- Flags de bits (similar a event flags)
- Transporte de valor (inteiro de 32 bits)
Essa versatilidade torna as task notifications um mecanismo coringa, desde que aplicadas corretamente.
Exemplo: Task aguardando notificação
#include "FreeRTOS.h"
#include "task.h"
static TaskHandle_t xWorkerTaskHandle = NULL;
/**
* @brief Task que aguarda um evento para executar uma ação.
*/
void vWorkerTask(void *pvParameters)
{
uint32_t ulNotificationValue;
for (;;)
{
xTaskNotifyWait(
0x00, // Bits a limpar ao entrar
0xFFFFFFFF, // Bits a limpar ao sair
&ulNotificationValue,
portMAX_DELAY // Bloqueia indefinidamente
);
process_event(ulNotificationValue);
}
}
Enviando uma notificação a partir de outra Task
xTaskNotify(
xWorkerTaskHandle,
0x01,
eSetBits
);
Enviando notificação a partir de uma ISR
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xTaskNotifyFromISR(
xWorkerTaskHandle,
0x01,
eSetBits,
&xHigherPriorityTaskWoken
);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
Quando usar Task Notifications
Use Task Notifications quando:
- Existe comunicação direta entre duas tasks.
- O dado é simples (evento, contador ou flags).
- Desempenho e baixo overhead são críticos.
- O evento vem de uma ISR e acorda uma única task.
Evite Task Notifications quando:
- Uma task precisa notificar múltiplas tasks.
- Há necessidade de buffer de múltiplas mensagens.
- A comunicação é muitos-para-muitos.
Vantagens Técnicas
- Menor uso de RAM (não há objeto externo).
- Menor latência.
- Código mais simples.
- Ideal para sistemas de tempo real estrito.
Armadilhas comuns
- Esquecer que cada task tem apenas um slot de notificação.
- Usar notificações onde filas seriam mais apropriadas.
- Sobrescrever notificações sem tratá-las corretamente.
Na prática, muitos projetos usam semáforos e filas por hábito, quando task notifications seriam mais rápidas, mais simples e mais seguras.
Na próxima seção, evoluiremos o conceito para Event Groups (Event Flags), que permitem sincronização baseada em múltiplos eventos simultâneos.