Skip to main content

remote-serial / boardctl

开发板控制工具(设计参考 ostool):每块开发板一个 TOML 配置,模块化 + 插件化架构——加传输方式/执行方式只需在插件目录丢一个文件, 改某块功能只需动对应模块。

当前接入的板卡:Sipeed LicheeRv Nano(Sophgo SG2002 / CV181x,RISC-V 玄铁 C906, U-Boot 2021.10,提示符 soph#),串口经 TCP 桥(gem12)透传,电源为小米智能插座。

快速上手

./boardctl.sh -b sg2002 run              # 列出该板的一键启动目标
./boardctl.sh -b sg2002 run hello        # 全流程:冷启动→传输→执行→断言→断电
./boardctl.sh -b sg2002 run hello -r 10  # 10 轮压测,汇总 N/10 PASS
./boardctl.sh boards                     # 列出已配置开发板
# 等价:./.venv/bin/python -m boardctl ...(任意目录可用 boardctl.sh)

架构(松耦合,单向依赖)

boardctl/
├── cli.py        命令行接线(argparse + 分发,无业务逻辑)
├── config.py     板卡 TOML 加载(不依赖其他模块)
├── session.py    U-Boot 串口会话 ← config
├── power.py      电源/冷启动   ← config, session
├── shell.py      命令执行(本机/ssh)← config
├── runner.py     run 编排       ← 上述全部 + plugins
└── plugins/      插件(目录约定自动发现,零注册代码)
    ├── transport/   传输插件:loady.py、tftp.py
    ├── executors/   执行插件:go.py、source.py、none.py、booti.py、bootm.py
    └── power/       电源插件:mijia.py(原生小米云)、command.py(命令,默认)

插件接口(接口约定写在各 __init__.py 里;插件可选声明 CFG_SECTION + DEFAULTS 自带配置默认值,TOML 优先):

  • 传输插件(plugins/transport/xxx.py):NAME + send(cfg, path, addr) -> bool
  • 执行插件(plugins/executors/xxx.py):NAME + build_cmd(addr) -> str | None
  • 电源插件(plugins/power/xxx.py):NAME + set_power(cfg, on) + get_power(cfg) -> bool | None

新建插件 = 加一个文件,--method/[run].exec 立即可用,核心代码零改动。

板卡配置(boards/*.toml)

搜索顺序(先找到的优先):$BOARDCTL_BOARDS → 当前目录 ./boards~/.config/boardctl/boards/(推荐:用户自己的板放这里) → 包内置示例。

说明
顶层 ssh_host 命令模式命令的执行位置:空 = 本机;填 ssh 别名(如 gem12)= 经 ssh 在远端主机执行,别名/端口/用户走 ~/.ssh/config
[serial] url / timeout 串口桥 URL(本板为 socket://... 裸 TCP)
[uboot] prompt / load_addr 提示符、默认加载地址
server_ip / ensure_server_ip TFTP 服务器地址;该 U-Boot 无 saveenv,连接时自动恢复
[power] method = "mijia" + [power.mijia] dev_name/did 方式一·电源插件:进程内原生调用小米云(凭证复用 ~/.config/mijia-api/auth.json,首次需 mijiaAPI login 扫码),不走 ssh_host
method = "command" + on_cmd/off_cmd/status_cmd 方式二·命令插件:任意开关机 shell 命令(经 ssh_host 决定本机/远端);method 未配置时默认即此。改 method 一行切换
[tftp] method=remote + ssh_host/remote_dir scp 到远端 tftpd(gem12 的 tftpd-hpa)
method=local + local_dir 本机临时拉起 tftp_server.py(UDP 69 需特权,退出自动回收)
[loady] sender Ymodem 发送器(Arch 为 lrzsz-sb)
[run.<名字>] file / exec / method / timeout 一键启动目标(exec/method 即插件名;run --repeat N 多轮压测,每轮冷启动并汇总)
addr / entry 加载地址 / 跳转执行地址(go 0x... 的目标);缺省都取 uboot.load_addr,加载与入口不同时分别指定
fdt / initrd booti 执行插件附加键:设备树地址(必需)/ initrd 地址(可选)
reset_before 开头冷启动:关→开→等提示符(从任意脏状态恢复)
after = off/reset/none 收尾动作
expect = [..] 输出断言(子串,全命中才 PASS);expect_re 正则版;fail_re 正则禁止命中(如 panic);退出码 0/1

端到端验收

./.venv/bin/python e2e/verify_e2e.py     # reset→tftp 部署→原始流逐字节断言,两套测试

裸机测试:e2e/baremetal/(riscv64-linux-gnu-gcc,注意 DW APB UART reg-shift=2、 -fno-pie--build-id=none)。脚本测试:e2e/script/(source 需 mkimage 的 legacy uImage 头)。构建细节与踩坑记录见 e2e/README.md

依赖

Python 3.11+(stdlib tomllib)+ pyserial。开发安装:uv venv && uv pip install -e '.[mijia]' (依赖唯一事实来源是 pyproject.toml)。交叉构建另需 riscv64-linux-gnu-gccmkimage(uboot-tools)、lrzsz

安装与发布

# 从 PyPI 安装(发布后)
pip install boardctl            # 核心:run 全流程(loady/tftp 传输)
pip install 'boardctl[mijia]'   # + 小米云电源插件

# 板卡配置搜索顺序:$BOARDCTL_BOARDS → ./boards → ~/.config/boardctl/boards → 包内置示例
# 用户自己的板卡放 ~/.config/boardctl/boards/(优先级高于包内置示例),不碰安装目录

# 发布(项目根目录)
uv build                        # 产出 dist/*.whl + *.tar.gz
uv publish --token <PyPI_API_Token>   # 建议先发 TestPyPI 演练

可选发布路径:GitHub 仓库 + Actions trusted publishing(打 tag 自动发布,免 token), 或直接 pip install git+https://...(零发布设施,适合私有/内网)。

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

boardctl-0.3.0.tar.gz (27.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

boardctl-0.3.0-py3-none-any.whl (27.4 kB view details)

Uploaded Python 3

File details

Details for the file boardctl-0.3.0.tar.gz.

File metadata

  • Download URL: boardctl-0.3.0.tar.gz
  • Upload date:
  • Size: 27.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for boardctl-0.3.0.tar.gz
Algorithm Hash digest
SHA256 7f959beac17212c6971c698818d54003d8f40f6aa999ed1c2cf8db9f9aeab709
MD5 74bd20a405244266506c22d097fc9123
BLAKE2b-256 be456bfa3fb3e0c2fceaf837f3785fa3cee2ee16e41b2762c7fc284a81e67857

See more details on using hashes here.

Provenance

The following attestation bundles were made for boardctl-0.3.0.tar.gz:

Publisher: publish.yml on yfblock/boardctl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file boardctl-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: boardctl-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 27.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for boardctl-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 21482e0a6375804ef14f3b5edd167de43b3a90ee02cac5bebfed826594e0a327
MD5 25796698912081e694fb2af2c4ba580d
BLAKE2b-256 99bb7c920ed5b0fcb42f03a11c0d02cde95cea07d1cb1f9fe03fc30c77e82e6a

See more details on using hashes here.

Provenance

The following attestation bundles were made for boardctl-0.3.0-py3-none-any.whl:

Publisher: publish.yml on yfblock/boardctl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.6.0

2 files

0.5.0

2 files

0.4.4

2 files

0.4.3

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.1

2 files

This release

0.3.0 This release

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page