[][src]Crate 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

// 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 mut some_value = 0;
        rcv.receive(|v| {some_value = *v});

        // other codes...
    }
}

Other Examples

You can find a specific board's example here. Currently there are very few examples, however.

Structs

MTMemBlk

Memory block used by Minimult

MTMsgQueue

Message queue for task-to-task communication

MTMsgReceiver

Message receiving channel

MTMsgSender

Message sending channel

MTShared

Shared variable among tasks

MTSharedCh

Shared variable access channel

Minimult

Multitasking API

Type Definitions

MTTaskId

Task identifier

MTTaskPri

Task priority