设计取舍
前七部分按代码讲机制,每一章都顺带碰到一些「这样做换来了什么、付出了什么」。这一部分只有一页,把它们收到一起:每一条先说 embassy 选了什么,再说收益和代价,数字取自本卷某一页的实验,链接指向那一页,这里不重讲机制。对照的对象主要是 tokio,它那一侧的机制取自 tokio 卷;RTOS 和 RTIC 本机没有搭,只写结构上的差别。另外这一页补了两个实验:两个任务经 channel 来回传一个数的开销(std 上对照 tokio,QEMU 上对照三种 RawMutex),以及开不开 LTO 对链接期符号的影响。
- 设计取舍:十条取舍、一份上游问题记录、一张文档与代码不符的表和一节同机实测。任务存储在编译期定死,spawn 不分配,代价是任务数和每个 future 的大小都要在链接前定下来;中断直接调 waker、空闲时
WFE,一次定时器唤醒约 170 条指令,但醒几次取决于时间驱动;一个执行器单线程协作,抢占靠InterruptExecutor,同样的负载延迟差 450 倍;时间驱动、定时器队列、pender、trace 都是链接期符号,错误推迟到链接,不开 LTO 时是真的函数调用;RawMutex类型参数让同一个Channel用在三种上下文,实测每个来回 511 到 615 条指令;等待者只占一个 waker 槽,几个任务一起等时 CPU 不睡;embassy-stm32 用build.rs和 1533 份芯片数据覆盖整个 STM32 产品线;Peri和bind_interrupts!把外设所有权和中断绑定搬到编译期;几十个 crate 各自发版,本卷核对出 25 处文档与代码不符。
flowchart TB timer["定时器主线"] --> st["静态任务"] timer --> wfe["中断唤醒 WFE"] timer --> sym["链接期符号"] irq["中断主线"] --> peri["Peri 与绑定"] irq --> gen["代码生成"] cross["跨任务主线"] --> rm["RawMutex 参数"] cross --> slot["单槽 waker"] st --> cmp["对照 tokio"] wfe --> cmp rm --> cmp
💬 关联讨论
发起讨论加载中...