MCU & FPGA RTOS ISR + RTOS na Prática com FreeRTOS

ISR + RTOS na Prática com FreeRTOS

Comunicação entre ISR e Tasks: qual mecanismo usar e quando

No FreeRTOS, a ISR não processa eventos, ela sinaliza eventos. A forma como essa sinalização ocorre define diretamente o desempenho, a latência e a robustez do sistema. O kernel oferece múltiplos mecanismos para comunicação ISR → Task, cada um com características muito distintas. Escolher o mecanismo errado é uma das principais causas de sistemas instáveis ou com desempenho ruim.

Nesta seção, vamos analisar quando e por que usar cada mecanismo, sempre do ponto de vista prático.


4.1 Semáforos binários: sinalização simples de eventos

O semáforo binário é o mecanismo mais direto para sinalizar que “algo aconteceu”. Ele não carrega dados, apenas um evento.

Uso típico:

  • Botão pressionado
  • Interrupção de fim de conversão do ADC
  • Evento externo simples

Exemplo clássico: botão gerando interrupção e acordando uma task.

ISR:

void EXTI0_IRQHandler(void)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    /* Limpa flag do EXTI */

    xSemaphoreGiveFromISR(xButtonSemaphore, &xHigherPriorityTaskWoken);

    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

Task:

void vButtonTask(void *pvParameters)
{
    for (;;)
    {
        if (xSemaphoreTake(xButtonSemaphore, portMAX_DELAY) == pdTRUE)
        {
            /* Trata o evento do botão */
        }
    }
}

Vantagens:

  • Simples
  • Baixíssima sobrecarga
  • Ideal para eventos pontuais

Limitações:

  • Não transporta dados
  • Eventos podem ser perdidos se ocorrerem rapidamente em sequência

4.2 Filas (Queues): eventos com dados

Quando a ISR precisa entregar dados para uma task, o mecanismo correto é a fila. A fila permite armazenar múltiplos eventos, mantendo ordem FIFO (First In, First Out).

Uso típico:

  • Recepção de bytes via UART
  • Amostras de ADC
  • Eventos estruturados

ISR (exemplo UART RX):

void USART1_IRQHandler(void)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    uint8_t rxByte;

    rxByte = USART1->DR;

    xQueueSendFromISR(uartRxQueue, &rxByte, &xHigherPriorityTaskWoken);

    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

Task:

void vUartTask(void *pvParameters)
{
    uint8_t byte;

    for (;;)
    {
        if (xQueueReceive(uartRxQueue, &byte, portMAX_DELAY) == pdTRUE)
        {
            /* Processa byte recebido */
        }
    }
}

Vantagens:

  • Transporta dados
  • Mantém ordem
  • Suporta burst de eventos

Desvantagens:

  • Mais custo de memória
  • Overhead maior que notificações

4.3 Notificações diretas de task: o mecanismo mais eficiente

As Task Notifications são o mecanismo mais rápido e leve do FreeRTOS para comunicação ISR → Task. Elas utilizam um campo interno da estrutura da task, evitando alocação dinâmica ou buffers intermediários.

Uso típico:

  • Sinalização de eventos frequentes
  • Sincronização rápida
  • Substituição de semáforo binário

ISR:

void TIM2_IRQHandler(void)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    vTaskNotifyGiveFromISR(xControlTaskHandle, &xHigherPriorityTaskWoken);

    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

Task:

void vControlTask(void *pvParameters)
{
    for (;;)
    {
        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);

        /* Executa rotina de controle */
    }
}

Vantagens:

  • Extremamente rápido
  • Baixíssimo uso de memória
  • Ideal para sistemas tempo real estritos

Limitações:

  • Um canal por task
  • Não serve para múltiplos consumidores

4.4 Event Groups: múltiplos eventos e sincronização complexa

Os Event Groups permitem sinalizar múltiplos eventos simultaneamente usando bits. São úteis quando uma task precisa aguardar combinações de eventos.

Uso típico:

  • Estado de múltiplos periféricos
  • Sincronização entre ISR e várias tasks

ISR:

xEventGroupSetBitsFromISR(
    systemEventGroup,
    EVENT_ADC_DONE,
    &xHigherPriorityTaskWoken
);

Task:

xEventGroupWaitBits(
    systemEventGroup,
    EVENT_ADC_DONE | EVENT_UART_DONE,
    pdTRUE,
    pdTRUE,
    portMAX_DELAY
);

Vantagens:

  • Expressivo
  • Bom para estados complexos

Desvantagens:

  • Não transporta dados
  • Overhead maior

Resumo arquitetural

MecanismoDadosVelocidadeUso típico
Semáforo binárioNãoAltaEvento simples
QueueSimMédiaComunicação com dados
NotificaçãoLimitadoMuito altaSinalização rápida
Event GroupNãoMédiaEstados múltiplos

Na próxima seção, vamos tratar de prioridades de interrupção, configMAX_SYSCALL_INTERRUPT_PRIORITY e erros clássicos em Cortex-M, um dos pontos mais críticos e mal compreendidos do FreeRTOS.


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