Modelo de Memória em Sistemas com FreeRTOS: CTB, Heap e Stack
Antes de falar em cálculos e fórmulas, é essencial compreender como o FreeRTOS enxerga a memória internamente e quais estruturas fazem parte desse modelo. Diferente de sistemas operacionais completos, o FreeRTOS não possui MMU (Memory Management Unit) nem isolamento de memória entre tarefas. Todo o modelo é cooperativo sobre um único espaço de endereçamento, o que torna o entendimento do layout de memória absolutamente crítico.
2.1 CTB (Control Block / TCB – Task Control Block)
Cada tarefa criada no FreeRTOS possui uma estrutura chamada TCB (Task Control Block). Em alguns textos técnicos e documentações didáticas, você encontrará o termo CTB (Control Task Block) como forma conceitual, mas no código-fonte do FreeRTOS o nome oficial é TCB.
O TCB é uma estrutura de dados alocada no heap do FreeRTOS e contém todas as informações necessárias para o escalonamento e gerenciamento da tarefa, incluindo:
- Ponteiro para o topo da stack da task
- Estado da tarefa (Ready, Blocked, Suspended, etc.)
- Prioridade atual e prioridade base
- Ponteiros para listas do scheduler
- Nome da task (se configurado)
- Informações de estatística e tracing (se habilitadas)
Do ponto de vista de consumo de memória, é fundamental entender que cada task consome memória duas vezes:
- Uma vez no heap, para o TCB
- Uma vez na stack, para a pilha da própria task
Em um Cortex-M típico, o TCB consome algo entre 80 e 120 bytes, dependendo das configurações habilitadas (configUSE_TRACE_FACILITY, configUSE_STATS_FORMATTING_FUNCTIONS, etc.). Esse valor cresce conforme recursos de debug e tracing são ativados.
2.2 Heap no FreeRTOS
O heap do FreeRTOS é a região de memória usada para alocações dinâmicas feitas pelo kernel, incluindo:
- TCBs de tasks
- Stacks de tasks (quando criadas dinamicamente)
- Semáforos
- Mutexes
- Filas (Queues)
- Event Groups
- Timers de software
- Stream Buffers e Message Buffers
Esse heap não é o mesmo heap da libc (malloc/free padrão), a menos que você configure explicitamente isso. O FreeRTOS implementa seu próprio gerenciador de heap por meio dos arquivos heap_1.c até heap_5.c.
O tamanho total do heap é definido por:
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 32 * 1024 ) )
Esse valor representa toda a memória dinâmica disponível para o kernel. Se ele for subdimensionado, chamadas como xTaskCreate, xQueueCreate ou xSemaphoreCreateMutex falharão silenciosamente se o retorno não for checado — um erro clássico em projetos iniciantes.
Importante:
👉 Heap do FreeRTOS ≠ Heap da aplicação
Buffers estáticos globais (static, global) não consomem heap.
Stacks criadas estaticamente também não consomem heap.
2.3 Stack no FreeRTOS
A stack é a pilha de execução de cada task. É nela que ficam armazenados:
- Variáveis locais
- Endereços de retorno de função
- Contexto salvo durante preempção
- Registros empilhados durante interrupções (dependendo da arquitetura)
Cada task possui sua própria stack, completamente independente das demais. Em sistemas ARM Cortex-M, o empilhamento ocorre em palavras de 32 bits, e o FreeRTOS define o tamanho da stack em unidades de palavras, não em bytes.
Exemplo clássico:
xTaskCreate(
vTaskExample,
"Example",
256,
NULL,
tskIDLE_PRIORITY + 1,
NULL
);
Aqui, 256 significa:
256 palavras × 4 bytes = 1024 bytes de stack
Um erro extremamente comum é assumir que o valor passado está em bytes. Isso leva a stacks 4 vezes menores do que o esperado, causando overflows intermitentes.
2.4 Relação entre Heap, TCB e Stack
O relacionamento entre esses elementos pode ser resumido assim:
- Heap: reserva memória dinâmica para o kernel
- TCB: estrutura de controle alocada no heap
- Stack: memória dedicada à execução da task
Dependendo da forma como a task é criada:
- Criação dinâmica (
xTaskCreate):- TCB → Heap
- Stack → Heap
- Criação estática (
xTaskCreateStatic):- TCB → fornecido pelo usuário
- Stack → fornecida pelo usuário
Essa distinção será crucial quando falarmos de estratégias avançadas de dimensionamento e projetos críticos, como sistemas safety-critical ou aplicações com certificação.