Soft Timers no FreeRTOS: Conceito, Arquitetura e Diferenças para Tarefas
Além das tarefas, o FreeRTOS oferece um mecanismo extremamente importante para sistemas embarcados: os Soft Timers (ou Software Timers). Diferentemente de timers de hardware (TIM, GPT, SysTick), os soft timers são gerenciados pelo kernel, executados no contexto de uma tarefa especial chamada Timer Service Task.
Soft timers são ideais para executar funções curtas e determinísticas de forma periódica ou com atraso, sem a necessidade de criar uma tarefa dedicada.
O que é um Soft Timer
Um soft timer é um objeto do FreeRTOS que dispara uma função de callback quando um determinado tempo expira. Esse tempo é contado em ticks do sistema, da mesma forma que vTaskDelay().
Principais características:
- Executa uma função callback, não uma tarefa
- Não possui stack própria
- Não pode bloquear
- Executa no contexto da Timer Service Task
- Ideal para tarefas periódicas simples
Timer Service Task
Internamente, o FreeRTOS cria uma tarefa dedicada para gerenciar todos os soft timers. Essa tarefa:
- Possui prioridade configurável (
configTIMER_TASK_PRIORITY) - Possui stack própria (
configTIMER_TASK_STACK_DEPTH) - Processa todos os timers do sistema
Isso implica uma consequência arquitetural importante:
todos os callbacks de soft timer compartilham a mesma tarefa.
Portanto, callbacks devem ser:
- rápidos,
- não bloqueantes,
- sem chamadas a
vTaskDelay(),xQueueReceive()bloqueante, ou semáforos bloqueantes.
Tipos de Soft Timers
O FreeRTOS suporta dois tipos principais:
- One-shot timer
Dispara uma única vez após o tempo configurado. - Auto-reload timer
Dispara periodicamente, reiniciando automaticamente após cada expiração.
Criação de um Soft Timer
A API central é xTimerCreate():
TimerHandle_t xTimerCreate(
const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction
);
Detalhando cada parâmetro:
pcTimerName
Nome simbólico do timer (debug).xTimerPeriodInTicks
Período do timer em ticks.uxAutoReloadpdTRUE→ periódicopdFALSE→ one-shotpvTimerID
Ponteiro genérico associado ao timer (muito útil em callbacks).pxCallbackFunction
Função chamada quando o timer expira.
Exemplo prático: Soft Timer periódico
#include "FreeRTOS.h"
#include "timers.h"
void vTimerCallback(TimerHandle_t xTimer)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
}
void app_main(void)
{
TimerHandle_t xLedTimer;
xLedTimer = xTimerCreate(
"LedTimer",
pdMS_TO_TICKS(1000),
pdTRUE,
NULL,
vTimerCallback
);
if (xLedTimer != NULL)
{
xTimerStart(xLedTimer, 0);
}
vTaskStartScheduler();
}
Nesse exemplo:
- O LED é alternado a cada 1 segundo
- Nenhuma tarefa dedicada foi criada
- O callback é curto e determinístico
O que NÃO fazer em callbacks de Soft Timer
Erros clássicos:
- Usar
vTaskDelay() - Usar
xQueueReceive()com bloqueio - Executar loops longos
- Chamar drivers pesados (TCP/IP, filesystem)
Essas ações bloqueiam a Timer Service Task e atrasam todos os timers do sistema, causando jitter e comportamento imprevisível.
Comparação: Tarefa vs Soft Timer
| Característica | Tarefa | Soft Timer |
|---|---|---|
| Possui stack própria | Sim | Não |
| Pode bloquear | Sim | Não |
| Executa código longo | Sim | Não |
| Prioridade própria | Sim | Compartilhada |
| Ideal para | Lógica complexa | Ações periódicas simples |
Soft timers não substituem tarefas, mas reduzem drasticamente a quantidade de tarefas quando usados corretamente.