MCU & FPGA RTOS FreeRTOS na Prática: Threads, Semáforos, Filas, Mutexes, Timers e Boas Práticas em Sistemas Embarcados

FreeRTOS na Prática: Threads, Semáforos, Filas, Mutexes, Timers e Boas Práticas em Sistemas Embarcados

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:

  1. Evento simples (equivalente a um semáforo binário)
  2. Contador (equivalente a um semáforo de contagem)
  3. Flags de bits (similar a event flags)
  4. 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.


0 0 votos
Classificação do artigo
Inscrever-se
Notificar de
guest
0 Comentários
mais antigos
mais recentes Mais votado
Feedbacks embutidos
Ver todos os comentários

Related Post

0
Adoraria saber sua opinião, comente.x