Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

构建与运行示例集

QEMU 是不用硬件就能跑 WS63 固件的“软件在环“环境。作为生态贡献者,你会反复 构建并运行 examples/ws63/* 里的示例来验证改动。本课带你跑通示例目录里的几个 代表:blinky(GPIO trace)、uart_hello(banner)、timer_irq / gpio_irq(中断串口输出)、 semihost_selftest(半主机退出码)。每一步都有可见结果。

QEMU 模型的原理见 QEMU 模型

示例都是根工作区的成员,所以一律从仓库根目录用 -p <name> 构建,再用同一条 命令模板运行:

cargo build -p <name> --release
qemu-system-riscv32 -M ws63 -nographic -bios none \
    -kernel target/riscv32imfc-unknown-none-elf/release/<name>
  • -M ws63:WS63 机器模型。
  • -nographic:无图形界面,把 UART0 接到当前终端。
  • -bios none:不加载额外固件,直接跑我们的 -kernel
  • -kernel <elf>:要运行的示例 ELF。

退出 QEMU 始终是:按 Ctrl-A,再按 X

第 1 步:blinky(GPIO 翻转,无串口)

cargo build -p blinky --release
qemu-system-riscv32 -M ws63 -nographic -bios none \
    -kernel target/riscv32imfc-unknown-none-elf/release/blinky

blinky 把 GPIO0 配成推挽输出,死循环里拉高、延时、拉低、延时。它没有串口输出, 所以控制台不会打印东西——这是预期的:程序在安静地翻转引脚(机器 trace 里能看到 GPIO0 每 500 ms 变一次)。想“看见“可观测行为,用下面带串口的示例。

关于构建目标和产物路径的细节,见 构建一个示例

第 2 步:uart_hello(串口 banner)

cargo build -p uart_hello --release
qemu-system-riscv32 -M ws63 -nographic -bios none \
    -kernel target/riscv32imfc-unknown-none-elf/release/uart_hello

uart_hello 为 QEMU 设计:它故意不初始化时钟,只碰 UART0 寄存器(0x4401_0000)。 控制台上你应当立刻看到 banner,随后是不断递增的 tick 计数:

Hello from WS63 on QEMU!
ws63-qemu: UART0 @ 0x44010000 is alive.
tick 0
tick 1
tick 2
...

真机上的串口 banner 仍在打磨(需要先初始化时钟),本课只承诺 QEMU。第 3 课的 blinky 才是当前确认可观测的真机行为。

第 3 步:timer_irq(定时器中断)

cargo build -p timer_irq --release
qemu-system-riscv32 -M ws63 -nographic -bios none \
    -kernel target/riscv32imfc-unknown-none-elf/release/timer_irq

TIMER_0 周期性触发 IRQ 26,处理函数每次累加计数并打印。你应当看到:

WS63 timer-IRQ test (TIMER_0 -> IRQ 26)
timer irq #0
timer irq #1
timer irq #2
...
OK: timer interrupts delivered

看到 timer irq # 不断递增、最后出现 OK: timer interrupts delivered, 说明 QEMU 的中断投递闭环正常。

第 4 步:gpio_irq(GPIO 中断)

cargo build -p gpio_irq --release
qemu-system-riscv32 -M ws63 -nographic -bios none \
    -kernel target/riscv32imfc-unknown-none-elf/release/gpio_irq

这个示例把 GPIO0 的边沿映射到一个自定义本地 IRQ(≥32)。你应当看到:

WS63 GPIO-IRQ test (GPIO0 pin0 -> IRQ 33, custom local)
gpio irq #0
gpio irq #1
...
OK: custom local IRQ (>=32) delivered

第 5 步:semihost_selftest(半主机退出码)

有些示例不靠串口打印,而是通过 RISC-V 半主机把结果报告给宿主—— semihost_selftest 跑完后会用半主机的“退出“操作返回退出码:PASS 返回 0,FAIL 返回 1, panic 返回 2。这个退出码会变成 QEMU 进程自己的退出码,非常适合写进自动化脚本。

要让半主机生效,必须加上 -semihosting

cargo build -p semihost_selftest --release
qemu-system-riscv32 -M ws63 -nographic -bios none -semihosting \
    -kernel target/riscv32imfc-unknown-none-elf/release/semihost_selftest

控制台会打印(通过半主机控制台):

semihost_selftest: PASS

随后 QEMU 自行退出。检查它的退出码:

echo $?

你应当看到:

0

0 就代表自检通过——脚本可以直接据此判定成败,无需解析串口文本。

各示例的预期标记串汇总见 示例目录与验证标记串; 半主机相关的环境变量见 HIL 标记串与环境变量

你现在已经能从仓库根目录构建并在 QEMU 里跑示例、读中断输出、用退出码做自检了。 下一课我们走出模拟器,做第一次真机测试 —— 第一次硬件在环测试