Skip to content

feat(chip): 新增 WCH CH583(QingKe V4A) 移植骨架(构建级) - #15

Merged
gqf2008 merged 11 commits into
masterfrom
feat/ch57x
Sep 19, 2026
Merged

gqf2008 merged 11 commits into
masterfrom
feat/ch57x

Conversation

@gqf2008

@gqf2008 gqf2008 commented Sep 18, 2026 •

Copy link
Copy Markdown
Owner

关联

Refs #14(不写 Closes——真机未验证,不关 issue)

变更概述

  • 新增 src/chip/ch583/{mod.rs, port.rs, port.S, restore_ctx.S, memory.x},以 src/chip/ch32v103/(V3A,同为 PFIC + WCH 自有 SysTick + 纯软件全保存)为模板。
  • 新增 examples/multitask_ch583.rs(构建级示例,与 examples/multitask_ch32v103.rs 同构)。
  • Cargo.toml 增 ch583 = ["riscv-rt"](CH58x 无现成 ch32-rs PAC,零 PAC 直址访问);build.rs、src/chip/mod.rs 注册;src/chip/env.rs 增时钟常量。
  • ROM 启动头 .bootvec(见下「启动头」)。
  • src/port.rs 芯片接线收成单一来源清单 + build.rs 接线守卫(见下「接线守卫」)。
  • 门禁加 ch583 构建 + 启动头产物级校验;README / CLAUDE.md / docs 同步登记。

原始寄存器常量与布局已按官方 openwch/ch583 EVT 源码逐条核对(Startup/startup_CH583.S、Ld/Link.ld、RVMSIS/core_riscv.h、StdPeriphDriver/inc/CH583SFR.h),出处写在源码注释里。

与既有口的 4 个关键差异

  1. 代码基址 0x00000000(非 0x08000000):memory.x FLASH ORIGIN = 0x0, LENGTH = 448K(官方 Link.ld 只给 448K,尾部 64K 留给 BootLoader/ISP/配置区);RAM ORIGIN = 0x20000000, LENGTH = 32K。前 0x18 字节留给启动头,.text 顶到 0x18。
  2. 私有 CSR 0xbc0 = 0x1f:_setup_interrupts 在关 HPE 之前多写一条——与官方 startup_CH583.S reset 序列逐字一致(CH572 是 0xbc0=0x25 且另有 0xbc1=1)。
  3. Direct mtvec + 0x804=0(关 HPE,纯软件全保存):mtvec = _start_trap & ~3(低 2 位 0,不是官方向量模式的 | 3);intsyscr(0x804) = 0 关硬件压栈/嵌套(官方 startup 写 0x3 开 HWSTKEN+嵌套,本口刻意走 36 字全保存帧),退回标准 RV32 机器模式。
  4. SysTick 64 位 + CTLR.SWIE 当 PendSV:SysTick @0xE000_F000;初始化 CTLR = INIT(5)|STRE(3)|STCLK(2)|STIE(1)|STE(0) = 0x2F(与官方 SysTick_Config() 逐位一致,不带 SWIE;SWIE 只在运行期 irq() 里置位请求切换——初始化就置 SWIE 会让第一个任务 mret 后立刻多进一次 trap,且早于 restore_ctx.S 写 mscratch);SR.CNTIF 写 0 清;systick() 读 64 位 CNT(高:低:高重读,非 CH572 的 32 位读法);PFIC IENR[0] @0xE000E100 bit12 使能核中断 12。

启动头(ROM boot option)

