第三十周工作总结
概述
在完成设计文档与实现计划后,本周实现了 K3 RT24 rcpu1 极简固件的全部代码——从 CCU 时钟链、PXA-UART 驱动、pinmux 配置到 Chip/TimerChip trait 实现,以及独立的 K3 app crate 与构建脚本。同时完成了一次重要的 platform 层重构:用 Chip::board_init() 替代了对外暴露的 extern "C" _board_init 弱符号模式,使 chip 初始化成为标准 trait 方法。全部改动已通过编译+符号验证,合并入 main 分支。
20 个文件、+1580/-62 行,产物:k3-minimal bin——编译出 ELF(entry=0x100804000),经 objcopy 即可生成刷板固件。
1. chip-k3-rt24 完整实现
1.1 硬件初始化序列(7 步,main.c 已验证)
| 步 | 操作 | 对应文件 |
|---|---|---|
| 1 | SPL 握手回写 write32(0xc088007c, 1) (如果不和spl握手,其会忙等一段时间) | clock.rs |
| 2 | 上游 ruart_14 DDN gate | clock.rs |
| 3 | UART0 末端 gate + mux 选择 | clock.rs |
| 4 | pinmux:GPIO_122/123 → MUX_MODE4 | clock.rs |
| 5 | 波特率/帧格式(8N1, 115200) | uart.rs |
| 6 | UUE 单元使能(PXA 专属,最易漏) | uart.rs |
| 7 | put_str 轮询 THR | uart.rs |
这 7 步在 clock::early_init() + uart::init() 中完成,经 _board_init → Chip::board_init() 链在用户 main 之前执行。
clock.rs 中的寄存器常量(ruart_14 gate num/den、uart0 mux/div)均与 ESOS 源码 ccu-spacemit-k3.c 逐项交叉验证。
2. Platform 层重构:Chip::board_init()
2.1 问题
初版设计用 link.x PROVIDE + #[no_mangle] extern "C" fn _board_init() 作为 chip 钩子机制:
- arch crate 提供
_default_board_init(空),link.xPROVIDE(_board_init = _default_board_init) - chip crate 用强
_board_init覆盖
这虽然可行,但 _board_init 是一个脱离 trait 体系的裸 extern "C" 函数——调用方(platform)和实现方(chip)之间没有 Rust 类型约束,也没有文档化的接口契约。
2.2 方案
在 Chip trait 中增加 board_init() 方法(带默认空实现),platform 通过 ChipImpl::board_init() 调用。chip crate 在 impl Chip for K3Rt24 中重写该方法即可。
优势:
- Rust trait 提供编译期类型检查,实现方不匹配即编译失败
- 所有 chip 初始化统一走
Chiptrait,新 chip crate 只需impl Chip,无需理解 link.x 弱符号机制 - 调用方代码
ChipImpl::board_init()自文档化
3. 独立 K3 app crate 与构建链
3.1 架构隔离
新建 apps/rt-async-k3 crate,与 QEMU apps/rt-async-app 完全隔离:
- 各自 memory.x(K3:
0x100804000,QEMU:0x80200000) - 各自 target triple(共用
riscv64imac-unknown-none-elf) - K3 app bin 通过
#[used] static引用chip_k3_rt24::K3Rt24,确保 chip rlib 被链接器拉入
3.2 xtask 统一命名
xtask build 统一 bin 命名为 <platform>-<bin>(如 qemu-demo、k3-minimal),K3 构建产物为 ELF 而非 bin(objcopy 留给脚本,因需刷板前确认)。
4. 刷板验证(7/5 完成)
4.1 真板上成功启动
周五(7/5)成功将 k3-minimal 固件刷入 K3 实体板,R_UART0 输出启动日志:
I am alive! Hello from rt-async on K3 RT24!注:rcpu1 的固件加载由 SPL 通过
rproc_load/rproc_start完成,esos.itb中rcpu1-fw节点的 load/entry0x1_804000是 RT24 SRAM 内的硬编码地址,不可改动。
5 刷写自动化工具链(scripts/flash/)
为缩短迭代周期,创建了一套完整的一键刷写自动化工具链,覆盖编译→打包→刷写的全流程:
scripts/flash/
├── k3-flash.sh # 主编排:一键编译+打包+刷写(7 步串联)
├── k3-pack-itb.sh # itb 打包(自包含,不依赖 esos 仓库)
├── k3-console.py # pyserial 串口交互(ensure-uboot / run / fastboot)
├── flash.conf # 串口配置(编辑一次即可)
├── esos_k3_com260_ifx.its # 精简 ITS 模板(仅 com260_ifx 板型,5 节点)
├── payloads/ # 固定 payload(入库)
│ ├── rt24_os0_rcpu.elf # rcpu0 esos 固件(固定复用)
│ ├── k3_rt240_com260_ifx.dtb # rcpu0 设备树
│ ├── k3_rt241_com260_ifx.dtb # rcpu1 设备树
│ └── null.spacemit # AP 交互 blob
└── README.mdk3-flash.sh 编排以下 7 步:
▶ build k3-minimal # cargo xtask build k3-minimal
▶ pack esos.itb # cp ELF + lzo + mkimage(自包含)
▶ ensure board at U-Boot prompt # reset + 抓 autoboot 窗口 → =>
▶ enter fastboot # 板端 fastboot usb 0,主机轮询 devices
▶ fastboot stage # 主机 stage 传输 itb → Ctrl-C 退出 fastboot
▶ mtd erase / write # 写 flash
▶ ensure-uboot # reset 停在 =>,新固件已就绪一键运行:./scripts/flash/k3-flash.sh
6 其他改动
- README.md 更新:修正构建步骤顺序(子模块 → xtask setup → xtask build → rootfs → install → run),补充 Musl 工具链从 setup-musl 预编译包安装的说明
- rt-async 子模块更新:同步平台重构(
Chip::board_init()替代弱符号)和相关文档
7. 本周在 K3 迁移中的位置
对应 项目计划-20260528 K3 适配第一阶段,与上周(二十九周)"下周计划"及本周补充工作对齐:
| 上周/本周计划项 | 本周状态 |
|---|---|
| 定位 UART 输入乱码根因 | 🟡 疑似硬件问题(CH340),待新硬件到货对照 |
实现 PXA-UART Chip::put_str + CCU 时钟使能 | ✅ 完成(clock.rs + uart.rs,7 步初始化) |
| 刷板验证:R_UART0 看到 rt-async 启动日志 | ✅ 真板上成功输出! |
| 刷写自动化工具链 | ✅ scripts/flash/ 一键刷写 |
| 替代路线调研(软复位/JTAG) | ✅ 两条路线均否决,选自动化 itb+mtd 路线 |
里程碑达成:从代码编译到真板运行的全链路已打通。
8. 下周计划
- 替换 StarryOS 为周雨同学版本:用 tgoskits 仓库中的 StarryOS 替换当前版本,适配 K3 真板
- AMP 双系统通信调试:
- 在真板上跑通 StarryOS(X100 大核)与 rt-async(RT24 小核)的共享内存 + IPI 通信
- 移植现有 ov-channels / ov-rpc 到真板拓扑
- TimerChip 真实现:研究 rtimer0 寄存器映射,实现
set_alarm/enable_timer_irq,让调度器时钟跑起来 - 目标:RT24 上跑通完整的 rt-async 调度循环(定时器中断 → 任务切换)