minimult_cortex-m 0.3.0

A minimal multitask library, or RTOS, for Cortex-M microcontrollers.
Documentation
# minimult_cortex-m

This crate for Rust provides a minimal multitask library `Minimult` for Cortex-M microcontrollers.

## Target

*Single-core* systems of

* Cortex-M0 / M0+ / M1  (`thumbv6m-none-eabi`)
* Cortex-M3  (`thumbv7m-none-eabi`)
* Cortex-M4 / M7  (`thumbv7em-none-eabi`) with FPU  (`thumbv7em-none-eabihf`)
* Cortex-M23  (`thumbv8m.base-none-eabi`)
* Cortex-M33 / M35P  (`thumbv8m.main-none-eabi`) with FPU  (`thumbv8m.main-none-eabihf`)

`Minimult` is still in **beta** because the author had only a few tests only on Cortex-M4 with FPU.

## Features

* Task like that of a typical RTOS
  * `Minimult` can take closures and register them as tasks.
  * `Minimult` runs into a loop to start dispatching those tasks.
    * *Not supported: dynamically creating and spawning.*
* Synchronization
  * `idle` and `kick`
    * A task goes into an idle state and other tasks/interrupts wake it up by kicking.
  * `MTMsgSender` and `MTMsgReceiver`
    * Task-to-task communication by message passing.
  * `MTSharedCh`
    * Shared variable among tasks.
* Priority-based dispatching
  * A higher priority task preempts lower priority tasks.
  * Round-robin dispatching within the same priority tasks.
  * `dispatch` can be directly requested so that timer-based preemption is also possible.
* Static memory allocation
  * `Minimult` doesn't require a global allocator but reserves a bunch of memory block in advance.

## Examples
### Usage Outline

```rust
// Build-only example

#![no_main]
#![no_std]

use cortex_m::Peripherals;
use cortex_m_rt::entry;
use cortex_m_rt::exception;
extern crate panic_semihosting;

// other codes...

use minimult_cortex_m::*;

#[entry]
fn main() -> ! {
    let mut mem = Minimult::mem::<[u8; 4096]>();
    let mut mt = Minimult::new(&mut mem, 2);

    // other codes...

    let mut q = mt.msgq::<u32>(4);
    let (snd, rcv) = q.ch();

    mt.register(0/*tid*/, 1, 256, || task0(snd));
    mt.register(1/*tid*/, 1, 256, || task1(rcv));

    // other codes...

    let cmperi = Peripherals::take().unwrap();
    let mut syst = cmperi.SYST;
    syst.set_clock_source(cortex_m::peripheral::syst::SystClkSource::Core);
    syst.set_reload(0xffffff);
    syst.clear_current();
    syst.enable_counter();
    syst.enable_interrupt();

    // other codes...

    mt.run()
}

#[exception]
fn SysTick()
{
    // other codes...

    Minimult::kick(0/*tid*/);
}

fn task0(mut snd: MTMsgSender<u32>)
{
    // other codes...

    loop {
        Minimult::idle();

        // other codes...

        let some_value = 1;
        snd.send(some_value);
    }
}

fn task1(mut rcv: MTMsgReceiver<u32>)
{
    // other codes...

    loop {
        let some_value = rcv.receive();
        assert_eq!(some_value, 1);

        // other codes...
    }
}
```

### Other Examples

You can find a specific board's example [here](https://github.com/convexbrain/Minimult/tree/master/examples/).
Currently there are very few examples, however.