CP固件升级工具
用途:Android 手机上通过 USB OTG 对搭载芯片的背夹设备进行一键固件升级。
核心技术:
模块 技术
USB 通信 CH343 CDC 三通道串口(MCU 115200 / CMD 921600 / DATA 115200)
下载引擎 自研 native 库(C + JNI),同步 → MBL → xboot → 批量 img 下载协议
波特率切换 115200 低速同步 → 2000000 高速传输,自动适配
可靠性 native 层 mutex 保护 + dl_active 防竞态,帧级 5 次重试
循环压测 自动循环下载+统计,支持 300+ 次连续测试
1、通信链路:Android USB Host → CH343 桥接 → MCU → UART
2、成果:独立 APK,一台手机即可完成固件升级,支持自动循环压测。
3、难点
1. 线程竞态 — native crash (SIGSEGV at dataReceive+124)
现象:连续下载几十次后 app 崩溃,fault addr 0x6,读线程 pool-N-thread-2。
根因:读线程 SC80_downloaderDataRec 和下载线程 *_wait_semaphore_callback 同时操作 dl_action.frame_data。
2. USB 端口关闭时机 — 堆损坏 (Scudo corruption)
根因:releaseAll() 调用 executor.shutdownNow() 后不等读线程退出就 port.close(),读线程还在 port.read() 中造成 USB 驱动内部状态冲突。
3. 文件 I/O 干扰下载 — CRC 错误
4. xboot 波特率切换时序 — partition.cfg 错误码 01
解决:第二次回调用 changeCmdBaudRate(不关端口),避免 enumDevices 打断已建立的高速通信。
5. MBL 同步假阳性 — "D" 自身 echo 匹配
解决:调整 ack 数组顺序,"@boot:" 放在 "D" 前面。
4、坑
AAR 版本混乱 1.0.0/1.0.1/1.0.2/1.0.3 多次替换,BuildId 确认生效 统一到 1.0.3
GC 终结器干扰 USB UsbRequest.close 在下载期间被 GC 调用 awaitTermination(500ms) + 关闭 DEBUG 日志
TTLON 不等待竞态 MCU 处理 TTLON 期间 enumDevices 关闭 USB 打断 加 200ms 延迟
Protocol 改动影响文本处理 NULL 检查和 frame_parse 重置破坏 ack 匹配 回退到最小改动
cmdBuffer 清空时机 waitForCmdResponse 清空时已缓存的数据丢失 先检查再清空
5、关键代码修改
*_downloader.c new — dl_active + mutex + destroyNative + 5次重试 + sleepMs 300ms + ack 顺序修复
*_protocol.c 1处 NULL