Skip to content

远程开发体系 ​

板子和线留在公司,人带着 Mac 回家。再改一版固件时,不必搬走整套设备:编译交给编译服务器,USB 和串口仍由接板子的调试前端机接管。手机也能入网查看,但烧录命令始终在接板子的主机上执行。

下面是我实际使用的分工。地址、端口和版本是这套环境的记录,不是通用默认值;这些服务走 WireGuard 内网,不应照抄成公网入口。

人换地点,板子不动 ​

每个节点只和云端互加 peer,跨节点流量由云端 ip_forward 中转。新增设备只改自己和云端,不必逐台修改其它机器。

要做什么走哪条路入口
shell、推拉文件本机 adb client → 调试前端机的 adb serveradb -H 10.8.0.6 shell
看 MCU 日志、操作控制台ser2net raw TCPsocket://10.8.0.6:400x
烧录镜像传产物,再 SSH 到调试前端机执行rsync + ssh
访问板端网页在调试前端机上做 adb forwardhttp://<前端 IP>:18080

ADB 用的是官方 client/server 分离,板端 adbd 不用改。远端本地 adb shell 与这里的 adb -H 共用同一个 server;可以并行读日志,但不能一边推文件一边重启板子。两端版本要接近,原记录均为 28.0.2。

一次远程烧录,命令在哪里跑? ​

先确认自己连的是哪台机器。编译服务器 vms 和调试前端机 vmt 的 hostname 都叫 olicca-vm,只看终端提示符会认错;这里以 WireGuard IP 和机器清单为准。调试前端机的地址是 10.8.0.6,下文称前端 IP。

bash
ping -c 2 10.8.0.6
ssh olicca@10.8.0.6 'echo OK'
adb -H 10.8.0.6 devices

连接正常后,本机编译、传文件;资源主机取锁、烧录。原记录链路 RTT 约 130ms,因此没有采用把刷机 USB 映射回本机的路线;这也不是一次 usbip 性能测试。

刷写命令随平台变化,不能拿同一条命令套两块板。板子锁也是本环境自建工具,并非系统自带:board-lock <board-id> <owner> <task> 失败时会返回占用者,应先用 board-status 查清,不要直接抢锁。操作结束再 board-unlock <board-id>。

锁目录 /tmp/boards/*.lock/ 保存 owner、任务和时间戳,主机重启后清空。它协调的是大家遵守的操作顺序,不能代替对正在运行的刷写进程的确认。

串口为什么不用 RFC2217? ​

ser2net 4.3.4 曾在异常断连后接受 TCP 却不再发送协商字节。改成 raw TCP 后,15 次快速连断保持稳定。代价是不能从客户端改波特率;本环境各口固定速率,正好用不上。这个结论只针对当时版本和测试。

端口串口用途波特率
4000S100P MCU-COM921600
4001S100P Main-COM921600
4002RV1126B AP(Linux)1500000
4003RV1126B MCU(RT-Thread)1500000
python
import serial
s = serial.serial_for_url("socket://10.8.0.6:4002", timeout=2)

昨天还通,今天该先查哪里? ​

不要从“重启所有服务”开始。网络通、服务 active、USB 已枚举,是三件不同的事。按下面顺序查,能少打断别人的任务。

看到的现象先检查这次记录里的原因或处理
ping 不通本机 WireGuard 与云端握手先恢复网络,不动板子
能 ping,SSH 失败地址、密钥、远程登录服务修 SSH 免密配置
adb 列表为空调试前端机侧板子供电、USB 直通请现场检查,不盲目重启 adb
CH340 插着却无 /dev/ttyUSB0内核日志是否提到 brltty开发机移除抢占服务后重插
ser2net active,但端口没监听启动时串口是否已枚举USB 晚于服务启动;重启恢复,后加 udev 规则
adb-server 卡在 activating5037 端口占用旧 adb -a nodaemon 未退出;确认后清理旧进程
更新 adb 后远程连接坏了两端版本对齐版本后重新连接
Mac adb -H ... forward 报 more than one是否为记录中的 adb 1.0.41 情况当时 -s 无效,改在 vmt 本地执行 forward
附录:入网、直连和会话同步

给新设备留一个固定身份 ​

machines.tsv 保存 id、IP、角色,权威副本在云端 /srv/mesh/;自建 mesh-whoami 按本机 WireGuard IP 匹配身份。记录中的云端为 .1、编译服务器为 .4、调试前端机为 .6、Mac 为 .10、手机为 .100,均在 10.8.0.0/24。编译服务器的宿主机为 .2,平时不在线。

2026 年 9 月接入 iPhone 时,先生成密钥和客户端配置,再在云端 wg0.conf 加公钥 peer,用 wg syncconf 热加载;手机通过 PNG 二维码导入。配置含私钥,权限设为 0600,不进 git。确认握手和 ping 后再登记清单;终端 ASCII 二维码曾显示不全。

板子带回家时,改走直连 ​

拔掉远程依赖后,Mac 上直接 adb devices。CH340/341 的 /dev/cu.wchusbserial* 名字会随 USB 重枚举变化,认波特率和提示符比记名字可靠。

板子 / 控制台波特率识别特征
RV1126B AP1500000root@ATK-DLRV1126B-MCU720:/#
RV1126B MCU1500000msh />
S100P AP921600ubuntu login:
S100P MCU921600无 shell,仅开机日志

S100P 进入 fastboot 的记录步骤:AP 串口约每 100ms 发一个 Ctrl+C(0x03),打断零延迟 autoboot;看到 Hobot$ 后输入 fastboot 0。每 10ms 连发反而淹没 U-Boot 输入缓冲。

文件跟人走,不等于板子能多人同时写 ​

共享任务经 syncthing 分发到编译服务器,watcher 收到后执行:固定流程用 runbook,需要判断才启动 Agent,结果写回 done/failed。会话按“一项目一 folder”同步,三端 folder_id 相同、路径分别映射;projects.tsv 记录映射,云端 ignoreDelete 留存档案。

云端还放了会话浏览(8080)、任务中心(8090)和 09:30 的日报任务,供 WireGuard 内查看;nginx 另托管公开主页和工具链下载。这些是配套,不是远程串口和 ADB 的前提。曾有编译服务器磁盘满导致全部同步 folder 挂起,排查同步时也要看空间。

这篇里有不清楚的地方,或者想聊类似的东西?私信我 →