2个版本
0.1.1 | 2020年9月21日 |
---|---|
0.1.0 | 2020年9月13日 |
#513 in 嵌入式开发
120KB
2K SLoC
juggle
在单线程环境中支持no_std的协同多任务异步任务切换。
该库提供工具来动态管理单线程或嵌入式环境中的任务组。注意,这不是一个操作系统,但可以作为不需要上下文切换的简单替代品,例如在嵌入式应用程序中。任务使用Rust的async/await机制,而插入切换点的任务则是程序员的职责。幸运的是,这个crate还提供了Yield
实用工具,以及处理忙等待。主调度器(Wheel
)可以动态地创建、挂起、恢复或取消由轮询算法管理的任务。
Crate默认使用std库(功能std
),但也可以配置为#![no_std]
,使用alloc
crate,这将禁用utils
模块中的某些功能。
示例
一个简单的程序,用于从传感器读取数据并处理。
use juggle::*;
use alloc::collections::VecDeque;
use core::cell::RefCell;
async fn collect_temperature(queue: &RefCell<VecDeque<i32>>,handle: WheelHandle<'_>){
loop{ // loop forever or until cancelled
let temperature: i32 = read_temperature_sensor().await;
queue.borrow_mut().push_back(temperature);
yield_once!(); // give scheduler opportunity to execute other tasks
}
}
async fn wait_for_timer(id: IdNum,queue: &RefCell<VecDeque<i32>>,handle: WheelHandle<'_>){
init_timer();
for _ in 0..5 {
yield_while!(get_timer_value() < 200); // busy wait but also executes other tasks.
process_data(&mut queue.borrow_mut());
reset_timer();
}
handle.cancel(id); // cancel 'collect_temperature' task.
shutdown_timer();
}
fn main(){
let queue = &RefCell::new(VecDeque::new());
let wheel = Wheel::new();
let handle = wheel.handle(); // handle to manage tasks, can be cloned inside this thread
let temp_id = handle.spawn(SpawnParams::default(),
collect_temperature(queue,handle.clone()));
handle.spawn(SpawnParams::default(),
wait_for_timer(temp_id.unwrap(),queue,handle.clone()));
// execute tasks
smol::block_on(wheel).unwrap(); // or any other utility to block on future.
}
依赖关系
~73KB