#cortex-m #rtos #memory-block #multitask

无 std minimultcortex-m

为 Cortex-M 微控制器提供的一个最小多任务库或 RTOS

7 个版本

0.3.3 2019年11月20日
0.3.2 2019年11月12日
0.3.0 2019年10月25日
0.2.1 2019年10月23日
0.1.0 2019年10月20日

嵌入式开发 中排名第 671

无许可证

69KB
1.5K SLoC

Rust 1K SLoC // 0.2% comments GNU Style Assembly 156 SLoC Shell 20 SLoC Alex 20 SLoC

包含(静态库,3KB)thumbv8m.main-none-eabihf_minimult_asm.a,(静态库,3KB)asm/thumbv6m-none-eabi_minimult_asm.a,(静态库,3KB)asm/thumbv7em-none-eabi_minimult_asm.a,(静态库,3KB)asm/thumbv7em-none-eabihf_minimult_asm.a,(静态库,3KB)asm/thumbv7m-none-eabi_minimult_asm.a,(静态库,3KB)thumbv8m.base-none-eabi_minimult_asm.a更多

minimult_cortex-m

此软件包为 Rust 提供了一个最小多任务库 Minimult,用于 Cortex-M 微控制器。

目标

单核 系统

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

功能

  • 类似典型 RTOS 的任务
    • Minimult 可以接收闭包并将它们注册为任务。
    • Minimult 通过循环启动这些任务的调度。
      • 不支持:动态创建和生成。
  • 同步
    • idlekick
      • 任务进入空闲状态,其他任务/中断通过踢动唤醒它。
    • MTMsgSenderMTMsgReceiver
      • 通过消息传递进行任务间通信。
    • MTSharedCh
      • 任务间的共享变量。
  • 基于优先级的调度
    • 高优先级任务抢占低优先级任务。
    • 同一优先级任务内的轮询调度。
    • 可以直接请求 dispatch,从而实现基于定时器的抢占。
  • 静态内存分配
    • Minimult 不需要全局分配器,但预先保留了一块内存。

示例

使用方法

// Runnable on QEMU ARM

#![no_main]
#![no_std]

use cortex_m::Peripherals;
use cortex_m_rt::entry;
use cortex_m_rt::exception;
use cortex_m_semihosting::debug;
use cortex_m_semihosting::hprintln;
use panic_semihosting as _;

use minimult_cortex_m::*;

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

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

    let sh = mt.share::<u32>(0);
    let shch1 = sh.ch();
    let shch2 = sh.ch();

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

    // SysTick settings
    let cmperi = Peripherals::take().unwrap();
    let mut syst = cmperi.SYST;
    syst.set_clock_source(cortex_m::peripheral::syst::SystClkSource::Core);
    syst.set_reload(1_000_000);
    syst.clear_current();
    syst.enable_counter();
    syst.enable_interrupt();

    // must be error in terms of lifetime and ownership
    //drop(mem);
    //drop(q);
    //drop(snd);
    //drop(rcv);
    //drop(sh);
    //drop(shch1);
    //drop(shch2);

    hprintln!("Minimult run").unwrap();
    mt.run()
}

#[exception]
fn SysTick()
{
    Minimult::kick(0/*tid*/);
}

fn task0(mut snd: MTMsgSender<u32>)
{
    for vsnd in 0.. {
        Minimult::idle();

        hprintln!("task0 send {}", vsnd).unwrap();
        snd.send(vsnd);
    }
}

fn task1(mut rcv: MTMsgReceiver<u32>, shch: MTSharedCh<u32>)
{
    for i in 0.. {
        let vrcv = rcv.receive();

        assert_eq!(i, vrcv);
        hprintln!("task1 touch {}", vrcv).unwrap();
        let mut vtouch = shch.touch();
        *vtouch = vrcv;
    }
}

fn task2(shch: MTSharedCh<u32>)
{
    let mut j = 0;

    while j < 50 {
        let vlook = shch.look();

        assert!(j <= *vlook);
        //hprintln!("task2 look {}", *vlook).unwrap(); // many lines printed
        j = *vlook;
    }

    hprintln!("task2 exit").unwrap();
    debug::exit(debug::EXIT_SUCCESS);
}

其他示例

您可以在 此处 找到特定板子的示例。 目前示例非常少。

依赖项

~1MB
~16K SLoC