共计 1661 个字符,预计需要花费 5 分钟才能阅读完成。
开篇痛点
刚入行嵌入式开发时,最头疼的就是设备分散在各个现场。每次升级固件都得跑现场,成本高不说,遇到紧急参数调整更是抓狂。还记得有次为了改一个温度阈值参数,硬是开车跑了 200 公里。这种经历让我下定决心研究远程管理方案。

通信协议选型
- HTTP 协议:最简单直接,适合小文件传输。但长连接维护成本高,我们测试发现设备在弱网环境下容易断开。
- MQTT 协议:轻量级发布 / 订阅模式,特别适合物联网场景。实测在 2G 网络下,1MB 固件包传输成功率比 HTTP 高 30%。
- CoAP 协议:专为受限设备设计,但生态不如 MQTT 成熟。
差分升级 绝对是流量敏感场景的救星。我们项目中使用 bsdiff 算法,使升级包体积平均减少 85%:
// bsdiff 示例(简化版)void apply_diff(FILE* old, FILE* new, FILE* patch) {
// 1. 读取差异头
// 2. 按块应用差异
// 3. 校验新文件 CRC32
}
核心实现三要素
固件签名校验
使用 RSA2048+PSS 方案,密钥对生成推荐 OpenSSL:
# 生成密钥对(生产环境建议使用 HSM)openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem
校验代码示例:
int verify_signature(uint8_t* fw_buf, size_t fw_len,
uint8_t* sig, size_t sig_len) {
// 1. 加载公钥
EVP_PKEY* pubkey = load_pem_key("public.pem");
// 2. 初始化验证上下文
EVP_MD_CTX* ctx = EVP_MD_CTX_new();
EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, pubkey);
// 3. 执行验证(返回 1 为成功)return EVP_DigestVerify(ctx, sig, sig_len, fw_buf, fw_len);
}
断点续传设计
状态机是关键,我们采用以下状态:
stateDiagram
[*] --> IDLE
IDLE --> DOWNLOADING: 收到升级指令
DOWNLOADING --> PAUSED: 网络中断
PAUSED --> DOWNLOADING: 网络恢复
DOWNLOADING --> VERIFYING: 下载完成
VERIFYING --> UPDATING: 校验通过
UPDATING --> [*]: 重启生效
参数原子性保障
对比两种方案:
- EEPROM 方案:
- 优点:单字节擦写
- 缺点:寿命约 10 万次
- Flash 方案:
- 采用双 bank 设计(参考 IEC 60730 标准)
- 写操作前先备份到临时区
安全防护实战
防中间人攻击
必须启用 TLS1.2+,推荐 mbedTLS 配置:
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
版本防回滚
遵循 RFC4122 规范,版本号包含时间戳:
typedef struct {
uint32_t timestamp; // Unix 时间戳
uint16_t major;
uint16_t minor;
uint8_t hash[16]; // MD5 校验值
} fw_version_t;
真实踩坑案例
-
堆栈溢出:某次升级失败因为没考虑解压时的内存需求,后来增加了预检:
if (fw_header.uncompressed_size > MAX_MEM) {return ERR_MEM_OVERFLOW;} -
电源异常:突然断电导致参数区损坏,现在关键参数区都做三备份。
-
证书过期:忘记更新 CA 证书导致全体设备失联,现在设置双重证书缓冲期。
百万级设备升级思考
当设备量达到百万级时,需要:
– 采用分级发布策略(先 1% 设备灰度)
– 使用 P2P 分发网络(如 LibTorrent 嵌入式版)
– 动态调整带宽(夜间自动提速)
你遇到过哪些远程升级的难题?欢迎分享你的解决方案。
正文完
发表至: 未分类
近三天内