官方 EVT/EXAM/SRC/Startup/startup_CH583.S 的 .vector 段第 5 个字固定 0xF3F9BDA9(注释 boot option, can't modify);官方 Ld/Link.ld 把 .vector 的 flash LMA 摆在 .init 的 j handle_reset 之后 → 该字落在 flash 0x14。

本口新增 .bootvec 复刻同一布局:

flash 0x00   j _start                 # ROM 取指入口(官方 .init 的 j handle_reset 同位)
flash 0x04   .word 0 / 0x08 .word 0   # 向量表[0][1](官方为 0)
flash 0x0c   .word _start_trap        # 向量表[2] NMI(本口 Direct mtvec,CPU 不读这张表)
flash 0x10   .word _start_trap        # 向量表[3] HardFault
flash 0x14   .word 0xF3F9BDA9         # 向量表[4] boot option, can't modify

摆放:memory.x 的 SECTIONS 把 .bootvec 钉到 flash 0x0,同时先定义 _stext = 0x18 把 .text 顶到启动头之后(riscv-rt 的 PROVIDE(_stext=...) 不覆盖已定义符号);链接期 ASSERT(_bootvec==0x0 / _boot_magic==0x14) 钉地址,产物级由 ci/check_ch583_boot.py 读 ELF 钉段地址、入口跳转与魔数字节。

接线守卫(防"构建绿、运行期 panic")

src/port.rs 的芯片选择原本是两份手写名单(每口一条正选 pub use ... as Porting + 兜底 not(any(...)) 的 feature 名单)。上一提交新增 ch583 时两处都漏 → Porting 落到 DefaultPorting(各方法 unimplemented!()),构建门禁全绿、运行期进 xtask::start() 才 panic(修前取证:整份 disasm 里 mscratch 只出现一次、无 Ch583Porting 符号)。

现改为 chip_portings! 单一来源清单,一次生成:正选别名 / 兜底名单 / RealPorting 标记实现 + 编译期断言;build.rs 再按 src/chip/<名字> 目录 ⇄ 启用 feature ⇄ 登记表三方交叉。漏登记 = 构建期失败。接线修复保留在独立提交 1554aef(未 amend 骨架提交,保留可追溯性)。

验收证据

宿主 x86_64-pc-windows-msvc,rustc 1.91.0-nightly(rust-toolchain 钉的 nightly-2025-08-08)。本地全门禁 bash ci/gate.sh:

== [1/3] 宿主回归:  test result: ok. 159 passed; 0 failed
== [2/3] 示例链接:  PASS: 向量表第 56 项 -> USART0 @0x08002A52
                    PASS: 启动头 @0x0..0x18 — 入口跳转 + boot option 0xF3F9BDA9 @0x14
== [3/3] QEMU 执行级:
        qemu_pingpong: PASS(A×200 B×200,调度/切换/节拍执行级验证)
        qemu_kernel_tests: 24/24 passed
        qemu_kernel_tests -smp 2: 24/24 passed
        qemu_kernel_tests(tlsf 全局后端): 24/24 passed
        qemu_smp -smp 2: 9/9 passed
== 全部通过 ==

阳性对照(证明新守卫真会红,验后已复原):①删 src/port.rs 的 "ch583" => 登记行 → build.rs 报红;②魔数改 0xF3F9BDAA → ci/check_ch583_boot.py 报红;③.bootvec 挪到 0x4 → 链接期 ASSERT 报红。

移植口回归:13 口 cargo build --lib 全绿(riscv32imac 8 口 / thumbv7em 2 口 / thumbv7m / thumbv6m / armv7r);默认 features cargo test --lib = 82 passed(README 旧记 80 已在本 PR 修正)。

⚠️ QEMU 边界:QEMU 没有 QingKe/PFIC 对应机器,ch583 本口无法仿真执行;QEMU 侧验证的是"内核执行级不回归"(qemu_riscv 口),ch583 只能到构建级 + 产物级(启动头字节、符号、反汇编)。

复审(5 遍)修正与证据

复审(依据核对 / 链接布局与产物 / Rust 逻辑与 cfg / 守卫有效性 / 端到端回归)查出两个真问题,已修:

  1. 示例堆仍然不够(重点)。QEMU 探针实测(同一 32 位分配器与 Task 布局;WCH 侧无法仿真,故在 qemu_riscv 口用同一任务组合取数):
    • 15 个示例任务 = 17,768 B;加软件定时器任务(1024 字 ≈4.4K)+ idle(512 字 ≈2.2K)后 ≈ 24.4K → 24K 堆会在 start() 里 panic("memory out")(已实测复现);而 32K SRAM 里 _sheap→_stack_start 只有 28.3K,给不出 26K+ 的堆。
    • 修法:示例任务 15 → 12(仅 example_task 的 5 个纯打印任务留 2 个;semaphore/queue 各 5 个不动,同优先级时间片与 IPC 语义不变)→ 12 任务 + timer + idle ≈ 20.9K,24K 堆余量 ≈3.6K(堆顶 0x20007188 距中断栈基 0x20007E00 仍 3.2K)。探针实测:heap=24576B 时 含 timer+idle 已用=22104B 空闲=2472B 且打出 METER-DONE。
  2. 校验脚本两处健壮性:①用 assert 判文件类型,-O 下会被关掉 → 改显式判断并补 ELF32/小端校验;②入口只认 4 字节 JAL → 放宽为 JAL/c.j(真正钉死布局的是段地址与魔数偏移,严编码只会引入误报)。

复核结论(证据):

  • 官方布局实测:用官方 Ld/Link.ld + 官方 .init/.vector 段内容链接出的 flash 镜像,0x14 处正是 0xF3F9BDA9 —— "魔数在 flash 0x14"由推演升级为实测(顺带确认:官方把 .vector 放在 .highcode 里 >RAM AT>FLASH,LMA 起点 0x04)。
  • 常量逐条核对:PFIC->IENR[0] @0x100 bit12 与官方 PFIC_EnableIRQ(SysTick_IRQn=12) 逐字等价;start_scheduler 反汇编确认 CMPLR=59999、CTLR=0x2F(无 SWIE)、IENR bit12;STK 基址与 SysTick_Type{CTLR,SR,u64 CNT,u64 CMP} 字偏移一致;SR.CNTIF 写 0 清。
  • 产物级:objcopy -O binary 的实际烧录镜像前 0x18 字节 = j _start + 0/0 + _start_trap×2 + F3F9BDA9;_stext=0x18、_stack_start/_sheap 与整改前一致(无布局回归)。
  • 守卫有效性(阳性对照,验后已复原):删 "ch583" => 登记行 → build.rs 报红;魔数改 0xF3F9BDAA → 脚本报红;.bootvec 挪到 0x4 → 链接期 ASSERT 报红;RealPorting 实现 cfg 掉 → E0277。脚本对整改前 ch583 ELF 报"没有 .bootvec 段"、对合成 ELF64 报"期望 32 位小端 ELF"。
  • 端到端:bash ci/gate.sh 全绿(host 159 / ISR 向量 / ch583 启动头 / qemu_pingpong A×200 B×200 / qemu_kernel_tests 24-24 与 -smp2、tlsf 三跑 / qemu_smp 9-9 / 全部通过);13 口 cargo build --lib 全绿;宿主默认 features 82 passed。
    • 注:首次门禁在 tlsf 变体红过一次(输出停在 suite starting),单独复跑 24/24、整门禁复跑亦全绿 —— 判为本机偶发,非回归。

第三轮:独立审查(全新会话,仅给任务书与一手资料)

结论:需修改(2 处文档级旧值 + 1 条设计观察),已全部处理(6c3e984):

  1. examples/multitask_ch583.rs 上板核对清单第 ③ 条仍写 CTLR=0x8000_002F(代码已改成 0x2F)→ 已改正;第 ④ 项升级为"官方 CH583 三套移植都不走 CTLR.SWIE,一律 SWI_IRQn=14 + SW_Handler,本口 SWIE 路线待上板确认,备选即改 IRQ 14"。
  2. src/chip/ch583/mod.rs 模块文档仍写"无 A 扩展 = 换 riscv32imc target"→ 已改为"须先做关中断/自旋锁原子垫片"(实测该 target 无 target_has_atomic)。
  3. 硬化:irq()/disable_irq() 对 CTLR 的读改写显式掩掉 INIT(bit5)——它是否自清无一手证据;若为电平位,每次 yield 会重装 64 位计数器、tick 账漂移。反汇编已核(andi -0x21 / and 0x7FFFFFDF)。

审查独立复现并确认(未被推翻):官方常量与 flash 0x14 布局、产物级启动头、三条守卫阳性对照、bash ci/gate.sh 全绿(host 159 / ch583 启动头 / 乒乓 A×200 B×200 / kernel 24-24×3 / smp 9-9)、13 口矩阵、宿主默认 82 passed。

审查提出的开放项(进上板清单,不在本 PR 内改设计):本口沿用 ch32v103 模板的 STK_CTLR.SWIE 软中断,而官方 CH583 三套 RTOS 移植都走 QingKe 专用 SWI_IRQn=14,SWIE 在官方 SDK 里只定义、零使用。上板若发现 SWIE 无效,改走 IRQ 14 即可(_int_dispatch 已按中断号分发,改动量小)。另:24K 堆余量按不同量法为 2.4–3.6K(审查方量到已用 22.1K),够启动但偏薄,上板若 OOM 优先再减示例任务。

遗留

  • 真机未验证:0x0 是否可写 / 是否存在 0x08000000 别名;复位默认主频(官方 FREQ_SYS=60MHz 是配置值,本口未做 SAM 解锁/PLL 初始化,SYSTICK_CLOCK_HZ=60M 待实测校正);0x804=0 后是否确实不再硬件压栈(36 字帧前提);CTLR.SWIE 置位后是否真进 SysTick 入口、SR.CNTIF 是否仍为 0;BootLoader 是否放行(启动头已复刻,仍需实板确认)。
  • .highcode(RAM 执行段)本版未启用:代码全留 FLASH(riscv-rt 的 link.x 不做 LMA→VMA 搬运)。
  • delay_us 仍用 mcycle:CH57x 是否实现 mcycle/Zicntr 待上板;未实现则读出恒 0 → 死循环,须改 SysTick/TMR 计时(CH57x 无 DWT)。
  • CH572 口未做(SWIE 在 SR、SysTick 32 位、PFIC 无 CFGR,需另一组差异常量)。
  • riscv32imc 退路不成立:实测该 target 只有 target_has_atomic_load_store、没有 target_has_atomic,内核里 fetch_add/swap 这类 RMW 编不过——无 A 扩展(CH572/青稞无 A 的档位)需要关中断/自旋锁原子垫片,不是换个 target 的事。

src/port.rs 的芯片选择是「每口一条 pub use ...::XxxPorting as Porting」+
「兜底 DefaultPorting 的 not(any(...)) 名单」两处成对维护;上一提交新增
ch583 特征时两处都漏了,导致开 ch583 特征时 Porting 落到 DefaultPorting
(方法全是 unimplemented!())——内核 xtask::start() 走 Porting::start_scheduler,
即 CH583 例程能编过(port.S 的 global_asm 与 #[no_mangle] 符号仍在,构建门禁
是绿的)但实际未接上本口。

- 补 #[cfg(all(feature = "ch583", not(test)))] pub use Ch583Porting as Porting;
- 兜底 DefaultPorting 的 any() 名单补 feature = "ch583"

取证(构建产物反汇编):修前 mscratch 在整份 disasm 里只出现一次
(_start_trap 的 csrr 读),restore_ctx.S 的 csrw mscratch 写缺失、且无
Ch583Porting 符号;修后 _...ch583..Ch583Porting..Portable..start_scheduler
出现,csrw mscratch 出现。本次改动仅补 cfg 接线,不动 ch583 口本身。
为什么改:正选别名与兜底桩名单原本两份手写,新增芯片只改一份时 Porting 静默落到 DefaultPorting(unimplemented!),构建与门禁全绿、运行期 xtask::start() 才 panic(ch583 骨架 PR 实测踩过,见 issue #14/PR #15)。

改法:chip_portings! 清单一次登记同时生成 正选别名/兜底 not(any(...))/RealPorting 标记实现+编译期断言;build.rs 再按 src/chip/<名字> 目录 ⇄ 启用 feature ⇄ 登记表 三方交叉,把漏登记变成构建期失败。

验证:删掉 ch583 登记行 → build.rs 报红(阳性对照);13 个移植口 --lib 全绿(riscv32imac 8 口/thumbv7em 2 口/thumbv7m/thumbv6m/armv7r)。
为什么改(按官方 openwch/ch583 EVT 源码核对,替换此前的推断):
1) ROM 启动头缺失:官方 Startup/startup_CH583.S 的 .vector 段第 5 字固定 0xF3F9BDA9(注释 boot option, can't modify),官方 Ld/Link.ld 把 .vector 紧跟在 .init 的 j handle_reset 之后 → 魔数落在 flash 0x14。此前本口 flash 0x14 是 riscv-rt 的启动代码,出厂(BootLoader 默认开)芯片不会进用户程序。现加 .bootvec 段复刻同一布局:0x00 入口跳转 + 向量表前 5 字,memory.x 用 SECTIONS 摆位并把 _stext 顶到 0x18,链接期 ASSERT 钉住 0x0/0x14。
2) SysTick CTLR:官方 RVMSIS/core_riscv.h 的 SysTick_Config() 写 INIT|STRE|STCLK|STIE|STE = 0x2F,不带 SWIE。原 0x8000_002F 的 SWIE 会让第一个任务 mret 后立刻多进一次 trap,且该 trap 早于 restore_ctx.S 写 mscratch(隐含依赖 MIE=0);去掉即无此依赖。
3) csrw 0xbc0,0x1f 与官方 reset 序列逐字一致(已按源码核对),保留并把注释换成出处引用。

