rust-embedded/embedded-alloc

Can not build for STM32 - undefined symbol critical section

steckes opened this issue · 1 comments

As I am new to embedded, it could be that I am just missing something.
I am following the STM32F3DISCOVERY (https://docs.rust-embedded.org/book/).
The allocator example in the cortex_m_quickstart template is working fine using the 0.4.2 version of alloc-cortex-m and I can use e.g. ndarray.
When I test the example of the current version 0.5.0 of embedded_alloc it can't find the symbol critical_section.

Do you know what I need to change to make it run?

error: linking with `rust-lld` failed: exit status: 1
          rust-lld: error: undefined symbol: _critical_section_1_0_acquire
          >>> referenced by lib.rs:180 (/Users/aicse/.cargo/registry/src/index.crates.io-6f17d22bba15001f/critical-section-1.1.1/src/lib.rs:180)
          >>>               embedded_alloc-3c639d8a5411f8c8.embedded_alloc.77b68f61-cgu.5.rcgu.o:(critical_section::with::hdf8f1ccb073a5751) in archive /Users/aicse/Development/micro-layer-test/target/thumbv7em-none-eabihf/debug/deps/libembedded_alloc-3c639d8a5411f8c8.rlib
          
          rust-lld: error: undefined symbol: _critical_section_1_0_release
          >>> referenced by lib.rs:197 (/Users/aicse/.cargo/registry/src/index.crates.io-6f17d22bba15001f/critical-section-1.1.1/src/lib.rs:197)
          
error: could not compile `micro-layer-test` (bin "micro-layer-test") due to previous error

Alright I found the solution. Maybe one word in the readme about that would be helpful for beginners?

I added the feature critical-section-single-core to cortex-m:

cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }

and used the cortex_m crate in my main.rs:

use cortex_m as _;

The full code is then looking like this:

#![no_std]
#![no_main]

extern crate alloc;

use cortex_m as _;
use cortex_m_rt::entry;
use embedded_alloc::Heap;
use panic_halt as _;

#[global_allocator]
static HEAP: Heap = Heap::empty();

#[entry]
fn main() -> ! {
    // Initialize the allocator BEFORE you use it
    {
        use core::mem::MaybeUninit;
        const HEAP_SIZE: usize = 1024;
        static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
        unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) }
    }

    // now the allocator is ready types like Box, Vec can be used.

    loop { /* .. */ }
}