Hi3861 OTA功能介绍
StashRecvDataToBuffer函数功能分析
函数功能概述
StashRecvDataToBuffer函数是OTA升级过程中的核心数据存储函数,负责将接收到的升级数据缓存到内存或写入到存储设备的HAL层。
函数签名
1 | static int StashRecvDataToBuffer(unsigned char *buffer, unsigned int startAddr, unsigned int endAddr) |
参数说明
buffer: 要存储的数据缓冲区startAddr: 数据的起始地址(相对于当前组件的偏移)endAddr: 数据的结束地址(相对于当前组件的偏移)
函数执行流程
1. 信息组件处理分支
1 | if (g_currentDloadComp.isInfoComp) { |
功能: 当前下载的是信息组件时,将数据复制到内存缓冲区g_infoCompBuff中。
用途: 信息组件包含升级包的元数据,需要先完整接收并验证后才能处理其他组件。
2. 非信息组件处理分支
1 | else { |
功能:
- 获取当前组件对应的分区ID
- 调用HAL层写入函数将数据写入对应分区
- 计算数据的哈希值用于后续验证
3. 状态更新
1 | g_currentDloadComp.remainSize -= (endAddr - startAddr); |
功能: 更新当前组件的下载进度信息。
Partition可选项分析
基于Hi3861平台的Partition定义
1 | typedef enum { |
特殊分区定义
1 |
分区组件映射表
1 | static const ComponentTableInfo g_componentTable[] = { |
Partition对OTA的影响
1. 数据路由影响
分区选择机制:
- 通过
GetCurrentDloadCompPartition函数,根据组件名称映射到具体的分区ID - 不同的分区ID决定了数据最终写入的物理位置
2. 双分区升级机制
KERNEL_A vs KERNEL_B:
PARTITION_KERNEL_A(3): 当前运行的内核分区PARTITION_KERNEL_B(4): 备用内核分区,用于A/B分区升级- 支持无缝升级和快速回滚
3. 信息组件特殊处理
PARTITION_INFO_COMP (1):
- 特殊处理,不直接写入存储
- 数据缓存在内存中,用于验证和解析升级包信息
- 包含组件列表、版本信息、签名数据等
4. HAL层写入行为
1 | int HotaHalWrite(int partition, unsigned char *buffer, unsigned int offset, unsigned int buffLen) |
不同分区的写入行为:
- 信息组件: 跳过HAL写入,仅在内存中处理
- 其他组件: 通过
hi_upg_transmit写入到对应的Flash分区
5. 错误处理影响
分区错误的影响:
PARTITION_ERROR(-1): 表示分区映射失败- 导致升级失败,系统状态回到
HOTA_FAILED - 触发错误回调
HOTA_DATA_WRITE_ERR
6. 升级策略影响
不同分区的升级策略:
- Bootloader: 通常需要特殊的升级保护机制
- Kernel: 支持A/B分区无缝升级
- RootFS: 文件系统级别的升级
- App: 应用程序更新
- Data: 用户数据分区,通常保持不变
总结
StashRecvDataToBuffer函数通过partition参数实现了灵活的数据路由机制:
- 信息组件:内存缓存,用于元数据解析和验证
- 系统组件:写入对应的Flash分区,支持A/B分区升级
- 错误处理:通过分区ID验证确保升级安全性
Partition的选择直接影响了:
- 数据的物理存储位置
- 升级策略(A/B分区、原地升级等)
- 系统的启动行为
- 升级失败时的恢复机制
这种设计确保了OTA升级过程的灵活性和安全性,支持不同类型组件的差异化处理。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Small Utopia!
评论