MCU & FPGA RTOS Arquitetura Orientada a Eventos no FreeRTOS

Arquitetura Orientada a Eventos no FreeRTOS

Queues e Message Passing em Arquiteturas Orientadas a Eventos

Em uma arquitetura orientada a eventos, nem todo evento pode ser representado apenas por um sinal ou flag. Muitos eventos carregam dados associados, e esses dados precisam ser entregues de forma segura, ordenada e determinística. É exatamente nesse ponto que as Queues do FreeRTOS tornam-se fundamentais, funcionando como o principal mecanismo de message passing entre tarefas e entre ISRs e tarefas.

Uma Queue no FreeRTOS é uma estrutura FIFO (First In, First Out) que permite o envio de mensagens tipadas, copiadas por valor, com sincronização automática. Diferente das Task Notifications e Event Groups, as filas acumulam eventos, preservam ordem e garantem que nenhum evento seja perdido enquanto houver espaço disponível.

Do ponto de vista arquitetural, queues são o elo ideal entre produtores rápidos e consumidores mais lentos, criando um desacoplamento temporal que é essencial em sistemas reativos.


Modelo conceitual de filas orientadas a eventos

Em arquiteturas bem projetadas, cada queue deve ter uma responsabilidade clara. Normalmente, uma fila representa um canal de eventos de um tipo específico, como:

  • Amostras de sensores
  • Pacotes de comunicação
  • Comandos de controle
  • Eventos de log ou telemetria

Misturar tipos de mensagens diferentes na mesma fila é um erro comum e prejudica a legibilidade e a segurança do sistema.


Exemplo 1 — Evento com payload (ISR → Task)

typedef struct
{
    uint32_t timestamp;
    uint16_t value;
} SensorEvent_t;

QueueHandle_t sensorQueue;

void vSensorTask(void *pvParameters)
{
    SensorEvent_t evt;

    for (;;)
    {
        if (xQueueReceive(sensorQueue, &evt, portMAX_DELAY) == pdPASS)
        {
            processSensor(evt.value, evt.timestamp);
        }
    }
}

A ISR produtora:

void ADC_IRQHandler(void)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    SensorEvent_t evt;

    evt.timestamp = getSystemTime();
    evt.value = ADC_Read();

    xQueueSendFromISR(sensorQueue, &evt, &xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

Aqui, o evento é a conclusão de uma conversão ADC, e o payload contém os dados associados. A arquitetura permanece orientada a eventos, mas agora com conteúdo estruturado.


Exemplo 2 — Fila como buffer de desacoplamento

void vProducerTask(void *pvParameters)
{
    uint32_t data = 0;

    for (;;)
    {
        xQueueSend(dataQueue, &data, portMAX_DELAY);
        data++;
        vTaskDelay(pdMS_TO_TICKS(10));
    }
}

void vConsumerTask(void *pvParameters)
{
    uint32_t received;

    for (;;)
    {
        xQueueReceive(dataQueue, &received, portMAX_DELAY);
        consumeData(received);
    }
}

Esse padrão cria um pipeline orientado a eventos, onde a produção e o consumo ocorrem em ritmos distintos, sem polling ou busy-wait. A fila atua como amortecedor, absorvendo variações temporais do sistema.


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

Como Criar Tarefas e Soft Timers no FreeRTOS: Guia Prático e Didático para Sistemas EmbarcadosComo Criar Tarefas e Soft Timers no FreeRTOS: Guia Prático e Didático para Sistemas Embarcados

Este artigo apresenta um guia completo e didático sobre como criar e gerenciar tarefas e soft timers no FreeRTOS, explicando conceitos fundamentais de escalonamento, prioridades, dimensionamento de stack e comunicação

0
Adoraria saber sua opinião, comente.x