Skip to content
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
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ jobs:
freertos-rust-stable:
name: Build freertos-rust using stable
runs-on: ubuntu-latest
env:
RUSTFLAGS: -D warnings # Warnings disabled only in CI
# env:
# RUSTFLAGS: -D warnings # Warnings disabled only in CI
Comment thread
schteve marked this conversation as resolved.
Outdated
steps:
- name: Clone
uses: actions/checkout@v3
Expand All @@ -70,8 +70,8 @@ jobs:
# target: x86_64-pc-windows-gnu
#- example: linux
# target: x86_64-unknown-linux-gnu
#- example: stm32-cortex-m3
# target: thumbv7m-none-eabi
- example: stm32-cortex-m3
target: thumbv7m-none-eabi
- example: stm32-cortex-m4-blackpill
target: thumbv7em-none-eabihf
#- example: nrf9160
Expand All @@ -93,7 +93,7 @@ jobs:
target
key: ${{ runner.os }}-${{ runner.arch }}
- name: Install Rust
uses: dtolnay/rust-toolchain@nightly
uses: dtolnay/rust-toolchain@stable
Comment thread
schteve marked this conversation as resolved.
Outdated
with:
targets: ${{ matrix.target }}
- name: Install cross deps
Expand Down
57 changes: 30 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,61 +13,68 @@ In contrast to freertos.rs this crate differs in these points:

## How it works

The `freertos-cargo-build` build-dependency compiles the FreeRTOS code from its original "C" sources files into an
archive to be linked against your Rust app. Internally it uses the [cc crate](https://docs.rs/crate/cc) and some meta
The `freertos-cargo-build` build-dependency compiles the FreeRTOS code from its original "C" sources files into an
archive to be linked against your Rust app. Internally it uses the [cc crate](https://docs.rs/crate/cc) and some meta
info provided by your apps `build.rs`:

1. A path to the [FreeRTOS](https://github.com/FreeRTOS/FreeRTOS-Kernel) `Sources`
1. A path to the app specific `FreeRTOSConfig.h`
1. A relative path to the `FreeRTOS port` to be used, e.g. for ARM Cortex-M3 cores.
1. Optional: Additional C code to be compiled
The `freertos-rust` dependency provides an interface to access all FreeRTOS functionality from your (embedded)

The `freertos-rust` dependency provides an interface to access all FreeRTOS functionality from your (embedded)
Rust app.

## Usage

1. Checkout FreeRTOS: https://github.com/FreeRTOS/FreeRTOS-Kernel
1. Checkout FreeRTOS: https://github.com/FreeRTOS/FreeRTOS-Kernel

1. Add dependencies to your Rust apps `Cargo.toml`

```
```toml
[dependencies]
freertos-rust = "*"

[build-dependencies]
freertos-cargo-build = "*"
```

1. Add this snippet to your apps `build.rs`:
```
```rust
fn main() {
let mut b = freertos_cargo_build::Builder::new();

// Path to FreeRTOS kernel or set ENV "FREERTOS_SRC" instead
b.freertos("path/to/FreeRTOS-Kernel");
b.freertos_config("src"); // Location of `FreeRTOSConfig.h`
b.freertos_port("GCC/ARM_CM3"); // Port dir relativ to 'FreeRTOS-Kernel/portable'
b.heap("heap_4.c"); // Set the heap_?.c allocator to use from
// 'FreeRTOS-Kernel/portable/MemMang' (Default: heap_4.c)
b.freertos_config("src"); // Location of `FreeRTOSConfig.h`
b.freertos_port("GCC/ARM_CM3"); // Port dir relativ to 'FreeRTOS-Kernel/portable'
b.heap("heap_4.c"); // Set the heap_?.c allocator to use from
// 'FreeRTOS-Kernel/portable/MemMang' (Default: heap_4.c)

// b.get_cc().file("More.c"); // Optional additional C-Code to be compiled

b.compile().unwrap_or_else(|e| { panic!("{}", e.to_string()) });
}
```
```

### Used C compiler
`freertos-cargo-build` depends on the [cc crate](https://docs.rs/crate/cc). So the C compiler
used can be set by using the `CC` enviroment variable or otherwise defined by internal
used can be set by using the `CC` enviroment variable or otherwise defined by internal
defaults. For the ARM architecture this is the `arm-none-eabi-gcc` which can be found [here](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads).

Install:
```shell
# on Ubuntu
sudo apt-get install -y gcc-arm-none-eabi
# on Windows
scoop install gcc-arm-none-eabi
```

## Examples
To get started there are examples in [freertos-rust-examples](freertos-rust-examples) for:

* Cortex M33 (nRF9160)
* Cortex M3 (STM32L151CBU6A)
* Cortex M4 (STM32F411CEU6)
* Cortex M3 (STM32F103C8)
* Cortex M4 (STM32F411CE)
* Windows
* ...more to come...

Expand All @@ -80,7 +87,3 @@ To get started there are examples in [freertos-rust-examples](freertos-rust-exam
This repository is using the MIT License. Some parts might state different licenses that need to be respected when used.

* The [Linux port](https://github.com/michaelbecker/freertos-addons) is licensed under GPLv2




15 changes: 6 additions & 9 deletions freertos-rust-examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,17 @@ repository = "https://github.com/lobaro/FreeRTOS-rust"
freertos-rust = {path = "../freertos-rust"}

[target.'cfg(target_arch = "arm")'.dependencies]
cortex-m = "0.6.0"
cortex-m-rt = {version = "0.6.12"}
nrf9160-pac = "0.2.1"
cortex-m = "0.7"
cortex-m-rt = "0.7"

# Example: stm32-cortex-m3
[target.thumbv7m-none-eabi.dependencies]
panic-halt = "0.2.0"
stm32l1xx-hal = {version = "0.1.0", features = ["stm32l151"], default-features = false}
stm32f1xx-hal = {version = "0.10", features = ["rt", "stm32f103", "medium"]}

# Example: stm32-cortex-m4-blackpill
[target.thumbv7em-none-eabihf.dependencies]
panic-halt = "0.2.0"
embedded-hal = "0.2.3"
stm32f4xx-hal = {version = "0.8.3", features = ["rt", "stm32f411"]}
embedded-hal = "1.0"
stm32f4xx-hal = {version = "0.22", features = ["stm32f411"]}

# Example: nrf9160
[target."thumbv8m.main-none-eabihf".dependencies]
Expand All @@ -39,4 +36,4 @@ nrf9160-pac = "0.2.1"
[target.x86_64-unknown-linux-gnu.dependencies]

[build-dependencies]
freertos-cargo-build = {path = "../freertos-cargo-build"}
freertos-cargo-build = {path = "../freertos-cargo-build"}
13 changes: 6 additions & 7 deletions freertos-rust-examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,29 +80,28 @@ Run the example

### Run STM32 Cortex-M3 Demo

we need the nightly build for some features like allocator_api:
We use stable toolchain and the target is thumbv7m-none-eabi:

rustup default nightly-x86_64-pc-windows-gnu // TODO: Build does not finish with GNU Toolchain
rustup default nightly-x86_64-pc-windows-msvc
rustup target add thumbv7m-none-eabi

Build the binary:

cargo build --package freertos-rust-examples --example stm32-cortex-m3 --target thumbv7m-none-eabi

Create hex file to be flashed:

cargo objcopy --example stm32-cortex-m3 --target thumbv7m-none-eabi -- -O ihex stm32-cortex-m3.hex

### Run STM32 Cortex-M4 Demo

As the previous example, we need nightly toolchain and the target is thumbv7em-none-eabihf:
We use stable toolchain and the target is thumbv7em-none-eabihf:

rustup target add thumbv7em-none-eabihf

Build the binary:

cargo build --package freertos-rust-examples --example stm32-cortex-m4-blackpill --target thumbv7em-none-eabihf

Create hex file to be flashed:

cargo objcopy --example stm32-cortex-m4-blackpill --target thumbv7em-none-eabihf -- -O ihex stm32-cortex-m4-blackpill.hex
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ extern void vAssertCalled( const char * const pcFileName, unsigned long ulLine )
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( 4200000UL ) //also systick runs at this frequency
#define configCPU_CLOCK_HZ ( 72000000UL ) //also systick runs at this frequency
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) //1000=1ms per tick, 100=10ms per tick
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 80 )
Expand All @@ -104,7 +104,7 @@ extern void vAssertCalled( const char * const pcFileName, unsigned long ulLine )
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 5
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_RECURSIVE_MUTEXES 0
#define configUSE_MALLOC_FAILED_HOOK 0 //TR
#define configUSE_APPLICATION_TASK_TAG 0
Expand Down
5 changes: 0 additions & 5 deletions freertos-rust-examples/examples/stm32-cortex-m3/layout.ld

This file was deleted.

141 changes: 47 additions & 94 deletions freertos-rust-examples/examples/stm32-cortex-m3/main.rs
Original file line number Diff line number Diff line change
@@ -1,121 +1,74 @@
#![no_std]
#![no_main]
// For allocator
#![feature(lang_items)]
#![feature(alloc_error_handler)]

extern crate panic_halt; // you can put a breakpoint on `rust_begin_unwind` to catch panics

use core::panic::PanicInfo;
use cortex_m::asm;
use cortex_m_rt::exception;
use cortex_m_rt::{entry, ExceptionFrame};
use freertos_rust::*;
use core::alloc::Layout;
use stm32l1xx_hal as hal;
use stm32l1xx_hal::hal::digital::v2::*;
use stm32l1xx_hal::gpio::*;
use stm32l1xx_hal::gpio::gpioa::PA1;

use stm32f1xx_hal::{gpio::PinState, pac, prelude::*};

#[global_allocator]
static GLOBAL: FreeRtosAllocator = FreeRtosAllocator;

fn delay() {
let mut _i = 0;
for _ in 0..2_00 {
_i += 1;
}
}

fn delay_n(n: i32) {
for _ in 0..n {
delay();
}
#[entry]
fn main() -> ! {
Task::new()
.name("default")
.stack_size(1000)
.start(move |_| {
app_main();
})
.unwrap();
FreeRtosUtils::start_scheduler();
}

static mut LED: Option<PA1<Output<PushPull>>> = None;

fn set_led(on: bool) {
unsafe {
let mut led = LED.take().unwrap();
if on {
led.set_low();
} else {
led.set_high();
}
}
}
fn app_main() -> ! {
let dp = pac::Peripherals::take().unwrap();
let mut flash = dp.FLASH.constrain();
let rcc = dp.RCC.constrain();
let _clocks = rcc
.cfgr
.use_hse(8.MHz())
.sysclk(72.MHz())
.freeze(&mut flash.acr);

let mut gpio = dp.GPIOB.split();
let mut led = gpio
.pb0
.into_open_drain_output_with_state(&mut gpio.crl, PinState::High);

// Setup IO for the LED and blink, does not return.
fn do_blink_forever() -> ! {
loop {
delay();
set_led(true);
delay();
set_led(false);
CurrentTask::delay(Duration::ms(500));
led.set_low();
CurrentTask::delay(Duration::ms(500));
led.set_high();
}
}

#[entry]
fn main() -> ! {
let dp = hal::stm32::Peripherals::take().unwrap();

// Set up the LED, it's connected to pin PA1.
let gpioa: stm32l1xx_hal::gpio::gpioa::Parts = dp.GPIOA.split();
unsafe { LED = Some(gpioa.pa1.into_push_pull_output()); }

// Initial blink
set_led(true);
delay_n(10);
set_led(false);
delay_n(10);

// Just blink (does NOT work!)
do_blink_forever();

// TODO: What comes now does not work yet!
// Initialize Tasks and start FreeRTOS
Task::new().name("hello").stack_size(128).priority(TaskPriority(1)).start(|_this_task| {
// Just blink
freertos_rust::CurrentTask::delay(Duration::ms(1000));
set_led(true);
freertos_rust::CurrentTask::delay(Duration::ms(1000));
set_led(false);
}).unwrap();


// TODO: Starting the scheduler fails, we need debugging to find the issue
// Seems like we don't even get an assert
FreeRtosUtils::start_scheduler();
}

#[allow(non_snake_case)]
#[exception]
fn DefaultHandler(_irqn: i16) {
// custom default handler
// irqn is negative for Cortex-M exceptions
// irqn is positive for device specific (line IRQ)
// set_led(true);(true);
// panic!("Exception: {}", irqn);
unsafe fn DefaultHandler(_irqn: i16) {
// custom default handler
// irqn is negative for Cortex-M exceptions
// irqn is positive for device specific (line IRQ)
// set_led(true);(true);
// panic!("Exception: {}", irqn);
asm::bkpt();
loop {}
}


#[allow(non_snake_case)]
#[exception]
fn HardFault(_ef: &ExceptionFrame) -> ! {
// Blink 3 times long when exception occures
delay_n(10);
for _ in 0..3 {
set_led(true);
delay_n(10);
set_led(false);
delay_n(5);
}
unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
asm::bkpt();
loop {}
}

// define what happens in an Out Of Memory (OOM) condition
#[alloc_error_handler]
fn alloc_error(_layout: Layout) -> ! {
set_led(true);
// We no longer need to use #[alloc_error_handler] since v1.68.
// It will automatically call the panic handler.
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
asm::bkpt();
loop {}
}
}
Loading