Can't flash the program into stm32nucleo-l476RG

Im trying to flash a nucleo-l476RG board with blink template from GitHub - David-OConnor/stm32-hal-quickstart: A default template for STM32-HAL
It says that flashing is complete, but the led isn't working, and there is no communication, only this error message


My memory.x looks like this

/* Change this as required for your MCU */

MEMORY
{
  /* NOTE 1 K = 1 KiBi = 1024 bytes */
  FLASH : ORIGIN = 0x08000000, LENGTH = 1024K
  RAM : ORIGIN = 0x20000000, LENGTH = 128K
}

cargo.toml

[package]
authors = ["Your name <your@em.ail>"]
name = "project_name"
edition = "2021"
version = "0.1.0"

[dependencies]
defmt = "0.3.2"
defmt-rtt = "0.4.0"
panic-probe = { version = "0.3.0", features = ["print-defmt"] }

cortex-m = {version = "^0.7.7", features = ["critical-section-single-core"]}
cortex-m-rt = "0.7.3"

# Change this import as required for your MCU.
stm32-hal2 = { version = "^1.5.5", features = ["l4x6", "l4rt"]}

# cargo build/run
[profile.dev]
codegen-units = 1
debug = 2
debug-assertions = true # <-
incremental = false
opt-level = 3 # <-
overflow-checks = true # <-

# cargo test
[profile.test]
codegen-units = 1
debug = 2
debug-assertions = true # <-
incremental = false
opt-level = 3 # <-
overflow-checks = true # <-

# cargo build/run --release
[profile.release]
codegen-units = 1
debug = 2
debug-assertions = false # <-
incremental = false
lto = 'fat'
opt-level = 3 # <-
overflow-checks = false # <-

# cargo test --release
[profile.bench]
codegen-units = 1
debug = 2
debug-assertions = false # <-
incremental = false
lto = 'fat'
opt-level = 3 # <-
overflow-checks = false # <-

config.toml

[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# Change this runner as required for your MCU.
runner = "probe-run --chip STM32L476RGTx" # to list chips, run `probe-run --list-chips.`
rustflags = [
  "-C", "linker=flip-link",
  "-C", "link-arg=-Tlink.x",
  "-C", "link-arg=-Tdefmt.x",
  # This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
  # See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
  "-C", "link-arg=--nmagic",
]

[build]
# Change this target as required for your MCU.
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (eg F, L4, H7)
[alias]
rb = "run --bin"
rrb = "run --release --bin"
rr = "run --release"

and the code itself

#![no_std]
#![no_main]

use core::panic::PanicInfo;
use cortex_m::delay::Delay;
use cortex_m_rt::entry; // The runtime
use stm32_hal2::{
    self,
    clocks::{Clocks, InputSrc},
    gpio::{Pin, PinMode, Port},
    pac,
};
use defmt_rtt as _;

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

    let cp = cortex_m::Peripherals::take().unwrap();
   
    let mut dp = pac::Peripherals::take().unwrap();

    let clock_cfg = Clocks::default();
    defmt::println!("Hello, world!");

    clock_cfg.setup().unwrap();


    let mut delay = Delay::new(cp.SYST, clock_cfg.systick());

    let mut led = Pin::new(Port::A, 5, PinMode::Output);

    loop {
        led.set_low();
        delay.delay_ms(1_000);
        led.set_high();
        delay.delay_ms(1_000);
        defmt::println!("Loopin");
    }
}
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
    cortex_m::asm::udf()
}

/// Terminates the application and makes `probe-run` exit with exit-code = 0
pub fn exit() -> ! {
    loop {
        cortex_m::asm::bkpt();
    }
}

is your probe correctly connected? what's the output if you run the command:

probe-run --list-probes

if the probe is detected, it's probably RTT isn't set up correctly or the runner has incompatible version.

if you have openocd installed, use openocd to check the connectivity, it's more reliable. you should see the some information of the chip, otherwise, you have a bad probe board or cable.

openocd -f interface/stlink-v2.cfg -f target/stm32l4x.cfg -c init -c "dap info" -c shutdown

