Compiling for ARM Cortex-M0 using xargo


#1

I’m trying to compile a project for ARM (thumbv6m-none-eabi) using xargo. The code looks like this:

src/main.rs:

#![feature(compiler_builtins_lib, lang_items, core_intrinsics, start)]
#![no_std]
extern crate libc;
extern crate compiler_builtins;

use core::intrinsics;

#[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
    0
}

#[lang = "eh_personality"]
#[no_mangle]
pub extern fn rust_eh_personality() {}

#[lang = "eh_unwind_resume"]
#[no_mangle]
pub extern fn rust_eh_unwind_resume() {}

#[lang = "panic_fmt"]
#[no_mangle]
pub extern fn rust_begin_panic(_: core::fmt::Arguments, _: &'static str, _: u32) -> ! {
    unsafe { intrinsics::abort() }
}

Cargo.toml:

[package]
name = "glove"
version = "0.1.0"
authors = ["Jascha <Jascha-N@users.noreply.github.com>"]

[dependencies.compiler_builtins]
git = "https://github.com/rust-lang-nursery/compiler-builtins"

[dependencies.libc]
version = "0.2"
default-features = false

[profile.debug]
panic = "abort"

[profile.release]
panic = "abort"

Xargo.toml:

[target.thumbv6m-none-eabi.dependencies]
collections = {}

.cargo/config:

[build]
target = 'thumbv6m-none-eabi'
rustflags = [
   '-Zunstable-options',
   '-Ctarget-feature=+crt-static'
]

But I get a bunch of errors when compiling libc about missing types such as c_long and c_char. Not depending on libc causes some missing symbols during linking such as memset.

EDIT: It seems I cannot depend on libc since it does not support bare metal ARM? Do I have write my own memset, exit, etc. functions?


#2

It seems I cannot depend on libc since it does not support bare metal ARM?

Correct. Nobody has added thumbv*m-none-eabi* support to the libc crate.

Do I have write my own memset, exit, etc. functions?

You can link to newlib to get those functions. (What does exit even mean in a bare metal context? You usually only have one endless program running)

If you want to build bare metal programs that don’t depend on newlib or C code, there’s this template that you could use.


#3

Thanks for the pointers. I’ve made a little bit of progress by reverse engineering how arduino-builder handles the creation of a binary. I have gotten the Arduino core library and variant object file linked together with my Rust code. The only problem is that the Arduino library is written in C++ which does not map well to Rust. My options are completely porting one specific implementation (each board seems to have their own) of the core library to Rust. The alternative is writing C wrappers around the public APIs as described by Arduino and then in turn create FFI bindings and a Rusty API around those. However I’m afraid the latter might cause too much overhead and it is very clunky in general. And again I can’t use libc so I have to define the C types myself.

The method you proposed, while interesting and challenging, might be a little too low-level for my use case.


#4

The teensy3-rs crate may be a better starting point; it wraps a C++ library.


#5

Hi…I recently finished my Master’s Thesis on using anything other than C/C++ on microcontrollers.A couple of languages like Rust, D, etc. can be hacked on micros due to their compiler suite, but it is always messy. Above guide uses inline assembly to blink a GPIO. Hardware access is on register level.In order to be viable for microcontrollers you need two things: * a compiler or interpreter for your target * a Hardware APIThere are some projects, like MicroPython and Espruino who realized the importance of the Hardware API. They basically transcend micro-interpreters and RTOS.

percentage calculator


#6

Check up also this awesome HAL framework/library for embedded development - https://github.com/bobbin-rs/bobbin-sdk.