# CORTEXM_THREADS 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](https://github.com/rust-embedded/awesome-embedded-rust) ## Current State Processor support: - [x] Cortex-M0 - [x] Cortex-M0+ - [x] Cortex-M3 - [ ] Cortex-M4 - [ ] Cortex-M4F Features: - [x] Preemptive, priority-based switching - [x] Efficient sleep - [ ] Accept stack memory area as a vec (arrayvec?, smallvec?) instead of &[] - [ ] Non-privileged mode - [ ] Mutex implementation aware of thread scheduling ## Examples The `example_crates` folder contains crates showing how to use cortexm-threads for different boards. Available examples: - [stm32f3](./example_crates/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](./example_crates/microbit) - 2 threads printing messages with co-operative context switching - [qemu-m4](./example_crates/qemu-m4) - (set up to run on qemu) 2 threads printing messages via semi-hosting. Run `cargo run` from `example_crates/qemu-m4` directory to see it running. You must have qemu-system-arm on the system PATH. Sample: ```rust #![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(); } ``` # License See [LICENSE.md](LICENSE.md)