Table of Contents
- Conceito de Tarefas no FreeRTOS e Estrutura Básica
- 2 – Prioridades, Stack e Boas Práticas na Criação de Tarefas
- Soft Timers no FreeRTOS: Conceito, Arquitetura e Diferenças para Tarefas
- Comunicação entre Soft Timers e Tarefas no FreeRTOS
- 5 – Exemplo Completo: Arquitetura Real com Tarefas e Soft Timers no FreeRTOS
Conceito de Tarefas no FreeRTOS e Estrutura Básica
Em um RTOS (Real-Time Operating System), o conceito central não é mais o superloop, mas sim a tarefa (task). Uma tarefa representa uma unidade independente de execução, com seu próprio contexto de CPU (registradores), sua própria pilha (stack) e um estado bem definido dentro do escalonador (scheduler). No FreeRTOS, tarefas são implementadas como funções C que nunca retornam, pois o controle do fluxo de execução é feito exclusivamente pelo kernel.
Do ponto de vista conceitual, uma tarefa pode ser vista como uma thread cooperativa/preemptiva, dependendo da configuração do sistema. O FreeRTOS utiliza escalonamento preemptivo por prioridade (opcionalmente cooperativo), onde a tarefa de maior prioridade pronta para execução assume o processador. Isso permite modelar sistemas embarcados de forma mais determinística, separando claramente aquisição de dados, processamento, comunicação e controle.
Assinatura de uma tarefa no FreeRTOS
Toda tarefa no FreeRTOS segue a mesma assinatura básica:
void vMinhaTarefa(void *pvParameters)
{
for (;;)
{
/* Código da tarefa */
}
}
Alguns pontos importantes que merecem atenção:
- A função não deve retornar.
- O parâmetro
pvParametersé um ponteiro genérico (void*) que permite passar dados para a tarefa no momento da criação. - O loop infinito não é opcional: ele garante que a tarefa continue viva enquanto o sistema estiver em execução.
- Bloqueios devem ser feitos usando primitivas do RTOS (como
vTaskDelay()), nunca com busy wait.
Criação de tarefas com xTaskCreate()
A API clássica para criação dinâmica de tarefas no FreeRTOS é a função xTaskCreate():
BaseType_t xTaskCreate(
TaskFunction_t pxTaskCode,
const char * const pcName,
const uint16_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask
);
Vamos detalhar cada parâmetro com precisão técnica:
pxTaskCode
Ponteiro para a função que implementa a tarefa.pcName
Nome simbólico da tarefa. Útil para debug, trace e ferramentas como FreeRTOS+Trace.usStackDepth
Tamanho da pilha da tarefa em palavras, não em bytes.
Em arquiteturas 32 bits (como Cortex-M), 1 palavra = 4 bytes.pvParameters
Ponteiro genérico para dados passados à tarefa.uxPriority
Prioridade da tarefa. Quanto maior o valor, maior a prioridade.pxCreatedTask
Retorna um handle da tarefa criada, usado para controle posterior (suspender, deletar, notificar etc.).
Exemplo prático: tarefa de LED
#include "FreeRTOS.h"
#include "task.h"
void vTaskBlink(void *pvParameters)
{
(void) pvParameters;
for (;;)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
vTaskDelay(pdMS_TO_TICKS(500));
}
}
void app_main(void)
{
xTaskCreate(
vTaskBlink,
"Blink",
128,
NULL,
1,
NULL
);
vTaskStartScheduler();
}
Nesse exemplo:
- A tarefa
vTaskBlinkexecuta periodicamente a cada 500 ms. vTaskDelay()coloca a tarefa no estado Blocked, liberando a CPU para outras tarefas.pdMS_TO_TICKS()converte tempo em milissegundos para ticks do sistema, respeitandoconfigTICK_RATE_HZ.
Estados de uma tarefa no FreeRTOS
Internamente, o kernel gerencia cada tarefa em um dos seguintes estados principais:
- Running – tarefa atualmente em execução.
- Ready – pronta para executar, aguardando CPU.
- Blocked – aguardando tempo, evento ou recurso.
- Suspended – explicitamente suspensa pelo usuário.
- Deleted – removida do sistema.
A criação correta das tarefas e o uso adequado de delays e sincronização é o que garante previsibilidade temporal, baixo consumo de CPU e bom comportamento em sistemas embarcados complexos.
Perfeito, vamos avançar mantendo o mesmo rigor técnico e didático.