$npx -y skills add easyzoom/aix-skills --skill cortex-m-debugUse when debugging Cortex-M microcontrollers, firmware bring-up, SWD/JTAG sessions, faults, startup code, or flashing failures
| 1 | # Cortex-M Debug |
| 2 | |
| 3 | ## Overview |
| 4 | |
| 5 | Use this skill to debug ARM Cortex-M firmware systematically. Start by identifying the exact MCU, board state, debug probe, toolchain, and failure phase, then choose the safest inspection path before changing flash, option bytes, clocks, or startup code. |
| 6 | |
| 7 | ## When To Use |
| 8 | |
| 9 | Use this skill when: |
| 10 | |
| 11 | - The target is a Cortex-M MCU, such as Cortex-M0/M0+/M3/M4/M7/M23/M33/M55/M85. |
| 12 | - The user mentions SWD, JTAG, J-Link, ST-Link, CMSIS-DAP, OpenOCD, pyOCD, GDB, or vendor IDE debug. |
| 13 | - Firmware does not boot, cannot be flashed, stops in `Reset_Handler`, hits HardFault, or has no UART/log output. |
| 14 | - The task involves vector tables, startup files, linker scripts, clocks, reset behavior, or fault registers. |
| 15 | |
| 16 | Do not use this skill when: |
| 17 | |
| 18 | - The target is Cortex-R (use `cortex-r5-debug`), embedded Linux, RISC-V, AVR, ESP8266, ESP32 Xtensa, or another non-Cortex-M architecture. |
| 19 | - The user only needs application-level C code review with no target-specific debug context. |
| 20 | - The request is to modify production firmware or security configuration before collecting baseline evidence. |
| 21 | |
| 22 | ## First Questions |
| 23 | |
| 24 | Ask for the minimum context needed: |
| 25 | |
| 26 | - MCU part number and board name. |
| 27 | - Core family if known, such as Cortex-M0+, M4F, M7, or M33. |
| 28 | - Current symptom: cannot connect, cannot flash, no boot, crash, hang, wrong peripheral behavior, or no logs. |
| 29 | - Debug probe: J-Link, ST-Link, CMSIS-DAP, DAPLink, ULINK, or onboard probe. |
| 30 | - Debug transport: SWD or JTAG. |
| 31 | - Toolchain and workflow: OpenOCD, pyOCD, J-Link GDB Server, STM32CubeIDE, Keil, IAR, PlatformIO, Zephyr, RTOS, or bare metal. |
| 32 | - Available artifacts: ELF, MAP file, linker script, startup file, OpenOCD config, boot log, fault dump, or GDB transcript. |
| 33 | |
| 34 | ## Workflow |
| 35 | |
| 36 | 1. Classify the failure phase. |
| 37 | Use these buckets: probe cannot connect, flash/download fails, reset/startup fails, runtime fault, peripheral bring-up fails, or low-power/wakeup fails. |
| 38 | |
| 39 | 1. Establish a non-destructive debug connection. |
| 40 | Prefer connect-under-reset when firmware may reconfigure SWD pins, enter low power, or crash immediately. |
| 41 | |
| 42 | 1. Confirm target identity. |
| 43 | Read the MCU ID, core type, flash size, RAM size, and debug probe target report before trusting assumptions. |
| 44 | |
| 45 | 1. Load symbols before changing target state. |
| 46 | In GDB, load the ELF symbols first so addresses, functions, and sections are meaningful. |
| 47 | |
| 48 | 1. Collect baseline evidence. |
| 49 | Record reset PC, SP, vector table address, fault registers if applicable, and whether the image in flash matches the expected build. |
| 50 | |
| 51 | 1. Pick the narrowest next check. |
| 52 | Do not jump from "no boot" directly to rewriting startup code. Verify reset vector, memory map, clock assumptions, and fault state first. |
| 53 | |
| 54 | 1. Ask before destructive actions. |
| 55 | Chip erase, option byte changes, mass erase, readout protection changes, boot mode changes, and flash loader changes require explicit user approval. |
| 56 | |
| 57 | ## Debug Connection Checklist |
| 58 | |
| 59 | For SWD/JTAG connection issues, check: |
| 60 | |
| 61 | - Probe driver and permissions. |
| 62 | - Correct target voltage and common ground. |
| 63 | - SWDIO, SWCLK, RESET, GND, and VTref wiring. |
| 64 | - Probe speed. Lower the clock for unstable boards, for example 100 kHz to 1 MHz. |
| 65 | - Reset strategy: normal reset, hardware reset, connect-under-reset, or halt-after-reset. |
| 66 | - Whether firmware disables debug pins, changes clocks too early, enters sleep, or locks the chip. |
| 67 | - Whether readout protection, secure debug, TrustZone, or option bytes block access. |
| 68 | |
| 69 | Useful command patterns: |
| 70 | |
| 71 | ```bash |
| 72 | openocd -f interface/stlink.cfg -f target/stm32f4x.cfg |
| 73 | arm-none-eabi-gdb build/firmware.elf |
| 74 | JLinkGDBServer -device <device> -if SWD -speed 4000 |
| 75 | pyocd list |
| 76 | pyocd gdbserver --target <target> |
| 77 | ``` |
| 78 | |
| 79 | ## GDB Baseline |
| 80 | |
| 81 | After GDB connects, collect evidence before editing code: |
| 82 | |
| 83 | ```gdb |
| 84 | target extended-remote :3333 |
| 85 | monitor reset halt |
| 86 | info registers |
| 87 | x/8wx 0x00000000 |
| 88 | x/8wx 0x08000000 |
| 89 | info files |
| 90 | bt |
| 91 | ``` |
| 92 | |
| 93 | For Cortex-M, pay special attention to: |
| 94 | |
| 95 | - `sp`: should point into valid RAM after reset. |
| 96 | - `pc`: should point to `Reset_Handler` or a valid flash/RAM execution address. |
| 97 | - Vector table word 0: initial stack pointer. |
| 98 | - Vector table word 1: reset handler address with Thumb bit set. |
| 99 | - `xpsr`: Thumb state and exception state. |
| 100 | - `VTOR`: vector table location on cores that implement it. |
| 101 | |
| 102 | ## Fault Debugging |
| 103 | |
| 104 | When the target hits HardFault, BusFault, UsageFault, or MemManage: |
| 105 | |
| 106 | 1. Stop and preserve the fault state. |
| 107 | Do not reset before reading fault registers. |
| 108 | |
| 109 | 1. Read core fault registers. |
| 110 | Common System Control Block addresses: |
| 111 | |
| 112 | ```text |
| 113 | SCB_CFSR = 0xE000ED28 |
| 114 | SCB_HFSR = 0xE000ED2C |
| 115 | SCB_DFSR = 0xE000ED30 |
| 116 | SCB_MMFAR = 0xE000ED34 |
| 117 | SCB_BFAR = 0xE000ED38 |
| 118 | SCB_AFSR = 0xE000ED3C |
| 119 | SCB_SHCSR = 0xE000ED24 |
| 120 | ``` |
| 121 | |
| 122 | 1. In GDB, read them: |
| 123 | |
| 124 | ```gdb |
| 125 | x/wx 0xE000ED28 |
| 126 | x/wx 0xE000ED2C |
| 127 | x/wx 0xE000ED34 |
| 128 | x/wx 0xE000ED38 |
| 129 | info registers |
| 130 | bt |
| 131 | ``` |
| 132 | |
| 133 | 1. Decode the stacked frame. |