Cannot Debug or Attach to STM32F4 Using Probe-RS

Hello,

I am new to the Rust lang itself, and by extension writing Rust intended for embedded targets. I have followed some tutorials online and have written a simple program intended only to print "hello world" in a loop when run on an STM32F429ZITx running a Cortex-M7 core.

I have configured my program to be compiled for a thumbv7em-none-eabihf target triple and for the cargo run command to invoke the probe-rs extension. My config.toml file is written like so:

[build]
target = "thumbv7em-none-eabihf"

[target.thumbv7em-none-eabihf]
rustflags = ["-C", "link-arg=-Tlink.x"]
runner = 'C:\Downloads\probe-rs-tools-x86_64-pc-windows-msvc\probe-rs.exe run --chip STM32F429ZI'

I have installed the panic_handler, cortex-m-rt, cortex-m (only for the critical-section-single-core feature), and rtt-target crates (so I can use RTT to print to terminal). My Cargo.toml file looks like so:

[package]
name = "cargo_cfg_test"
version = "0.1.0"
edition = "2024"

[dependencies]
cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] }
cortex-m-rt = "0.7.5"
panic-halt = "1.0.0"
rtt-target = "0.6.1"

[features]
default=[]

My main.rs file itself uses the entry proc_macro so the reset handler jumps to main after initializing RAM. It just prints hello world in a loop:

#![no_std]
#![no_main]

use panic_halt as _;
use cortex_m as _;
use cortex_m_rt::entry;
use rtt_target::{rprintln, rtt_init_print};

#[entry]
fn main() -> ! {

    rtt_init_print!();
    
    loop{
        rprintln!("Hello world");
    };
}

I also have made sure to configure my memory.x file appropriately for the STM32F429:

MEMORY
{
  FLASH : ORIGIN = 0x08000000, LENGTH = 2000000
  RAM   : ORIGIN = 0x20000000, LENGTH = 256K
}

I am able to flash and erase and program the chip using cargo embed, but attempting to step through the instructions using probe-rs does not work. For reference, I have configured my launch.json file (I am using VS-Code) for probe-rs debugging like so (I mostly just copied from the probe-rs documentation and made some small modifications):

{
    "configurations": [
        {
            "type": "probe-rs-debug",
            "request": "launch",
            "name": "probe-rs Test",
            "cwd": "c:/Downloads/probe-rs-tools-x86_64-pc-windows-msvc",
            "connectUnderReset": false,
            "chip": "STM32F429ZI",
            "flashingConfig": {
                "flashingEnabled": true,
                "haltAfterReset": true
            },
            "probe": "0483:374b:0664FF575251717867201529",
            "coreConfigs": [
                {
                    "coreIndex": 0,
                    "programBinary": "C:/cargo_cfg_test/target/thumbv7em-none-eabihf/debug/cargo_cfg_test",
                    "rttEnabled": true,
                    "rttChannelFormats": [
                      {
                        "channelNumber": 0,
                        // Format RTT data as String data
                        "dataFormat": "String",
                        // Include host-side timestamps for every line of data transferred from the target RTT output
                        "showTimestamps": true
                      }
                    ]         
                }
            ]
        }
    
    ]
}

When I attempt run to run the code, it seems that an immediate unhandled exception occurs somewhere in the reset handler, as the Call Stack in the debug view immediately indicates the program is halted in an "Unknown Function" @ address 0x08000400 invoked from the Reset Handler. Attempting to step through this "Unknown Function" generates these errors from the probe-rs debug console:

Step error @0x0800040C: Unable to determine target address for this step request.\n

Attempting to run the program rather than stepping once this occurs leads to the error message:

WARN probe_rs::probe::stlink:754: send_jtag_command 242 failed: SwdApFault

WARN probe_rs_debug::debug_info:717: UNWIND: Error while checking for exception context. The stack trace will not include the calling frames. : Probe(Arm(Probe(ProbeSpecific(BoxedProbeError(CommandFailed(SwdApFault))))))

Any help on what exactly I have configured wrong here would be helpful considering my program can be flashed onto the chip, but I seem to be unable to attach to the core or step through any instructions.

0x400 is the size of the vector table, the cortex-m-rt crate put the reset handler directly after the vector table, so 0x08000400 should be the address of the reset handler.

you can verify this by exmaining the first 2 entries (32bit each) in the vector table located at the start of the flash, one is the initial stack pointer, which by default points to the end of the ram, and the other should be the reset handler, i.e. 0x08000400

normally, the reset handler is designated by a symbol Reset, the fact that the debugger says it's an "unknown function" indicates either a wrong linker script is used, or the debug symbol is not properly generated or loaded.

you can dump the symbol table using tools like nm or objdump. you can use cargo-binutils if you don't have the tools installed already.

this is probably also the consequence of lacking debug symbols, so the debugger doesn't know where "next line" is.

but I think you should still be able to step in disassembly view. can you verify that?

I don't know what caused this, but it usually indicates the core is not responding to debug command, e.g. in some locked up state or low power mode.

if it were caused by the halt in the panic handler, can you replace panic-halt with panic-semihosting and try again?