配置一块开发板
最后更新
开发板信任团队的 dev 密钥,所以它会安装团队里任何人构建的东西。零售机器人的配置方式不同,并且会刻意拒绝这些构建。
这一页的所有内容都假设你面对的是开发板,不是零售机器人。
安全性并没有放宽
这一点值得说清楚,因为容易误解:dev 构建走的是同样的签名与哈希校验、同样的健康门禁、同样的自动回滚。唯一的区别是由哪把密钥签名。
而这正是这些构建进不了零售机器人的原因——零售机器人从两个层面拒绝 dev 密钥:
allow_dev_keys = false;- 一把受信任的密钥只有在文件名以
.dev.pub结尾时才算 dev 密钥。
下面整个配置流程存在的意义,就是把这两项翻过来。
刷系统
用 Armbian imager,选 Radxa Zero 3,然后 Armbian 26.2.1 Minimal。
写入前先把 imager 的 profile 填好——wifi 名称和密码、你想要的用户名和密码。在这里填能省掉后面接串口控制台的麻烦:板子首次开机就会连上你的网络,可以直接 ssh。
然后把 ssh 公钥送上去,provisioning 重启板子后需要靠它重连:
ssh-copy-id radxa@192.168.1.42
开始前需要准备
- 板子的 IP 地址。 这个镜像上的 mDNS 不可靠,
.local名字能不能解析全看心情。duckctl ip通过蓝牙问机器人要地址,不需要你自己有网络,也不需要读 DHCP 租约;板子还没开始广播时,退回去查路由器的租约表。 - ssh 密钥访问(上一步)。provisioning 会重启板子并自行重连,密码提示是活不过重启的。
- 一个 GitHub token,在这个仓库还是私有的期间——它的 release 资产没有 token 拿不到。仓库公开后 token 变成可选,只用来提高 API 速率限制。
- 一份仓库克隆。 需要的 dev 公钥已经提交在
deploy/dev-key/team.dev.pub,不用向任何人索要。
安装
在自己机器上的克隆里,两条命令:
export DUCK_TOKEN=github_pat_replace_with_your_token
./scripts/provision-board.sh --pause-btd-on-pair --name <MY_COOL_ROBOT_NAME> radxa@192.168.1.42
它会送上你的 dev 密钥、启动 provisioning、等过重启、流式输出日志,最后停在 robotctl health。
日志输出只是个查看器,不是干活的那个东西。 provisioning 装了一个 systemd unit 在开机时续跑,所以不管你还在不在看,板子都会自己走完。Ctrl-C 不会有任何损失,之后随时接回日志:
ssh -t radxa@192.168.1.42 'sudo tail -f /var/lib/robot/provision.log'
为什么默认带 --pause-btd-on-pair
在 aic8800 无线芯片上,btd 正在广播时手柄无法建立新的绑定。这个参数留下一个标记,让 robotctl pad pair 在配对窗口内停掉 btd 并给适配器断电重启,之后再启动它。
已有的绑定不受影响——配好的手柄在整套服务运行时照样连接和驱动——所以代价只是一个守护进程在配对期间短暂下线。
它成为默认值的原因很实际:一块需要它却没带这个参数配置的板子,表现出来就是“手柄配不上”,而你第一时间去查的每一个可能原因都在别处。
三种蓝牙配置,以及怎么判断你是哪一种
这里有两个互相独立的故障,所以有两个参数。先配一次手柄,读它的失败方式,然后对照:
| 你看到的现象 | 这块板子需要 |
|---|---|
| 手柄能绑定、能驱动 | 什么都不需要——不带参数配置 |
| 手柄绑不上,最后一步 SMP 永远不完成 | --pause-btd-on-pair |
暂停 btd 也绑不上 |
--weird-ble(隐含暂停,并加上 Privacy = device) |
手柄能绑上,然后反复掉线——PIN or Key Missing (0x06),创建不出输入设备 |
--weird-ble 对这块板子是错的:去掉它,保留暂停 |
最后一行是要特别留意的那个。
在只需要暂停的板子上设 Privacy = device,会产生一个“绑上之后立刻不工作”的状态——这比一个干脆配不上的手柄更难诊断。官方在 50:37:CD:16:1D:90 这块板子上实测过:off 加暂停能绑定并保持稳定,而 device 在 45 秒内掉线 46 次。
因此 --weird-ble 已经不再是默认值。
在两种配置之间移动
从 --weird-ble 退回只用暂停(保留标记):
sudo sed -i 's/^Privacy = device/Privacy = off/' /etc/bluetooth/main.conf && sudo reboot
反方向,用 provisioning 在板子上留下的脚本副本:
sudo DUCK_WEIRD_BLE=1 /usr/local/sbin/robot-setup-board && sudo reboot
验证一块板子两个都不需要——去掉之后配一次手柄:
sudo rm /var/lib/robot/weird-ble
sudo sed -i '/^Privacy = /d' /etc/bluetooth/main.conf && sudo reboot
改完
Privacy必须重新配对。它会改变已存储密钥所派生的地址,所以已有的绑定不再匹配,会一直以PIN or Key Missing反复掉线,直到重新配对。
这一整套都是对 aic8800 无线芯片的绕行方案,不是设计本身的性质——换掉这个芯片它就消失了。详见配对手柄。
从分支配置
./scripts/provision-board.sh --ref BRANCH radxa@192.168.1.42
--ref BRANCH 用某个分支来配置:跑它的脚本做 bring-up,并在上面装它构建的守护进程。
这里有个设计取舍值得理解:golden 始终保持稳定发布版——它是开机恢复网的兜底,而用分支构建当 golden 等于给一个坏分支配一个坏兜底——current 才是分支。
配置会失败,如果那个构建装不上,或者装上后被健康门禁回滚了。这是刻意的:
一块被要求装分支、却安静地跑着稳定版的开发板,是最难排查的失败——看起来一切都装好了,而被测试的代码根本不在上面。
配置前给 CI 一两分钟。如果卡住,用 gh run list --branch BRANCH 查。
其它有用的参数
--name Ducky—— 给机器人命名,而不是留着它从序列号推出来的duck-7f3a。之后robotctl system set-name也能改,所以这只是省一条命令。--local—— 发送这份克隆里的provision.sh而不是去拉取。这是在不合并的前提下测试 provisioning 脚本改动的方法。--no-dev-key—— 做出一块只接受正式发布版的板子。
确认真的成功了
robotctl health
板子只有在密钥真的装上时才算开发板,而这是一件可以查证的事,不用靠记忆:
grep -c 'DEV BOARD' /var/lib/robot/provision.log
1 表示是。0 表示密钥没落地——之后 --ref 会被拒绝,而报错信息读起来像是发布版损坏。这个检查存在的意义就是提前抓住这个失败。
下一步
- 本机构建,一分钟装上板子
- 开发板速查——包括更新之后的重启陷阱