lighkLife / rcore-blog

0 stars 0 forks source link

rcore 引入异步运行时 embassy #1

Open lighkLife opened 10 months ago

lighkLife commented 10 months ago

现状描述

embassy 成功引入 内核态,并可以调用异步函数

记录遇到的问题

https://github.com/lighkLife/embassy-cn/issues

目标测例描述

以键盘鼠标时间接受为例子的处理流程:

操作步骤

加入依赖

embassy-executor = { version = "0.3.2", features = ["arch-riscv32", "nightly", "executor-thread"] }
static_cell = "2.0.0"
riscv = { version = "0.10.1", features = ["critical-section-single-hart"] }
# 如果已经依赖了 rcore 的 riscv 
# 可以 将其替换为下面的依赖, 同时修改 trap/context 中 riscv 的路径为 riscv_asm
riscv_asm = { git = "https://github.com/lighklife/riscv-asm", features = ["inline-asm"] }

crate 入口添加 rust nightly 特性

#![feature(type_alias_impl_trait)]

内核启动函数改造

use embassy_executor::Executor;
use embassy_executor::Spawner;
use lazy_static::*;
use static_cell::StaticCell;

static EXECUTOR: StaticCell<Executor> = StaticCell::new();

#[no_mangle]
pub fn rust_main() -> ! {
    let executor = EXECUTOR.init(Executor::new());
    executor.run(|spawner| {
        spawner.spawn(kernel_start(spawner)).unwrap();
    });
}

async fn test(){
    let f1 = async {
        println!("========= async test f1 ==============");
    };
    let f2 = async {
        println!("========= async test f2 ==============");
    };
    let f3 = async {
        println!("========= async test f3 ==============");
    };
    f3.await;
    f2.await;
    f1.await;
}

#[embassy_executor::task]
async fn kernel_start(spawner: Spawner) {
    clear_bss();
    mm::init();
    UART.init();
    println!("KERN: init gpu");
    let _gpu = GPU_DEVICE.clone();
    println!("KERN: init keyboard");
    let _keyboard = KEYBOARD_DEVICE.clone();
    println!("KERN: init mouse");
    let _mouse = MOUSE_DEVICE.clone();
    println!("KERN: init trap");
    trap::init();
    trap::enable_timer_interrupt();
    timer::set_next_trigger();
    board::device_init();
    fs::list_apps();
    task::add_initproc();
    *DEV_NON_BLOCKING_ACCESS.exclusive_access() = true;

    # 测试异步调用
    test().await;

    # 开始线程调度
    task::run_tasks().await;
    panic!("Unreachable in rust_main!");
}
lighkLife commented 10 months ago

image