从故障诊断到可交付 SDK¶
设备偶发无响应时,“重启以后好了”留下的解释很少。交付一个 SDK,需要让集成者区分请求超时、通道断开、事件循环失去进展和设备故障,也需要知道库在什么环境里构建、支持哪些能力以及如何安全退出。
前置阅读:SDK 契约、双运行时。构建条件见环境准备,公开头文件、示例与许可见源码与版本。
用快照连接症状和故障层¶
| 观测 | 能支持的判断 | 仍需补充的信息 |
|---|---|---|
| 线程或任务存活 | 执行对象尚在 | 是否取得业务进展 |
| owner 处理事件 | 事件循环有进展 | 是否在某类事件上长期饥饿 |
| 请求持续完成 | 部分业务链路正常 | 失败类型、尾延迟与数据完整性 |
| 后端健康回复 | 通道和协议有响应 | 实际设备功能是否正常 |
日志关联 instance、generation、id、状态、终态原因和时间边界。记录入口、水位、live、丢弃与恢复次数,使一次断连能追踪到具体会话。单纯定时喂 watchdog 不能替代这些进展指标,本 SDK 也没有整机 watchdog 实现。
恢复从最小必要层级开始¶
请求结束、通道重建、设备复位和整机重启的状态损失不同。先确定哪一层失效,再规定负责恢复的对象、最大次数、退避和失败终态。各层独立无限重试容易把一次故障扩大为持续过载。
本例由调用者显式发起 recover。旧请求失败,新 generation 在后端 ready 后接收工作;恢复失败进入 FAILED。超时请求可能已经产生远端副作用,恢复或重试前需要业务协议给出幂等性和状态查询办法。
停止超时同样保留对象。等待线程返回 SDK_ETIME,说明这次等待预算耗尽;callback、owner 或后端仍可能使用实例。安全销毁顺序见生命周期评审。
兼容性分成三个承诺¶
| 层次 | 问题示例 | 发布时需要写明 |
|---|---|---|
| 源码 API | 新头文件能否编译旧调用者 | 参数、函数与行为的兼容范围 |
| 二进制 ABI | 已编译程序能否换库运行 | 架构、libc、符号和结构布局 |
| wire 协议 | 两端不同版本能否通信 | 编码、版本协商和拒绝规则 |
本例 API 与协议版本为 1;这个数字不承诺未来任意二进制布局兼容。wire 使用显式序列化,拒绝版本不符、截断与超长消息。能力查询把不支持的 remote cancel、pause_data 和裁剪后的数据能力明确报告给调用者。
让一个新目录独立集成¶
集成者至少需要头文件、库或源码、依赖、示例、构建条件和许可。预编译库标明架构、libc 与选项;换环境时从源码重编。下载与校验方式见源码入口。
在专用工具容器的项目根目录执行:
make -C platform all libraries
make -C platform public-test
./build/platform/sdk-demo /work/build/platform/device-sim
public-test 使用只包含 sdk.h 的外部消费者,链接顺序为:
需要 FreeRTOS 时,先获取并校验固定依赖,再构建该 runtime。空目录演练帮助发现缓存和手工准备项;仍应保留真实集成者反馈,尤其是交叉编译、能力查询与错误处理。
证据要能解释通过的范围¶
每次运行记录源码哈希、命令、环境、工具版本、退出码和原始结果。预期失败检查具体触发与原因;SKIP 写清缺失条件。历史基准、当前修订源码测试和真实硬件测量分别标记,避免一份旧 PASS 覆盖后来改动。
ASan/UBSan 支持已执行路径的内存与未定义行为检查,TSan 支持已执行交错的数据竞争检查。专用 QEMU 的内核实验与真实 DMA、无线链路和 MCU 时序是不同范围,验证入口统一从源码与版本查阅。
产品生命周期还需要额外决策¶
| 阶段 | 需要准备的决定与验证 |
|---|---|
| 集成 | 支持组合、接口冻结、变更影响与回归 |
| 长期运行 | 混合负载、恢复次数、资源峰值和现场诊断 |
| 升级 | 中断、校验失败、断电、启动失败、配置迁移与回滚 |
| 供应替代 | 改板、驱动、认证、工具授权与维护成本 |
| 停止支持 | 修复窗口、兼容版本、迁移和数据保留 |
安全启动、双分区和反回滚等选项需要产品策略、Flash、密钥和恢复责任共同评审。本实验没有这些产品级验证;平台的选择与完整评审方法见平台选型和评审清单。
进一步定义故障保证¶
一次本地 terminal 不等于远端副作用只执行一次。故障模型与恢复边界用丢回复与重试展开结果未知、去重、时间预算和恢复层级。