Skip to content

fix(uboot): stabilize serial transfers#145

Merged
ZR233 merged 2 commits into
mainfrom
codex/fix-rk3568-serial-stability
Jun 25, 2026
Merged

fix(uboot): stabilize serial transfers#145
ZR233 merged 2 commits into
mainfrom
codex/fix-rk3568-serial-stability

Conversation

@ZR233

@ZR233 ZR233 commented Jun 25, 2026

Copy link
Copy Markdown
Member

问题

近期 ROC-RK3568-PC 的 dev 板测在进入内核前不稳定,日志里主要表现为:

  • U-Boot 命令阶段偶发超时或串口字节污染。
  • loady/YMODEM 传输偶发 NAK,当前重试预算会被前面包消耗,后续包容错下降。
  • ostool-server 在自动 power-on 尚未完成时就可能把客户端输入写进串口,早发的 Ctrl-C/命令容易落在 ROM/SPL/U-Boot 过渡期。
  • 新会话打开串口后可能读到上一轮残留内容。

修改

  • ostool-server 打开串口后先清理 input buffer,避免新会话继承旧串口残留。
  • 在自动 power-on 完成前,server 暂缓处理客户端写入,只继续转发串口输出和监听 session shutdown;power-on 成功后再开始把客户端输入写入串口。
  • 将 session TTL 从 2s 提高到 10s,给长串口输出和 loady 传输保留更稳定的续租余量。
  • uboot-shell::loady 每次 attempt 前先 drain 当前串口输入,再执行 loady
  • loady 增加整次传输重试:一次 YMODEM 传输失败后用 Ctrl-C 恢复 U-Boot shell,重新打开文件并重新执行 loady
  • YMODEM 的 retry 改为按包计数,包 ACK 成功后重新获得 retry 预算,避免前一个包的偶发 NAK 降低后续包容错。
  • 增加协议/字节流测试覆盖:包级 retry 重置、loady 整次失败后恢复并重传、server power-on 前暂缓客户端串口写入。

验证

  • cargo fmt --all
  • cargo test -p uboot-shell
  • cargo clippy -p uboot-shell --all-targets -- -D warnings
  • cargo test -p ostool-server
  • cargo clippy -p ostool-server --all-targets -- -D warnings
  • cargo test -p ostool
  • cargo clippy -p ostool --all-targets -- -D warnings
  • ROC-RK3568-PC 实机传内核测试通过:
    • 本地临时使用 patched ostool/uboot-shell 客户端。
    • 远端 ostool-server 保持原 systemd active,未重启服务。
    • 命令:RUST_LOG=info,ostool=debug,uboot_shell=debug cargo xtask axvisor test board --board roc-rk3568-pc-linux --server 10.3.10.194 --port 2999
    • loady 完成 FIT image 传输,U-Boot 输出 2(SOH)/2423(STX)/0(CAN) packets, 1 retries,随后 bootm 启动 Linux guest,最终匹配 login:,测试输出 ok: smoke/roc-rk3568-pc-linux / all axvisor board test groups passed

备注

  • 实机验证后确认远端 ostool-server.service 仍为 active,session 为空,ROC-RK3568-PC 可用。

mai-team-app[bot]
mai-team-app Bot previously requested changes Jun 25, 2026

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

代码审查总结

整体改动方向正确,针对性地解决了 ROC-RK3568-PC 串口传输不稳定的一系列问题。以下是详细审查意见。

✅ 优点

  1. 串口打开后清空输入缓冲 (clear_serial_input_after_open):引入 SerialOpenCleanup trait 提高了可测试性,且清空失败仅 warn 不中断 session,设计合理。
  2. power-on 期间暂缓客户端写入:在 run_serial_ws_inner 中将 ws_receiver.next()power_on_task.is_some() 的 select 分支移除,使客户端消息在 power-on 期间自然缓冲在 websocket 流中,完成后自动消费。逻辑正确。
  3. Session TTL 从 2s 提升到 10s:对于 loady 长传输场景合理,session heartbeat 机制保证活跃 session 不会过早过期。
  4. YMODEM 重试预算按包重置:将 self.retries 改为局部变量 retries,ACK 成功后自动重置,避免前一个包的 NAK 消耗后续包的容错能力。修复正确。
  5. loady 整次传输重试:失败后发送 Ctrl-C 恢复 U-Boot shell、重新 clear_shell、再执行 loady,设计清晰。最多 3 次尝试,LOADY_RETRY_DELAY 300ms 合理。
  6. 测试覆盖良好:新增 ymodem 单元测试、loady 模拟测试、server 集成测试,测试场景全面。

❌ 需要修复

Clippy 错误 (-D warnings 下编译失败):

uboot-shell/src/lib.rs 第 488、492 行:

self.queue_read([b'C']);  // clippy: byte-char-slices

应改为:

self.queue_read(*b"C");

运行 cargo clippy -p uboot-shell --all-targets -- -D warnings 可复现。

💡 建议(非阻塞)

  1. loady 最终失败时的错误消息中 last_err.map(...).unwrap_or_else(|| "unknown error".to_string()) 理论上 last_err 不可能为 None(循环至少执行一次且失败路径一定设置 last_err),可考虑直接 .unwrap() 或使用更明确的类型保证。
  2. 集成测试 websocket_buffers_client_serial_input_until_power_on_finishes 使用 shell 脚本作 power-on 门控,设计巧妙,但仅限 unix 平台(已有 #![cfg(unix)] 保护)。

Powered by mimo-v2.5-pro

@ZR233 ZR233 merged commit 5052d8d into main Jun 25, 2026
2 checks passed
This was referenced Jun 25, 2026
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