Hi, thanks for answering
probe-run --list-probes detects STlink the following probes were found: [0]: STLink V2-1 (VID: 0483, PID: 374b, Serial: 066EFF504955707267243405, StLink)
openocd returns:

Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
WARNING: interface/stlink-v2.cfg is deprecated, please switch to interface/stlink.cfg
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : clock speed 500 kHz
Info : STLINK V2J42M27 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.263366
Info : [stm32l4x.cpu] Cortex-M4 r0p1 processor detected
Info : [stm32l4x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32l4x.cpu on 3333
Info : Listening on port 3333 for gdb connections
Error: DAP instance not available. Probably a HLA target...

so the hardware connection is definitely working, and I would assume the template code is correct, so I suspect it's a protocol version mismatch, probably between the RTT and the runner. but I have no experience with probe-run, can you try probe-rs as default runner?

install probe-rs

cargo install probe-rs --features cli
probe-rs info

configure probe-rs as cargo runner

edit your .cargo/config.toml

- runner = "probe-run --chip STM32L476RGTx"
+ runner = "probe-rs run --chip STM32L476RGTx"

flash and run

simply run:

cargo run --release
1 Like

Thank you it seems you are correct, probe-rs returned

 Finished release [optimized + debuginfo] target(s) in 0.87s
     Running `probe-rs run --chip STM32L476RGTx target/thumbv7em-none-eabihf/release/project_name`
     Erasing sectors ✔ [00:00:00] [###########################################################################################################] 8.00 KiB/8.00 KiB @ 32.80 KiB/s (eta 0s )
 Programming pages   ✔ [00:00:00] [###########################################################################################################] 7.00 KiB/7.00 KiB @ 17.65 KiB/s (eta 0s )    Finished in 0.669s
ERROR probe_rs::cmd::run: Error attempting to attach to RTT: Error communicating with probe: An ARM specific error occurred. Continuing without RTT...     
Frame 0: <unknown function @ 0x08001716> @ 0x08001716
Frame 1: <unknown function @ 0xfffffff8> @ 0xfffffff8

Do you know how should I proceed with fixing this issue?

can you try to run a minimal example to test out RTT protocol? (you'll need add panic_halt and rtt_target to your dependencies)

#![no_std]
#![no_main]

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

#[cortex_m_rt::entry]
fn main() -> ! {
    rtt_init_print!();
    loop {
        rprintln!("Hello, world!");
    }
}

if you don't receive the "Hello, world!" message, there might be something wrong with your board configuration. if the message does show up, it might be something to do with the project template or HAL crate.

I'm not familiar with the hardware you have. I noticed these stack frames:

are these the correct reset vector value? do you have some boot select pin/jumper/switch that is wrongly placed?

btw, if you are using vscode, you can install this extension or search for probe-rs in the marketplace:

then you can set a point in the code and use the debugger to figure out what's wrong with the blinky code.

you'll need to add an entry to the launch.json vscode config file:

{
  "version": "0.2.0",
  "configurations": [
    {
      "preLaunchTask": "${defaultBuildTask}",
      "type": "probe-rs-debug",
      "request": "launch",
      "name": "hello",
      "chip": "STM32L476RGTx", //!MODIFY
      "coreConfigs": [
        {
          "programBinary": "target/thumbv7em-none-eabihf/release/project_name" //!MODIFY
        }
      ]
    }
  ]
}

see the documentation for details

After running your example i get this

error: linking with `flip-link` failed: exit status: 1
  |
  = note: LC_ALL="C" PATH="/home/prk/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin:/home/prk/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin" VSLANG="1033" "flip-link" "-flavor" "gnu" "/tmp/rustc76JxhJ/symbols.o" "/home/prk/Desktop/testing/target/thumbv7em-none-eabihf/release/deps/test-088e2909b51568cc.test.a0362fb2be343086-cgu.0.rcgu.o" "--as-needed" "-L" "/home/prk/Desktop/testing/target/thumbv7em-none-eabihf/release/deps" "-L" "/home/prk/Desktop/testing/target/release/deps" "-L" "/home/prk/Desktop/testing/target/thumbv7em-none-eabihf/release/build/cortex-m-063929d4c8154787/out" "-L" "/home/prk/Desktop/testing/target/thumbv7em-none-eabihf/release/build/cortex-m-rt-5bb4004673e6aec1/out" "-L" "/home/prk/Desktop/testing/target/thumbv7em-none-eabihf/release/build/defmt-a61ef2fd4e7440fe/out" "-L" "/home/prk/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabihf/lib" "-Bstatic" "/home/prk/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabihf/lib/libcompiler_builtins-1cc8d288f9da4605.rlib" "-Bdynamic" "--eh-frame-hdr" "-z" "noexecstack" "-L" "/home/prk/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabihf/lib" "-o" "/home/prk/Desktop/testing/target/thumbv7em-none-eabihf/release/deps/test-088e2909b51568cc" "--gc-sections" "-O1" "-Tlink.x" "-Tdefmt.x" "--nmagic"
  = note: rust-lld: warning: section type mismatch for .got
          >>> <internal>:(.got): SHT_PROGBITS
          >>> output section .got: SHT_NOBITS
          
          rust-lld: warning: section type mismatch for .got.plt
          >>> <internal>:(.got.plt): SHT_PROGBITS
          >>> output section .got: SHT_NOBITS
          
          rust-lld: warning: section type mismatch for .got
          >>> <internal>:(.got): SHT_PROGBITS
          >>> output section .got: SHT_NOBITS
          
          rust-lld: error: undefined symbol: _critical_section_1_0_acquire
          >>> referenced by lib.rs:183 (/home/prk/.cargo/registry/src/index.crates.io-6f17d22bba15001f/critical-section-1.1.2/src/lib.rs:183)
          >>>               /home/prk/Desktop/testing/target/thumbv7em-none-eabihf/release/deps/test-088e2909b51568cc.test.a0362fb2be343086-cgu.0.rcgu.o:(test::__cortex_m_rt_main::h54bbd47a7c7da847)
          >>> referenced by lib.rs:183 (/home/prk/.cargo/registry/src/index.crates.io-6f17d22bba15001f/critical-section-1.1.2/src/lib.rs:183)
          >>>               /home/prk/Desktop/testing/target/thumbv7em-none-eabihf/release/deps/test-088e2909b51568cc.test.a0362fb2be343086-cgu.0.rcgu.o:(test::__cortex_m_rt_main::h54bbd47a7c7da847)
          
          rust-lld: error: undefined symbol: _critical_section_1_0_release
          >>> referenced by lib.rs:200 (/home/prk/.cargo/registry/src/index.crates.io-6f17d22bba15001f/critical-section-1.1.2/src/lib.rs:200)
          >>>               /home/prk/Desktop/testing/target/thumbv7em-none-eabihf/release/deps/test-088e2909b51568cc.test.a0362fb2be343086-cgu.0.rcgu.o:(test::__cortex_m_rt_main::h54bbd47a7c7da847)
          >>> referenced by lib.rs:200 (/home/prk/.cargo/registry/src/index.crates.io-6f17d22bba15001f/critical-section-1.1.2/src/lib.rs:200)
          >>>               /home/prk/Desktop/testing/target/thumbv7em-none-eabihf/release/deps/test-088e2909b51568cc.test.a0362fb2be343086-cgu.0.rcgu.o:(test::__cortex_m_rt_main::h54bbd47a7c7da847)
          
          flip-link: the native linker failed to link the program normally; please check your project configuration and linker scripts
          

error: could not compile `test` (bin "test") due to previous error```
I've read that it could be caused without critical section implementation, however i have it in my cargo.toml
![image|690x165](upload://kKx3cTpSoZFAeAFQuR5J48p0GGQ.png)
Im sorry if i don't understand it correctly, I've only started learning recently

it seems the critical section implementation is missing, try add this line to your code, this will force the HAL crate to be linked.

use stm32_hal2 as _;

It again, returned the Frame 0: <unknown function @ 0x08001716> @ 0x08001716 Frame 1: <unknown function @ 0xfffffff8> @ 0xfffffff8
I don't believe i have any wrong placed pin/jumper/switch because I can flash the board using cubeIDE without a problem.
Thank you for your patience

as I said, I'm not familiar with the hardware you have. just from the memory.x layout, that Frame 0: @0x08001716 seems a valid address, but the other one 0xfffffff8 feels wrong to me. I don't know exactly what it refers to though.

since downloading and flashing complete successfully, I'm pretty sure the toolchain all work fine. it's most likely a configuration error (like memory map, reset vector table, bootloader etc). but just to be sure, can you try to run (and even debug) a CubeIDE program (such as blinky) under probe-rs?

first build your program in CubeIDE, note the build log line like:

Finished building target: blinky.elf

then find the path to the blinky.elf file, to flash and run:

probe-rs run --chip STM32L476RGTx path/to/blinky.elf
# you can also start a gdb server and connect the IDE debugger
probe-rs gdb --chip STM32L476RGTx path/to/blinky.elf

if you want to see RTT in action, try this project instead of blinky: (you don't need a j-link probe, probe-rs should be compatible, but I don't have experience with STM32, I know rp2040 works)

2 Likes

I successfully flashed a blinky program written in cubeIDE but I can't do the same for program written in rust
Frame1 would point to internal peripherals but i have no idea why


I've tried setting memory.x Flash and Ram to smaller values but it did nothing.

the stack frame could be invalid and the address 0xfffffff8 is meaningless, or it could be the the reset vector (or some other exception vector), or it could be that the program simply crashed.

to figure out, build and flash the program onto the device as before, after flashing is done, use a debugger to check the chip status.

# build and flash as usual. omit the `--release` option to get more debug info
cargo run
# attach `probe-rs`' simple debugger, use `debug` instead of `release`
probe-rs debug --chip STM32L476RGTx --exe target/thumbv7em-none-eabihf/debug/project_name
# now inside the debugger prompt, try to get a stack trace
Core is running.
# first halt the processor
>> halt
# example output
Core stopped at address 0x000001c2
0x1c2: movs r0, #0
0x1c4: mov r1, r4
0x1c6: movs r2, #0xe
0x1c8: bl #0x272
0x1cc: b #0x1c2
0x1ce: bx lr
# print back trace
>> bt
# example output
Frame 0: __cortex_m_rt_main @ 0x000001c2
       Y:\hello\src/main.rs:12:9
Frame 1: __cortex_m_rt_main_trampoline @ 0x0000016c
       Y:\hello\src/main.rs:8:1
Frame 2: fmt @ 0x00000142

the built in debugger has very limited functionality, it would be more convenient to run probe-rs gdb --chip STM32L476RGTx as a gdb server and use a proper debugger interface to debug the code.

1 Like

Thanks, It seems that 0x08000004 is indeed an exception vector


0xfffffff8 `appears right at the start into the program counter register

It also seems that a RAM location in memory.x is wrong should i decrease the RAM size or am I reading that incorrectly?

Im using a probe-rs debugger because gdb just freezes the moment i try to start a session

yeah, there's definitely something wrong there. from the screenshot I think the problem is, the "bottom" portion of the RAM is inaccessible for some reason, and that range is used as the stack.

again, as I don't have the hardware, I can only guess, but it's likely the memory map is wrong. you can either reduce the RAM size and try again, or you can find the linker script in a CubeIDE project and compare the memory section.

if it still fails, I'd suggest you post an issue on the stm32-hal2 repository, the author are more familiar with the STM32 hardware and you are more likely to get a clear answer.


RANT ALERT

I know it's frustrating if you cannot even get a basic blinky program to run. with all the awesome work done by the community, embedded rust still lags behind C/C++ in terms of vendor support. we need BSPs, we need drivers for special peripherals, we need easy to use configuration tools, we need interactive project template generator (a.k.a. new project wizard), and so much more.
but the industry is showing more interests in rust now. espressif is offering rust training programs for their ESP32 architecture, infineon has announced rust toolchain support for their AURIX architecture. I hope more manufacturers would support rust as first class embedded development language.

1 Like

Oh my god im so dumb it's embarrassing, I should've checked the linker script in in CubeIDE in the begging, turns out RAM1 is 96K and RAM2 is 32K, however in the user manual it was 128K SRAM, that was causing the issue. Thank you for your patience again.