目标:把内核移植到 WCH CH57x 系列(重点 CH583,兼顾极窄资源的 CH572),对齐 README「移植的芯片」清单里 RISC-V 一节。
两台机器同为 QingKe + PFIC + WCH 自有 SysTick 架构,且 PFIC(0xE000E000)/SysTick(0xE000F000) 基址与系统块寄存器(0x40001000 起)逐字节基本同址,
因此计划做成一份 ch57x 芯片层 + 一组差异常量,而不是两份独立移植。
已有资料(本地已核对,未入仓):openwch/ch583 的 EVT/EXAM/{SRC,FreeRTOS,RT-Thread,HarmonyOS} 实装(startup_CH583.S / Link.ld / CH583SFR.h / core_riscv.h)与 openwch/ch570 的 CH572SFR.h / startup_CH572.S。
1. 与现有口的关系(选型结论)
基线取 src/chip/ch32v103,不是 ch32v307:V3A 与 V4A 的 PFIC+SysTick 模型同源(都靠 STK_CTLR.SWIE 触发软中断当 PendSV,都是 SR.CNTIF 写 0 清),
且都是「纯软件全保存」而非 WCH 硬件压栈路线(0x804 = 0,36 字帧,Direct mtvec)。
CH583 官方 FreeRTOS 口走的是硬件压栈+HPE 路线(("WCH-Interrupt-fast") 属性),Rust 侧表达不了,不采用。
2. 必须解决的增量(4 条)
- 代码基址是
0x00000000,不是现有各 RISC-V 口的 0x08000000;且 EVT Link.ld 只给 448K(尾部留给 BootLoader/ISP/配置)。
- 向量表第 5 个字(index 4)必须是私有 boot 标记
0xF3F9BDA9,不可改(BootLoader 靠它识别有效用户向量表)。
- BootLoader 默认开启 → 量产配置须关掉,否则不直接跑用户程序。
.highcode 段(CH57x 特有):WCH 约定 __attribute__((section(".highcode"))),VMA 在 RAM、LMA 在 FLASH,由 startup_*.S 逐字搬运;官方把所有 ISR + 高频函数塞进去(FLASH 取指有等待周期;且擦写 FLASH 期间代码不能跑在 FLASH 上)。
riscv-rt 的 link.x 不会做 LMA→VMA 搬运 → 需要决策:(a) 先不用 .highcode(代码全留 FLASH,最省事,代价是 ISR 慢 + 不能在 RAM 里跑 ISR 以避 flash 操作冲突);(b) 额外 linker script 段 >RAM AT>FLASH + 启动拷贝循环 + Rust 侧 #[link_section=".highcode"]。
- 私有 CSR:
0xbc0(流水线控制 + 动态分支预测控制位)CH583 写 0x1f、CH572 写 0x25 且另有 0xbc1=1;0x804(INTSYSCR)官方各自写 0x01/0x03。
现有 ch32v103/ch32v307 口只写 0x804=0(关 HPE),没写 0xbc0 → 需确认 CH57x 上是否必须补。
delay_us() 当前实现用 mcycle。CH57x 若不实现 Zicntr/mcycle(读出来恒 0),现有实现会死循环。CH57x 无 DWT,备选是 SysTick/TMR 计时。
3. 双机差异(决定能否共用一份芯片层)
| 项 |
CH572 |
CH583 |
| CIU 内核 |
QingKe(无 A 扩展 → 原子操作只能关中断/自旋锁) |
QingKe V4A |
| CODE |
240K(+BOOT 8K + INFO 8K) |
512K |
| DATA |
12KB(xISRStack 与任务栈全要挤) |
32KB |
| SysTick 计数器 |
32 位(CNTL/CMPL) |
64 位 |
| 软中断触发位 |
SR.SWIE(bit31)(CTLR 里没有) |
CTLR.SWIE(bit31) |
| PFIC 复位寄存器 |
无 CFGR → 只能用 PFIC->SCTLR = 0x80000000 |
CFGR = PFIC_KEY3|(1<<7) |
| PFIC FastINT 寄存器名 |
VTFIDR/VTFADDR[4] |
IDCFGR/FIADDRR[4](同址同义改名) |
IPRIOR 语义 |
priority ? 0x80 : 0(1 位抢占,无子优先级) |
整字节:bit7 抢占 / bit6-4 子优先级 |
| 外设 |
1×UART / 1×SPI / 1×TMR / 无 ADC / 1×USB,另有 LCD·按键扫描·正交编码器·4 比较器 |
4×UART / 2×SPI / 4×TMR / ADC+温度 / 2×USB,另有触摸按键 |
| 中断号 |
Reset=0;外部尾部 …KEYSCAN=33, ENCODE=34, WDOG_BAT=35 |
Reset=1;尾部 TMR3=32, UART2=33, UART3=34, WDOG_BAT=35 |
(Core 槽完全一致:NMI=2、EXC=3、SysTick=12、SWI=14 可当 PendSV。)
4. 上板前必须核对(构建级已静态确认,板上行为待验)
5. 验收标准
6. 参考
openwch/ch583(Apache-2.0):官方 SDK,EVT 自带 FreeRTOS / RT-Thread / HarmonyOS 三份移植(libcpu/WCH/Qingke_V4A/* 是最直接的内核对照)
biemster/ch32fun_freertos(CC0):ch5xx 的 FreeRTOS RISC-V port(port.c/portASM.S/portmacro.h)
cnlohr/ch32fun(MIT):examples_ch5xx/ 有 ch570_encoder_timer、ble_beacon、lowpower
biemster/ch570_ble:BLE broadcaster + 闭源 libCH572BLE_PERI.a/libCH57xRF.a(BLE 先不带;这些库的 ISR 跑在中断上下文、栈需求大,12K SRAM 上尤其危险)
备注:本轮已完成的静态比对见工作区 pdfwork/ch583-xtask-port-guide.md(CH583 移植速查表)与 pdfwork/ch572-vs-ch583-diff.md(双机对照表),素材副本在 pdfwork/ch583src/、pdfwork/ch572src/。
补记(2026-09-19):上述 pdfwork/* 素材不在仓库也不在工作区,审查者与后来读者无法复算(已按 startup_CH583.S/CH572SFR.h 等文件名全盘搜过,零命中)。寄存器常量与启动头布局现改按官方 openwch/ch583 EVT 源码逐条核对,出处写进 src/chip/ch583/port.{S,rs} 注释与 docs/README.md 的芯片手册表;本仓 ci/check_ch583_boot.py 把启动头布局钉成机器可检。
目标:把内核移植到 WCH CH57x 系列(重点 CH583,兼顾极窄资源的 CH572),对齐 README「移植的芯片」清单里 RISC-V 一节。
两台机器同为 QingKe + PFIC + WCH 自有 SysTick 架构,且 PFIC(
0xE000E000)/SysTick(0xE000F000) 基址与系统块寄存器(0x40001000起)逐字节基本同址,因此计划做成一份
ch57x芯片层 + 一组差异常量,而不是两份独立移植。已有资料(本地已核对,未入仓):
openwch/ch583的EVT/EXAM/{SRC,FreeRTOS,RT-Thread,HarmonyOS}实装(startup_CH583.S/Link.ld/CH583SFR.h/core_riscv.h)与openwch/ch570的CH572SFR.h/startup_CH572.S。1. 与现有口的关系(选型结论)
基线取
src/chip/ch32v103,不是ch32v307:V3A 与 V4A 的 PFIC+SysTick 模型同源(都靠STK_CTLR.SWIE触发软中断当 PendSV,都是SR.CNTIF写 0 清),且都是「纯软件全保存」而非 WCH 硬件压栈路线(
0x804 = 0,36 字帧,Directmtvec)。CH583 官方 FreeRTOS 口走的是硬件压栈+HPE 路线(
("WCH-Interrupt-fast")属性),Rust 侧表达不了,不采用。2. 必须解决的增量(4 条)
0x00000000,不是现有各 RISC-V 口的0x08000000;且 EVTLink.ld只给 448K(尾部留给 BootLoader/ISP/配置)。0xF3F9BDA9,不可改(BootLoader 靠它识别有效用户向量表)。.highcode段(CH57x 特有):WCH 约定__attribute__((section(".highcode"))),VMA 在 RAM、LMA 在 FLASH,由startup_*.S逐字搬运;官方把所有 ISR + 高频函数塞进去(FLASH 取指有等待周期;且擦写 FLASH 期间代码不能跑在 FLASH 上)。riscv-rt的link.x不会做 LMA→VMA 搬运 → 需要决策:(a) 先不用.highcode(代码全留 FLASH,最省事,代价是 ISR 慢 + 不能在 RAM 里跑 ISR 以避 flash 操作冲突);(b) 额外 linker script 段>RAM AT>FLASH+ 启动拷贝循环 + Rust 侧#[link_section=".highcode"]。0xbc0(流水线控制 + 动态分支预测控制位)CH583 写0x1f、CH572 写0x25且另有0xbc1=1;0x804(INTSYSCR)官方各自写0x01/0x03。现有
ch32v103/ch32v307口只写0x804=0(关 HPE),没写0xbc0→ 需确认 CH57x 上是否必须补。delay_us()当前实现用mcycle。CH57x 若不实现Zicntr/mcycle(读出来恒 0),现有实现会死循环。CH57x 无 DWT,备选是 SysTick/TMR 计时。3. 双机差异(决定能否共用一份芯片层)
+BOOT 8K + INFO 8K)CNTL/CMPL)SR.SWIE(bit31)(CTLR里没有)CTLR.SWIE(bit31)CFGR→ 只能用PFIC->SCTLR = 0x80000000CFGR = PFIC_KEY3|(1<<7)VTFIDR/VTFADDR[4]IDCFGR/FIADDRR[4](同址同义改名)IPRIOR语义priority ? 0x80 : 0(1 位抢占,无子优先级)Reset=0;外部尾部 …KEYSCAN=33, ENCODE=34, WDOG_BAT=35Reset=1;尾部TMR3=32, UART2=33, UART3=34, WDOG_BAT=35(Core 槽完全一致:
NMI=2、EXC=3、SysTick=12、SWI=14可当 PendSV。)4. 上板前必须核对(构建级已静态确认,板上行为待验)
0x00000000是否可写 / 是否存在0x08000000别名mcycle是否存在(决定delay_us走mcycle还是 SysTick/TMR)INTSYSCR(0x804)写 0 后,中断入口是否确实不再硬件压栈(决定 36 字帧是否成立)已按官方 SDK 确认(2026-09-19,PR feat(chip): 新增 WCH CH583(QingKe V4A) 移植骨架(构建级) #15):csrw 0xbc0, 0x1f是否必须EVT/EXAM/SRC/Startup/startup_CH583.S的 reset 序列逐字写li t0,0x1f; csrw 0xbc0,t0,本口保留;上板只需确认不触发 Illegal InstructionCTLR.SWIE置 1 后是否真进SysTick入口、且SR.CNTIF仍为 0(CH572 需换到SR位置)。本项已升级(2026-09-19 独立审查):官方 CH583 三套 RTOS 移植(FreeRTOS/RT-Thread/HarmonyOS)都不走CTLR.SWIE(SDK 里只定义、零使用),一律用青稞专用SWI_IRQn=14+SW_Handler(FreeRTOSportYIELD()=PFIC_SetPendingIRQ(SWI_IRQn));本口沿用 ch32v103 模板的 SWIE,故上板要验的是"SWIE 可用 / 否则改走 IRQ 14"两条路BootLoader 是否拦截启动头已复刻(2026-09-19,PR feat(chip): 新增 WCH CH583(QingKe V4A) 移植骨架(构建级) #15):flash0x00..0x17= 入口跳转 + 向量表前 5 字,boot option0xF3F9BDA9落在 0x14(官方Ld/Link.ld把.vector的 flash LMA 摆在.init的j handle_reset之后,故不是 0x10 —— 本 issue 正文原写的 0x10 有误);链接期ASSERT钉地址 +ci/check_ch583_boot.py钉产物字节。实板仍需确认"是否确实进用户程序"R8_SAFE_ACCESS_SIG@0x40001040=0x57→0xA8解锁,之后凡写R8_RST_WDOG_CTRL/R8_PLL_CONFIG/R32_OSC32M_CTRL/R32_MISC_CTRL等必须先解锁,否则写入被丢弃;R32_MISC_CTRL还要按官方写法&= ~7; |= 0x600000055. 验收标准
cargo build --example multitask_ch583 --features ch583,timer --target riscv32imac-unknown-none-elf --release通过(✅ 2026-09-19,PR feat(chip): 新增 WCH CH583(QingKe V4A) 移植骨架(构建级) #15:已进门禁,并附启动头产物级校验),且--features ch572同构通过(✅ 2026-09-19,PR feat(chip): 新增 CH572(青稞无 A 扩展/RV32IMC)移植口 + 12K SRAM 栈账实测 #17:ch572 口落地,门禁含 riscv32imc 构建 + 启动头产物校验);无a扩展时riscv32imc-unknown-none-elf也过。✅ "riscv32imc 也过"已打通(2026-09-19,PR feat(arch): RISC-V 无 A 扩展目标的原子垫片(critical-section 收归一处) #16):内核的原子读改写本就封装在
atomic-polyfill里(arc/semaphore/notify),缺的只是critical-section的 RISC-V 实现——已收归src/arch/riscv/critical.rs(存mstatus.MIE→ 关中断 → 按旧值恢复,单核语义)。同一 ch583 示例在riscv32imc下编译+链接通过,产物反汇编 0 条 AMO/LR/SC(有 A 的 imac 产物 12 条作阳性对照),门禁已含该目标构建。剩下的只是 CH572 口自身的差异常量(32 位 SysTick、软中断位在SR、PFIC 无CFGR、12K SRAM 的栈账)。multitask_*例程语义(优先级抢占 + 同优先级时间片 + IPC)。CH32V?风格两行(注明「构建级验证 / 真机待验」)。 ✅(2026-09-19,PR feat(chip): 新增 WCH CH583(QingKe V4A) 移植骨架(构建级) #15/feat(chip): 新增 CH572(青稞无 A 扩展/RV32IMC)移植口 + 12K SRAM 栈账实测 #17:已加CH58x: ch583与CH57x: ch572两行,均标注构建级验证/真机待验)6. 参考
openwch/ch583(Apache-2.0):官方 SDK,EVT 自带 FreeRTOS / RT-Thread / HarmonyOS 三份移植(libcpu/WCH/Qingke_V4A/*是最直接的内核对照)biemster/ch32fun_freertos(CC0):ch5xx 的 FreeRTOS RISC-V port(port.c/portASM.S/portmacro.h)cnlohr/ch32fun(MIT):examples_ch5xx/有ch570_encoder_timer、ble_beacon、lowpowerbiemster/ch570_ble:BLE broadcaster + 闭源libCH572BLE_PERI.a/libCH57xRF.a(BLE 先不带;这些库的 ISR 跑在中断上下文、栈需求大,12K SRAM 上尤其危险)备注:本轮已完成的静态比对见工作区
pdfwork/ch583-xtask-port-guide.md(CH583 移植速查表)与pdfwork/ch572-vs-ch583-diff.md(双机对照表),素材副本在pdfwork/ch583src/、pdfwork/ch572src/。补记(2026-09-19):上述
pdfwork/*素材不在仓库也不在工作区,审查者与后来读者无法复算(已按startup_CH583.S/CH572SFR.h等文件名全盘搜过,零命中)。寄存器常量与启动头布局现改按官方openwch/ch583EVT 源码逐条核对,出处写进src/chip/ch583/port.{S,rs}注释与docs/README.md的芯片手册表;本仓ci/check_ch583_boot.py把启动头布局钉成机器可检。