stm32l432kc flash problem with quickstart template
lucazulian opened this issue · 2 comments
lucazulian commented
I have a stm32l432kc and I started a new project with cortex-m-quickstart template. I can build and the with openocd but I have a problem to flash (or load) the binary into the nucleo.
//! Blinks an LED
#![no_std]
#![no_main]
use core::panic::PanicInfo;
extern crate cortex_m;
#[macro_use]
extern crate cortex_m_rt as rt;
extern crate cortex_m_semihosting as sh;
extern crate stm32l4xx_hal as hal;
use crate::hal::prelude::*;
use crate::hal::delay::Delay;
use crate::rt::ExceptionFrame;
use crate::rt::entry;
use core::fmt::Write;
use crate::sh::hio;
#[inline(never)]
#[entry]
fn main() -> ! {
let mut hstdout = hio::hstdout().unwrap();
writeln!(hstdout, "Hello, world!").unwrap();
let cp = cortex_m::Peripherals::take().unwrap();
let dp = hal::stm32::Peripherals::take().unwrap();
let mut flash = dp.FLASH.constrain(); // .constrain();
let mut rcc = dp.RCC.constrain();
// Try a different clock configuration
let clocks = rcc.cfgr.hclk(8.mhz()).freeze(&mut flash.acr);
let mut gpiob = dp.GPIOA.split(&mut rcc.ahb2);
let mut led = gpiob.pa1.into_push_pull_output(&mut gpiob.moder, &mut gpiob.otyper);
let mut gpiof = dp.GPIOB.split(&mut rcc.ahb2);
let mut leda = gpiof.pb3.into_push_pull_output(&mut gpiof.moder, &mut gpiof.otyper);
let mut timer = Delay::new(cp.SYST, clocks);
loop {
timer.delay_ms(100 as u32);
led.set_high();
leda.set_high();
timer.delay_ms(100 as u32);
led.set_low();
leda.set_low();
writeln!(hstdout, "ciao").unwrap();
}
}
#[panic_handler]
#[no_mangle]
pub fn panic(_info: &PanicInfo) -> ! {
loop{}
}
[package]
authors = ["luca"]
edition = "2018"
readme = "README.md"
name = "app"
version = "0.1.0"
[dependencies]
cortex-m = "0.6.1"
cortex-m-rt = "0.6.10"
cortex-m-semihosting = "0.3.3"
panic-halt = "0.2.0"
alloc-cortex-m = "0.3.5"
embedded-hal = "0.2.1"
generic-array = "0.12.0"
nb = "0.1.0"
[dependencies.stm32l4xx-hal]
version = "0.5.0"
features = ["stm32l4x2"]
[dependencies.stm32l4]
version = "0.8.0"
features = ["stm32l4x2", "rt"]
[dependencies.cast]
default-features = false
version = "0.2.2"
# this lets you use `cargo fix`!
[[bin]]
name = "app"
test = false
bench = false
[profile.release]
codegen-units = 1 # better optimizations
debug = false # symbols are nice and they don't increase the size on Flash
lto = true # better optimizations
panic = "abort"
opt-level = 's'
#[profile.dev]
#panic = "abort"
The memory.x is
MEMORY
{
/* NOTE K = KiBi = 1024 bytes */
FLASH : ORIGIN = 0x08000000, LENGTH = 256K
RAM : ORIGIN = 0x20000000, LENGTH = 40K
}
/* This is where the call stack will be allocated. */
/* The stack is of the full descending type. */
/* You may want to use this variable to locate the call stack and static
variables in different memory regions. Below is shown the default value */
/* _stack_start = ORIGIN(RAM) + LENGTH(RAM); */
/* You can use this symbol to customize the location of the .text section */
/* If omitted the .text section will be placed right after the .vector_table
section */
/* This is required only on microcontrollers that store some configuration right
after the vector table */
/* _stext = ORIGIN(FLASH) + 0x400; */
/* Example of putting non-initialized variables into custom RAM locations. */
/* This assumes you have defined a region RAM2 above, and in the Rust
sources added the attribute `#[link_section = ".ram2bss"]` to the data
you want to place there. */
/* Note that the section will not be zero-initialized by the runtime! */
/* SECTIONS {
.ram2bss (NOLOAD) : ALIGN(4) {
*(.ram2bss);
. = ALIGN(4);
} > RAM2
} INSERT AFTER .bss;
*/
If I inspect app I can see
arm-none-eabi-readelf -h app
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x80004a3
Start of program headers: 52 (bytes into file)
Start of section headers: 49632 (bytes into file)
Flags: 0x5000400, Version5 EABI, hard-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 3
Size of section headers: 40 (bytes)
Number of section headers: 21
Section header string table index: 19
But the "same" functionality produces in Arduino something like this:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x80002ad
Start of program headers: 52 (bytes into file)
Start of section headers: 149912 (bytes into file)
Flags: 0x5000400, Version5 EABI, hard-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 3
Size of section headers: 40 (bytes)
Number of section headers: 18
The difference here is the Entry point address. If I try to copy
arm-none-eabi-objcopy -O binary app app.bin
cp app.bin /run/media/luca/NODE_L432KC
The binary produced by rust does not start.
therealprof commented
Most likely the problem is the use of semihosting in the code. semihosting requires that the board is hooked up to a debug probe, a debugger is running on the host system and properly set up. Otherwise it will just crash the application and nothing happens.
lucazulian commented
@therealprof now it works! Thanke for helping me!