I'm working on building out a Rust interface to the nRF51x series parts.  I
have a bare metal system working quite well.  The nRF51x has a bluetooth
stack (called Softdevice).  This stack requires the use of supervisor calls
to request the stack to perform certain functions.  My plan is to write a C
library wrapper around these service calls, compile with arm-none-wabi-gcc
and then link this to my Bare-metal rust system.  A large chunk of the work
I have done thus far is based off of STM32 example work done by Jorge
Aparicio (https://github.com/japaric).

Since I have the basics up and running, I am working on trying to get a C
static library built with arm-none-eabi-gcc and archived with
arm-none-eabi-ar to properly link in with my Rust code.

I have the following (very basic) .c file:
uint32_t sum(uint32_t a, uint32_t b)
{
return a + b;
}

I am compiling and linking with the following commands:

arm-none-eabi-gcc -Wall -mcpu=cortex-m0 -mthumb -fPIC --specs=nosys.specs
-shared test.c -o test.o

arm-none-eabi-ar -rs libtest.a test.o


In my rust file:

[link(name="test", kind="static")]

extern {

pub fn sum(a: u32, b: u32) -> u32;

}


I then invoke it as a test:

pub fn main() {

        let test_sum = unsafe { sum(2, 3) };

}


I am using a Makefile to execute the rust compiler for some specific
arguments, such as my specific target:

# rustc target

TARGET = thumbv6m-none-eabi


# toolchain prefix

TRIPLE = arm-none-eabi


APP_DIR = src/app

OUT_DIR = target/$(TARGET)/release


DEPS_DIR = $(OUT_DIR)/deps


BINS = $(OUT_DIR)/%.hex

HEXS = $(OUT_DIR)/%.hex

ELFS = $(OUT_DIR)/%.elf

OBJECTS = $(OUT_DIR)/intermediate/%.o

SOURCES = $(APP_DIR)/%.rs


APPS = $(patsubst $(SOURCES),$(BINS),$(wildcard $(APP_DIR)/*.rs))


RUSTC_FLAGS := -C lto -g $(RUSTC_FLAGS)


# don't delete my elf files!

.SECONDARY:


all: rlibs  $(APPS)


clean:

cargo clean


# TODO $(APPS) should get recompiled when the `rlibs` change


$(OBJECTS): $(SOURCES)

mkdir -p $(dir $@)

rustc \

$(RUSTC_FLAGS) \

--crate-type staticlib \

--emit obj \

--target $(TARGET) \

-L $(DEPS_DIR) \

-L ../sd110_lib \

--verbose \

-o $@ \

-ltest \

$<


$(ELFS): $(OBJECTS)

$(TRIPLE)-ld \

--gc-sections \

-T layout.ld \

-o $@ \

$<

#size $@


$(BINS): $(ELFS)

$(TRIPLE)-objcopy \

-O ihex \

$< \

$@


rlibs:

cargo build --target $(TARGET) --verbose --release


The cargo.toml is as follows:

[package]

name = "bmd200eval"

version = "0.1.0"

authors = ["Eric Stutzenberger <eric.stutzenber...@rigado.com>"]


[dependencies.nrf51822]

path = "../nrf51822.rs"


When I run make, I get the following output:

.

.

.

mkdir -p target/thumbv6m-none-eabi/release/intermediate/

rustc \

-C lto -g  \

--crate-type staticlib \

--emit obj \

--target thumbv6m-none-eabi \

-L target/thumbv6m-none-eabi/release/deps \

-L ../sd110_lib \

--verbose \

-o target/thumbv6m-none-eabi/release/intermediate/blink.o \

-ltest \

src/app/blink.rs

src/app/blink.rs:42:9: 42:17 warning: unused variable: `test_sum`,
#[warn(unused_variables)] on by default

src/app/blink.rs:42     let test_sum = unsafe { sum(2, 3) };

                            ^~~~~~~~

arm-none-eabi-ld \

--gc-sections \

-T layout.ld \

-o target/thumbv6m-none-eabi/release/blink.elf \

target/thumbv6m-none-eabi/release/intermediate/blink.o

target/thumbv6m-none-eabi/release/intermediate/blink.o: In function
`blink::main':

git/rust-nrf/bmd200eval.rs/src/app/blink.rs:42: undefined reference to `sum'



I have found numerous different references to linking Rust with C and
calling C from Rust but I haven't found a specific answer as to why this
will not link.  As you can see in the Makefile, I have tried to
force rustc's hand in finding and linking against the library, but this
doesn't seem to make a difference.


Is there an issue with how I am building a library?

Since rustc is generating a staticlib in this case, is there some different
method that needs to be used?


Note that I am avoiding the Clang compiler for the moment due to the
following:

https://devzone.nordicsemi.com/question/29628/using-clang-and-the-s110-issues-with-supervisor-calls-to-the-softdevice/


Essentially, the gist of the above is that Clang is not quite producing the
correct supervisor assembly code for calling in to the bluetooth stack,
especially when optimizations are enabled.


Cheers,

Eric
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to