Skip to content

rtos/FreeRTOS: support ARMv8-M (Cortex-M33) stacking#151

Open
anujdeshpande wants to merge 2 commits into
raspberrypi:rpi-commonfrom
anujdeshpande:pr-armv8m-cortex-m33
Open

rtos/FreeRTOS: support ARMv8-M (Cortex-M33) stacking#151
anujdeshpande wants to merge 2 commits into
raspberrypi:rpi-commonfrom
anujdeshpande:pr-armv8m-cortex-m33

Conversation

@anujdeshpande
Copy link
Copy Markdown

@anujdeshpande anujdeshpande commented May 21, 2026

Problem

info threads / per-task backtraces are garbage when debugging FreeRTOS on ARMv8-M targets (e.g. RP2350 Cortex-M33, RP2350_ARM_NTZ port). OpenOCD's FreeRTOS support only knows the classic Cortex-M3/M4F stack layouts.

Originally reported downstream against the Flipper One MCU firmware: flipperdevices/flipperone-mcu-firmware#51

Two distinct issues:

  1. Wrong stack layout. ARMv8-M ports save an extra PSPLIM + EXC_RETURN ahead of R4–R11 (and R4–R11 follow EXC_RETURN rather than preceding it), so every register offset differs from rtos_standard_cortex_m4f*. From the saved pxTopOfStack:

    0x00  PSPLIM
    0x04  EXC_RETURN (software-saved LR)
    0x08  R4 .. 0x24 R11
    (0x28 S16..S31, only when the task used the FPU - extended frame)
    <hardware frame: R0..R3, R12, LR, PC, xPSR (+ S0..S15, FPSCR)>
    
  2. Wrong frame-type selection. The cm4_fpu_enabled probe (fp_feature + CPACR) does not reliably report the FPU on ARMv8-M cores, so the basic layout was applied to every task — FPU-extended-frame tasks reconstructed as pc=lr=xpsr=0, while basic-frame tasks happened to look fine.

Fix

  • Add rtos_standard_cortex_m33_stacking (basic) and rtos_standard_cortex_m33_fpu_stacking (extended FPU frame) with correct offsets.
  • In freertos.c, handle ARMv8-M first and pick FPU vs basic purely from bit 4 of the software-saved EXC_RETURN at offset 0x04 (which these ports always stack), independent of the unreliable FPU detection.

Testing

Tested on an RP2350 (Cortex-M33, FPU enabled) running a FreeRTOS application built with the RP2350_ARM_NTZ port, debugged over a CMSIS-DAP probe with -rtos FreeRTOS:

  • Before: tasks whose saved context used the extended (FPU) frame were decoded with the basic-frame offsets and came back as pc=lr=xpsr=0 (e.g. a task whose real PC was at frame offset 0x80 was instead read from 0x40); tasks with a basic frame happened to decode correctly.
  • After: every task — both basic-frame and FPU-extended-frame — reports a correct, fully symbolized backtrace via thread apply all bt.

Builds with --enable-cmsis-dap-v2.

ARMv8-M FreeRTOS ports (e.g. the RP2350_ARM_NTZ port used on the
RP2350's Cortex-M33) save a different software frame than the classic
Cortex-M3/M4F ports the existing stackings assume. From the saved
pxTopOfStack the layout is:

    0x00  PSPLIM
    0x04  EXC_RETURN (software-saved LR)
    0x08  R4 .. 0x24 R11
    (0x28 S16..S31, only when the task used the FPU - extended frame)
    <hardware frame: R0..R3, R12, LR, PC, xPSR (+ S0..S15, FPSCR)>

i.e. two extra leading words (PSPLIM, EXC_RETURN) and R4-R11 follow
EXC_RETURN instead of preceding it, so every register offset differs
from rtos_standard_cortex_m4f*. Add rtos_standard_cortex_m33_stacking
(basic frame) and rtos_standard_cortex_m33_fpu_stacking (extended FPU
frame) with the correct offsets and xPSR-based stack alignment.

Signed-off-by: Anuj Deshpande <anuj@makerville.io>
On ARMv8-M targets (Cortex-M33/M23) handle stack reconstruction before
the existing armv7m FPU probe and choose the extended (FPU) vs basic
layout from bit 4 of the software-saved EXC_RETURN at offset 0x04,
which these ports always stack.

This must not be gated on the cm4_fpu_enabled detection
(fp_feature + CPACR): that probe does not reliably report the FPU on
ARMv8-M cores, so relying on it silently reconstructed every
FPU-extended-frame task with the basic layout, yielding pc=lr=xpsr=0
and a garbage call stack, while basic-frame tasks looked fine.

Tested on an RP2350 (RP2350_ARM_NTZ port) with a CMSIS-DAP probe: all
FreeRTOS tasks - both basic and FPU-extended frames - now produce
correct backtraces via "thread apply all bt".

Signed-off-by: Anuj Deshpande <anuj@makerville.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant