MCU & FPGA RTOS Dimensionamento de Pilha (Stack) e Heap no FreeRTOS

Dimensionamento de Pilha (Stack) e Heap no FreeRTOS

Stack no FreeRTOS: Funcionamento Interno, Cortex-M e Impacto das Interrupções

Nesta seção entramos no nível microarquitetural da stack, algo essencial para dimensionamento correto. Muitos problemas atribuídos ao FreeRTOS, na prática, são erros de entendimento do modelo de empilhamento do Cortex-M combinado com o escalonador.


3.1 O que realmente vai para a stack de uma task

A stack de uma task no FreeRTOS não armazena apenas variáveis locais. Em um Cortex-M, ela precisa comportar, de forma segura:

  1. Variáveis locais das funções
  2. Endereços de retorno (call stack)
  3. Contexto salvo pelo FreeRTOS durante troca de contexto
  4. Contexto salvo automaticamente pelo hardware em interrupções
  5. Chamadas de funções de biblioteca (printf, sprintf, lwIP, etc.)

Esse último item é o mais subestimado. Funções como printf, snprintf, conversões de ponto flutuante e rotinas de rede podem consumir centenas ou até milhares de bytes de stack.


3.2 Empilhamento automático no Cortex-M (hardware stacking)

Quando ocorre uma interrupção no Cortex-M, o próprio hardware empilha automaticamente os seguintes registradores:

  • R0
  • R1
  • R2
  • R3
  • R12
  • LR
  • PC
  • xPSR

Isso totaliza:

8 registradores × 4 bytes = 32 bytes

Se o FPU estiver habilitado (Cortex-M4F, M7, M33 com FPU), e se a interrupção utilizar ponto flutuante, o hardware também empilha:

  • S0 a S15
  • FPSCR

O que adiciona:

18 palavras × 4 bytes = 72 bytes

Portanto, uma única interrupção pode consumir até 104 bytes de stack automaticamente, sem contar o empilhamento adicional feito pelo compilador dentro da ISR.


3.3 Stack da Task vs Stack da Interrupção

Aqui está um ponto crítico que gera confusão.

  • Interrupções NÃO usam a stack da task
  • Elas usam a Main Stack Pointer (MSP)
  • As tasks usam a Process Stack Pointer (PSP)

O FreeRTOS configura isso de forma explícita:

  • MSP → usado por ISRs
  • PSP → usado pelas tasks

Porém, durante uma troca de contexto, o FreeRTOS salva parte do contexto da task na stack da própria task, incluindo:

  • Registradores R4 a R11
  • Ponteiros internos do kernel

Isso adiciona mais consumo temporário à stack da task, principalmente em sistemas com alta taxa de preempção.


3.4 Fórmula prática para estimativa inicial de stack

Uma forma profissional de iniciar o dimensionamento de stack é decompor o consumo:

\[
\text{Stack}{task} =
S
{locais} +
S_{chamadas} +
S_{contexto} +
S_{margem}
\]

Onde:

  • \(S_{locais}\): variáveis locais máximas (structs, arrays)
  • \(S_{chamadas}\): profundidade máxima de chamadas
  • \(S_{contexto}\): contexto salvo pelo RTOS
  • \(S_{margem}\): fator de segurança (30–50%)

Exemplo prático:

  • Variáveis locais: 256 bytes
  • Cadeia de chamadas: 4 níveis × 64 bytes = 256 bytes
  • Contexto RTOS: ~100 bytes
  • Margem de segurança (40%): ~240 bytes

\[
\text{Stack total} \approx 850 \text{ bytes}
\]

Convertendo para palavras (Cortex-M):

\[
850 / 4 \approx 212 \text{ words}
\]

Arredonda-se para:

#define STACK_TASK_EXAMPLE  256

3.5 Erros clássicos de dimensionamento de stack

Alguns padrões de erro recorrentes em projetos reais:

  • Usar printf em tasks com stack de 128 words
  • Criar arrays locais grandes (uint8_t buffer[1024])
  • Usar recursão (quase sempre inviável em RTOS)
  • Ativar FPU sem revisar stacks
  • Copiar exemplos genéricos sem medir consumo real

Todos esses levam a stack overflow silencioso, corrupção de heap e comportamento errático.


3.6 Detecção e medição de stack no FreeRTOS

O FreeRTOS fornece mecanismos robustos para medir stack real usada:

  • uxTaskGetStackHighWaterMark()
  • configCHECK_FOR_STACK_OVERFLOW
  • vApplicationStackOverflowHook()

Exemplo:

UBaseType_t watermark;

watermark = uxTaskGetStackHighWaterMark(NULL);
/* Retorna o menor valor já observado de stack livre */

Se o valor retornado for, por exemplo, 40, significa que apenas 40 words sobraram no pior caso, indicando stack muito justa.


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