验证:构建过;产物级检查 ci/check_ch583_boot.py PASS(入口跳转 + boot option@0x14);阳性对照——魔数改 0xF3F9BDAA → 脚本报红;.bootvec 挪到 0x4 → 链接期 ASSERT 报红。
本示例(ch583,+timer)要起 15 个默认任务(256 字栈 ≈1.03K/个)+ 软件定时器任务(1024 字 ≈4.1K),加 Task 结构与同步对象 ≈21.5K,全部走堆;原 16K 必 OOM。32K SRAM 里 _sheap(0x20001188) 到 _stack_start(0x20008000) 有 ~27.6K,取 24K 后堆顶 0x20007188,与中断栈(_stack_start-512)仍留 1.6K 余量。
ch583(QingKe V4A)没有 QEMU 机器可执行,门禁补两件事:①cargo build --example multitask_ch583 --features ch583,timer;②新增 ci/check_ch583_boot.py 读 ELF 校验 .bootvec 回到 flash 0x0..0x17、入口是 4 字节跳转、boot option 0xF3F9BDA9 落在 0x14。缺了它,ROM 不引导而构建/门禁全绿(假绿)。
README 芯片清单补 CH58x: ch583(构建级验证 2026-09-19,真机待验,注明启动头已复刻);docs/README.md 补 ch583 的官方 EVT 素材来源(Startup/Ld/RVMSIS/StdPeriphDriver),把审查提的'寄存器常量依据不可复核'落成可追溯链接;CLAUDE.md 的 chip feature 清单补 ch583;README 默认 features 计数按今日实测 82 修正(旧记 80)。
@gqf2008

