A simple library for context-switching on ARM Cortex-M ( 0, 0+, 3, 4, 4F ) micro-processors
Supports pre-emptive, priority based switching
This project is meant for learning and should be used only at the user's risk. For practical and mature rust alternatives, see Awesome Embedded Rust
Processor support:
- Cortex-M0
- Cortex-M0+
- Cortex-M3
- Cortex-M4
- Cortex-M4F
Features:
- Preemptive, priority-based switching
- Efficient sleep
- Accept stack memory area as a vec (arrayvec?, smallvec?) instead of &[]
- Non-privileged mode
- Mutex implementation aware of thread scheduling
The example_crates
folder contains crates showing how to
use cortexm-threads for different boards.
Available examples:
- stm32f3 - 2 threads with one thread running an LED roulette, and the other periodically printing magnetometer readings. Currently compiles for target thumbv7m-none-eabi instead of thumbv7em-none-eabihf. See Roadmap#1
- microbit - 2 threads printing messages with co-operative context switching
- qemu-m4 - (set up to run
on qemu) 2 threads printing messages via semi-hosting.
Run
cargo run
fromexample_crates/qemu-m4
directory to see it running. You must have qemu-system-arm on the system PATH.
Sample:
#![no_std]
#![no_main]
extern crate panic_semihosting;
use cortex_m::peripheral::syst::SystClkSource;
use cortex_m_rt::{entry, exception};
use cortex_m_semihosting::{hprintln};
use cortexm_threads::{init, create_thread, create_thread_with_config, sleep};
#[entry]
fn main() -> ! {
let cp = cortex_m::Peripherals::take().unwrap();
let mut syst = cp.SYST;
syst.set_clock_source(SystClkSource::Core);
syst.set_reload(80_000);
syst.enable_counter();
syst.enable_interrupt();
let mut stack1 = [0xDEADBEEF; 512];
let mut stack2 = [0xDEADBEEF; 512];
let _ = create_thread(
&mut stack1,
|| {
loop {
let _ = hprintln!("in task 1 !!");
sleep(50); // sleep for 50 ticks
}
});
let _ = create_thread_with_config(
&mut stack2,
|| {
loop {
let _ = hprintln!("in task 2 !!");
sleep(30); // sleep for 30 ticks
}
},
0x01, // priority, higher numeric value means higher priority
true // privileged thread
);
init();
}
See LICENSE.md