Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add POC Rust Crazyflie app example #1429

Merged
merged 1 commit into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 <[email protected]>"]
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); }
}
}