gqf2008 commented Sep 19, 2026

Copy link
Copy Markdown
Owner Author

审查整改(2026-09-19):5 个提交,已按官方 openwch/ch583 EVT 源码核对

先把审查依据补上:issue 里引用的 pdfwork/* 素材不在仓库/工作区,寄存器常量无法复核。本次把官方 SDK 拉下来逐条核对,顺带修正审查里的一处说法:

事实 官方出处 结论
boot option 0xF3F9BDA9 EVT/EXAM/SRC/Startup/startup_CH583.S 的 .vector 段第 5 字(注释 boot option, can't modify) 确认;且官方 Ld/Link.ld 把 .vector 的 flash LMA 摆在 .init 的 j handle_reset 之后(0x04) → 魔数落在 flash 0x14,不是 0x10(审查时按 issue 表述写的 0x10 有误,以官方 Link.ld 为准)
csrw 0xbc0, 0x1f 同上 reset 序列 确认 CH583 必须写,原 PR 保留 ✓(只把注释换成出处引用)
SysTick 初值 EVT/EXAM/SRC/RVMSIS/core_riscv.h SysTick_Config():CMP=ticks-1、CTLR = INIT|STRE|STCLK|STIE|STE = 0x2F 原 PR 多写了 SWIE(bit31)→ 已改 0x2F
0x804 官方写 0x3(开 HWSTKEN+嵌套,配 HPE 序言) 本口刻意写 0(纯软件全保存,36 字帧前提),注释已写明差异

提交

  1. fix(port): 芯片接线收成单一来源清单(chip_portings! 一次生成 正选别名/兜底 not(any(...))/RealPorting 标记+编译期断言),build.rs 再按 src/chip/<名字> ⇄ 启用 feature ⇄ 登记表 三方交叉 —— 漏登记从"构建绿、运行期 unimplemented!()"变成构建期失败。
  2. fix(chip): 新增 .bootvec(flash 0x00..0x17:入口跳转 + 向量表前 5 字,boot option @0x14),memory.x 用 SECTIONS 摆位 + _stext=0x18 + 链接期 ASSERT;SysTick CTLR 改 0x2F(去掉 SWIE,顺带消掉"首个 mret 后多一次 trap 且早于 mscratch 初始化"的隐含依赖)。
  3. fix(chip): 示例堆 16K→24K(15 个默认任务 ≈15.4K + 软件定时器任务 4.1K + Task/同步对象 ≈21.5K,原值上板必 OOM,会被误判成寄存器问题)。
  4. ci(chip): 门禁加 ch583 构建 + ci/check_ch583_boot.py 产物级校验。
  5. docs: README 芯片清单/docs 材料表/CLAUDE.md 登记 ch583;README 默认计数 80→82(实测)。

验证

本地全门禁(bash ci/gate.sh)全绿——这是 QEMU 能覆盖的部分:

== [1/3] 内核 host 回归: test result: ok. 159 passed; 0 failed
== [2/3] 示例链接: PASS: 向量表第 56 项 -> USART0 @0x08002A52
                   PASS: 启动头 @0x0..0x18 — 入口跳转 + boot option 0xF3F9BDA9 @0x14   ← 本次新增
== [3/3] QEMU 执行门禁: qemu_pingpong: PASS(A×200 B×200)
                        qemu_kernel_tests: 24/24 passed
                        qemu_kernel_tests -smp 2: 24/24 passed
                        qemu_kernel_tests(tlsf 全局后端): 24/24 passed
                        qemu_smp -smp 2: 9/9 passed
== 全部通过 ==

阳性对照(新守卫不是摆设):①删 port.rs 的 "ch583" => 登记行 → build.rs 报红;②魔数改 0xF3F9BDAA → check_ch583_boot.py 报红;③.bootvec 挪到 0x4 → 链接期 ASSERT 报红。三项验证后已复原。

移植口回归:13 个口 cargo build --lib 全绿(riscv32imac 8 口 / thumbv7em 2 口 / thumbv7m / thumbv6m / armv7r);宿主默认 features cargo test --lib = 82 passed。

⚠️ QEMU 边界:QEMU 没有 QingKe/PFIC 对应的机器,ch583 本口无法仿真执行。QEMU 侧验证的是"内核执行级不回归"(qemu_riscv 口 24/24×3 + 乒乓 200 轮 + SMP 9/9);ch583 侧只能到构建级 + 产物级(启动头字节、符号、反汇编)。真机项仍待验:0x0 可写性/别名、mcycle 是否实现(决定 delay_us)、SWIE 置位后是否真进 SysTick、TICKS/时钟默认频率(SAM 解锁与 PLL 未做,官方默认 FREQ_SYS=60MHz 但复位默认频率待实测)。

未处理(留给后续):CH572 口(32 位 SysTick、SWIE 在 SR、PFIC 无 CFGR);riscv32imc 无 A 扩展路线——实测该 target 只有 target_has_atomic_load_store、没有 target_has_atomic,内核里 fetch_add/swap 这类 RMW 编不过,需要关中断/自旋锁垫片,建议在 #14 里单列验收项。

README 验证体系补一条'产物级':ci/gate.sh 除 host 回归与 QEMU 执行级外,还校验 ch583 的 ROM 启动头(flash 0x00..0x17,向量表第 5 字 boot option 0xF3F9BDA9 @0x14),并说明该口没有 QEMU 机器可跑;一键复现的命令注释同步。
复审实测(QEMU 探针:同一 32 位分配器 / 同一 Task 布局;WCH 侧无法仿真,只能这样取数):
  15 个示例任务                                  = 17768 B
  + 软件定时器任务(1024 字) + idle(512 字) + 计表任务 ≈ 24900 B(计表任务占 1.2K)
即原 15 任务组合启动就需 ~24.4K 堆;24K 会在 start() 里 panic(memory out)(已实测复现),
而 32K SRAM 里 _sheap 到 _stack_start 只有 28.3K,给不出 26K+ 堆。
故把示例任务 15 → 12(仅 example_task 的 5 个纯打印任务留 2 个;semaphore/queue 各 5 个不动,
同优先级时间片与 IPC 语义不变):12 任务 + timer + idle ≈ 20.9K,24K 堆余量 ≈3.6K,
堆顶 0x20007188 距中断栈基 0x20007E00 仍有 3.2K。注释写清实测数与不要再加任务的告警。
复审发现两处:
1) 用 assert 做文件类型判断,-O 下会被关掉(校验不能依赖 assert);改为显式判断并补
   ELF32/小端检查——否则指向 64 位 ELF 会以解析异常结束,而不是给出清晰 FAIL。
2) 只认 4 字节 JAL,而 2 字节 c.j 同样合法;真正钉死布局的是 .bootvec 段地址/长度与
   魔数偏移,故放宽为 JAL/c.j 都接受,避免误报。
两项均实测:合成 ELF64 → 期望 32 位小端 ELF 报红;整改前 ch583 ELF → 没有 .bootvec 段报红。
@gqf2008

gqf2008 commented Sep 19, 2026

Copy link
Copy Markdown
Owner Author

复审 5 遍的结果(新增 2 个提交)

复审按 5 个角度各跑一遍:①依据核对(回官方 SDK) ②链接布局与产物 ③Rust 逻辑与 cfg ④守卫有效性与可达性 ⑤端到端回归。查出 2 个真问题,已修并留证(详见 PR 描述新增的「复审(5 遍)修正与证据」一节):

  1. 示例堆仍然不够 —— 我上一轮的 24K 修得不对:QEMU 探针实测 15 个示例任务 17,768B,加软件定时器任务 + idle 后 ≈24.4K,24K 堆会在 start() 里 panic("memory out")(实测复现);而 32K SRAM 给不出 26K+ 堆。→ 示例任务 15 收到 12(example_task 只留 2 个,semaphore/queue 不动),实测 12 任务 + timer + idle ≈20.9K,24K 堆余量 ≈3.6K。提交 fcb4275。
  2. 校验脚本两处健壮性(assert 在 -O 下失效;入口只认 4 字节 JAL)→ 提交 f7e0cfb。

顺带把最关键的"魔数在 flash 0x14"从推演升级成实测:用官方 Ld/Link.ld + 官方 .init/.vector 段内容链接,产物 0x14 处就是 0xF3F9BDA9。

验证:门禁全绿(host 159 / ch583 启动头 / 乒乓 A×200 B×200 / kernel_tests 24-24 ×3 / smp 9-9)、13 口矩阵全绿、4 项阳性对照全部按预期报红(验后复原)。唯一异常是首次门禁在 tlsf 变体偶发红一次(输出停在 suite starting),单独复跑与整门禁复跑均 24/24 绿,判为本机偶发。

独立审查(全新会话,只给任务书与一手资料)结论:需修改(2 处文档级)+ 1 条设计观察,逐条处理:

1) examples/multitask_ch583.rs 头部的上板核对清单第③条仍是旧值 CTLR=0x8000_002F,
   而 7385bf4 已把代码改成 0x2F —— 照它验会验到固件根本没写的值。改为 0x2F,并把
   第④项升级为"官方三套移植走 SWI_IRQn=14,本口 SWIE 路线待上板确认,备选改 IRQ 14"。
2) src/chip/ch583/mod.rs 模块文档仍写"无 A 扩展退路 = 换 riscv32imc target",与实测
   (该 target 无 target_has_atomic,内核 fetch_add/swap 编不过)自相矛盾。改为
   "需先做关中断/自旋锁原子垫片"。
3) 硬化:irq()/disable_irq() 对 CTLR 的读改写显式掩掉 INIT(bit5)。INIT 是否自清没有
   一手证据(官方 SysTick_Config 只在初始化写一次 CTLR、之后从不读改写);若它是电平位,
   回写会让每次 yield 重新装载 64 位计数器 → tick 账漂移。掩掉后两种情况都安全。
   反汇编核对:irq() = lw / or SWIE / andi -0x21 / sw;disable_irq() = lw / and 0x7FFFFFDF / sw。

审查同时复现(未被推翻、无需改代码):官方常量与 flash 0x14 布局、产物级启动头、
三条守卫的阳性对照、门禁全绿(host 159 / ch583 启动头 / 乒乓 / kernel 24-24×3 / smp 9-9)、
13 口矩阵、宿主默认 82 passed。
@gqf2008

gqf2008 commented Sep 19, 2026

Copy link
Copy Markdown
Owner Author

独立审查(第三轮)结果:需修改 → 已修 6c3e984

审查由全新会话执行(只拿到任务书 + 一手资料,不看作者推理),独立复核了官方 SDK 常量、flash 0x14 布局、产物级启动头、三条守卫的阳性对照、门禁与 13 口矩阵,并自己复测了堆账。结论:需修改(2 处文档级旧值),另有 1 条设计观察:

  1. 上板核对清单第③条是旧值:examples/multitask_ch583.rs 头部仍写 CTLR=0x8000_002F,而代码已是 0x2F —— 照它验会验到固件没写的值(这正是"改完代码忘了改清单"的典型)。已改正,并把第④项升级为 SWIE/SWI_IRQn 两条路的说明。
  2. 模块文档自相矛盾:src/chip/ch583/mod.rs 仍写"无 A 扩展退路 = 换 riscv32imc target",与实测(该 target 无 target_has_atomic)冲突。已改为"须先做关中断/自旋锁原子垫片"。
  3. 硬化:irq()/disable_irq() 的 CTLR 读改写掩掉 INIT(bit5),消除"INIT 若是电平位则每次 yield 重装计数器"的未知数。

开放项(留给上板):官方 CH583 的 FreeRTOS/RT-Thread/HarmonyOS 三套移植都不用 CTLR.SWIE(SDK 里只定义、零使用),一律走 SWI_IRQn=14 + SW_Handler;本口沿用 ch32v103 模板。上板若 SWIE 无效,改走 IRQ 14 即可。已同步进 issue #14 的核对清单。

@gqf2008
gqf2008 merged commit b146fea into master Sep 19, 2026
2 checks passed
gqf2008 added a commit that referenced this pull request Sep 19, 2026
为什么改:正选别名与兜底桩名单原本两份手写,新增芯片只改一份时 Porting 静默落到 DefaultPorting(unimplemented!),构建与门禁全绿、运行期 xtask::start() 才 panic(ch583 骨架 PR 实测踩过,见 issue #14/PR #15)。

改法:chip_portings! 清单一次登记同时生成 正选别名/兜底 not(any(...))/RealPorting 标记实现+编译期断言;build.rs 再按 src/chip/<名字> 目录 ⇄ 启用 feature ⇄ 登记表 三方交叉,把漏登记变成构建期失败。

验证:删掉 ch583 登记行 → build.rs 报红(阳性对照);13 个移植口 --lib 全绿(riscv32imac 8 口/thumbv7em 2 口/thumbv7m/thumbv6m/armv7r)。
@gqf2008
gqf2008 deleted the feat/ch57x branch September 19, 2026 04:28
@gqf2008

gqf2008 commented Sep 19, 2026

Copy link
Copy Markdown
Owner Author

合并记录(2026-09-19)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant