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

Message Queues no FreeRTOS: Transporte de Dados e Desacoplamento entre Tasks

As Message Queues (filas de mensagens) são o principal mecanismo do FreeRTOS para transferência segura de dados entre threads, permitindo desacoplar completamente quem produz a informação de quem consome. Diferentemente de semáforos e notificações, que sinalizam eventos, as filas transportam dados estruturados, preservando ordem e integridade.

Arquiteturalmente, uma fila implementa o padrão Produtor–Consumidor, sendo especialmente útil em sistemas onde sensores, ISRs ou protocolos geram dados em uma cadência diferente da lógica de processamento ou armazenamento.

Modelo Conceitual

Uma fila no FreeRTOS é definida por:

  • Tamanho máximo (número de itens).
  • Tamanho de cada item (em bytes).
  • Política FIFO (First-In, First-Out).

Cada envio ou recebimento pode bloquear a task até que haja espaço ou dados disponíveis, eliminando polling e desperdício de CPU.

Criação de uma Fila

#include "FreeRTOS.h"
#include "queue.h"

typedef struct
{
    uint16_t adc_value;
    uint32_t timestamp;
} adc_sample_t;

QueueHandle_t xAdcQueue;

void vInit(void)
{
    xAdcQueue = xQueueCreate(10, sizeof(adc_sample_t));
}

Task Produtora (ou ISR)

void vAdcProducerTask(void *pvParameters)
{
    adc_sample_t sample;

    for (;;)
    {
        sample.adc_value = read_adc();
        sample.timestamp = get_time();

        xQueueSend(xAdcQueue, &sample, portMAX_DELAY);
    }
}

Também é possível enviar dados a partir de uma ISR usando xQueueSendFromISR().

Task Consumidora

void vProcessingTask(void *pvParameters)
{
    adc_sample_t received;

    for (;;)
    {
        if (xQueueReceive(xAdcQueue, &received, portMAX_DELAY) == pdTRUE)
        {
            process_sample(&received);
        }
    }
}

Quando usar Message Queues

Use filas quando:

  • Dados precisam ser transferidos entre tasks.
  • A ordem dos dados é importante.
  • Há desacoplamento entre produção e consumo.
  • Múltiplos produtores ou consumidores existem.

Evite filas quando:

  • Apenas um evento simples precisa ser sinalizado.
  • Comunicação é estritamente ponto-a-ponto e leve (use notifications).
  • O dado pode ser acessado via buffer protegido por mutex.

Vantagens Técnicas

  • Comunicação robusta e segura.
  • Isolamento entre módulos.
  • Facilita escalabilidade.
  • Ideal para pipelines de processamento.

Impacto em Memória

Filas consomem RAM proporcional a:

RAM ≈ (tamanho_do_item × quantidade) + overhead

Em microcontroladores com RAM limitada, esse custo deve ser cuidadosamente planejado.

Armadilhas comuns

  • Criar filas grandes “por segurança”.
  • Enviar ponteiros para dados voláteis.
  • Bloquear tarefas críticas em filas longas.
  • Usar fila como mecanismo de sincronização simples.

Na próxima seção, entraremos nos Software Timers, explicando como executar funções temporizadas sem criar novas tasks e quando eles são preferíveis a vTaskDelay().


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