Skip to content

Commit

Permalink
Merge pull request #1429 from bitcraze/ataffanel/kbuild-rust-app
Browse files Browse the repository at this point in the history
Add POC Rust Crazyflie app example
  • Loading branch information
ataffanel authored Oct 30, 2024
2 parents 0b086b9 + 7fa439e commit bf168d4
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 0 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ PROCESSOR = -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
LINKER_DIR = $(srctree)/tools/make/F405/linker

LDFLAGS += --specs=nosys.specs --specs=nano.specs $(PROCESSOR) -nostdlib
image_LDFLAGS += -z noexecstack
image_LDFLAGS += -Wl,-Map=$(PROG).map,--cref,--gc-sections,--undefined=uxTopUsedPriority
image_LDFLAGS += -L$(srctree)/tools/make/F405/linker
image_LDFLAGS += -T $(LINKER_DIR)/FLASH_CLOAD.ld
Expand Down
1 change: 1 addition & 0 deletions examples/app_hello_rs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target/
16 changes: 16 additions & 0 deletions examples/app_hello_rs/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions examples/app_hello_rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "cfapprs"
version = "0.1.0"
authors = ["Arnaud Taffanel <arnaud@bitcraze.io>"]
edition = "2021"

[lib]
crate-type = ["staticlib"]

[dependencies]
panic-halt = "1.0.0"
15 changes: 15 additions & 0 deletions examples/app_hello_rs/Kbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Name of the RUST lib crate to include in the build
CRATE_NAME := cfapprs

# The crate's output lib will become app.o to make KBUILD happy
obj-y += app.o

# Flag required to link the whole static library into built-in.o, noexecstack matches the default behavior of LLVM
EXTRA_LDFLAGS += -Wl,--whole-archive -z noexecstack

# Always build the Rust lib crate and copy it to app.o
$(obj)/app.o: FORCE
cargo build --release --target thumbv7em-none-eabihf
cp $(obj)/target/thumbv7em-none-eabihf/release/lib$(CRATE_NAME).a $@

FORCE:
23 changes: 23 additions & 0 deletions examples/app_hello_rs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# The firmware uses the Kbuild build system. There are 'Kbuild' files in this
# example that outlays what needs to be built. (check src/Kbuild).
#
# The firmware is configured using options in Kconfig files, the
# values of these end up in the .config file in the firmware directory.
#
# By setting the OOT_CONFIG (it is '$(PWD)/oot-config' by default) environment
# variable you can provide a custom configuration. It is important that you
# enable the app-layer. See app-config in this directory for example.

#
# We want to execute the main Makefile for the firmware project,
# it will handle the build for us.
#
CRAZYFLIE_BASE := ../..

#
# We override the default OOT_CONFIG here, we could also name our config
# to oot-config and that would be the default.
#
OOT_CONFIG := $(PWD)/app-config

include $(CRAZYFLIE_BASE)/tools/make/oot.mk
28 changes: 28 additions & 0 deletions examples/app_hello_rs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Rust Hello world App for Crazyflie 2.x

Rust version of the Hello-world app.

This folder shows a proof of concept of how to compile some Rust in the Crazyflie to call firmware functions.

This is a very minimal examples that can be used as a starting point to build better Rust integration for the Crazyflie fiwmware.

## Build dependencies

The prerequisite to build the rust app is to have a recent rust compiler (tested with 1.82.0) and the target for the Crazyflie CPU.
To install the target with [rustup](https://rustup.rs):
```
rustup target add thumbv7em-none-eabihf
```

## Architecture

The Crazyflie build system is based on KBuild and it had to be creatively bent to allow to link a static library.
This is done my renaming the Rust crate output static lib into a .o and make sure GCC copies the full lib content into the resulting firmware (See [Kbuild](Kbuild)).

The Rust project is setup to generate a C static library.
The Makefile calls `cargo build` to build the lib and copies the resulting lib into ```app.o```.

The Crazyflie firmware will call `appMain()` at startup.
This function is declared in rust as `pub extern "C"` to be callable from C.

The FreeRTOS delay function and Crazyflie console putchar function are manually declared `extern "C"` which allows Rust to call them.
3 changes: 3 additions & 0 deletions examples/app_hello_rs/app-config
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CONFIG_APP_ENABLE=y
CONFIG_APP_PRIORITY=1
CONFIG_APP_STACKSIZE=350
23 changes: 23 additions & 0 deletions examples/app_hello_rs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#![no_std]

use panic_halt as _;

extern "C" {
pub fn vTaskDelay(ticks: u32);
pub fn consolePutchar(ch: i32) -> i32;
}

fn console_print(msg: &str) {
for c in msg.as_bytes() {
unsafe{ consolePutchar(*c as i32); }
}
}

#[no_mangle]
pub extern "C" fn appMain() -> i32 {
console_print("Hello from Rust!\n");

loop {
unsafe { vTaskDelay(1000); }
}
}

0 comments on commit bf168d4

Please sign in to comment.