# PatchReadme **Repository Path**: wanghui0574xs/PatchReadme ## Basic Information - **Project Name**: PatchReadme - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-05-08 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PATCH ## 约定 1. 小端模式, 低字节在前. ## 分包内容 Part: ``` Index + TLen + DiffCrc + OldLen + OldCrc + NewLen + NewCrc + Data Index: 1字节, 分包序号 TLen: 2字节, 分包长度类型, 高字节 bit7表示分包类型, 1:copy, 0:diff; bit6: oldCode不完整; bit5: newCode不完整. DiffCrc: 2字节, diff的CRC16, 验证diffcode的正确 OldCrc: 2字节, oldCode的CRC16, 验证 odlcode正确 OldLen: 2字节, oldCode不完整时, 表示oldCode长度. oldCode不完整时,有此数据, 完整时默认为4k NewCrc: 2字节, newCode的CRC16, 用于验证生成的newCode是否正确. NewLen: 2字节, newCode不完整时, 表示newCode长度, newCode不完整时,有此数据, 完整时默认为4k Data: n字节, 分包数据 ``` ## 补丁文件内容 File: ``` FLen + Fcount + OldLen + OldCrc + NewLen + NewCrc + Part0 + Part1 + ... Partx + CRC FLen: 4字节, 文件长度,包含全部字节数 Fcount: 2字节, 分包数 OldLen: 4字节, old App 的长度 OldCrc: 4字节, old App 的Crc32, 用于验证是否与生成补丁文件时的old一致. NewLen: 4字节, new App 的长度 NewCrc: 4字节, new App 的Crc32, 用于验证是生成的new App是否正确. Part: n字节, 分包内容. CRC: 4字节, 补丁文件从FLen到CRC前的Crc32, 用于传输文件时比对. ``` ## 补丁文件使用: ``` 1. App 程序在接收完整的补丁文件后, 对补丁文件验证正确, 验证old是否与生成补丁文件时的old一致. 之后再启动bootloader升级. 2. bootloader 程序链接patch_lib_xxx.a 3. bootloader 程序的heap设置在8k及以上, stack设置在4k及以上. 4. bootloader 程序声明外部函数patchX. 5. bootloader 程序 升级功能如下: 5.1. 读Fcount, 对分包进行循环 5.2. 读 Index, TLen. 得到分包序号,长度, 类型. 序号不对不升级 5.3. 再按长度获取分包i的内容, 5.4. 将 TLen + DiffCrc + OldLen + OldCrc + NewLen + NewCrc + Data 作为 diff_i 5.5 调用patchX函数, 将old_i, diff_i, 生成 new_i 5.6 patchX 返回1表示new,old一致, 不需要刷mcu; 返回0:表示new, old不一致, 需要刷mcu; 返回<0, 表示失败. 5.6 重复步骤5.2, 5.3, 5.4, 5.5, 5.6直到分包全部处理完毕 ``` 此部分需要由各项目自行处理. ## 函数声明: ``` /** * @brief 补丁使用 * @param newData [ O] 输出new的缓存起始指针 * @param newDataEnd [ O] 输出new的缓存结束指针 * @param oldData [I ] 输入old的起始指针 * @param oldData_end [I ] 输入old的结束指针 * @param diffData [I ] 输入diff的起始指针 * @param diff_end [I ] 输入diff的结束指针 * @return 1:new与old一致, 不需要刷mcu; 0:new与old不一致, 需要刷mcu, <0:失败, -1:old错误, -2:diff错误. */ extern int8_t patchX(uint8_t *newData, uint8_t *newDataEnd, const uint8_t *oldData, const uint8_t *oldData_end, const uint8_t *diffData, const uint8_t *diff_end); ``` ## 例子 ``` #define HAL_malloc(s) malloc(s) #define HAL_free(p) free(p) #define DATAFLASH_READ(buf, addr, len) dataflash_read(buf, addr, len) // dataflash读函数 #define MCUFLASH_WRITE(addr, buf, len) mcuflash_write(addr, buf, len); // mcuflash写函数 #define PATCH_ADDR 0x00000000 // 补丁文件在dataflash里的起始地址 #define APP_CODE 0x00008000 // APP code 在 mcu里的起始地址 #define P_SIZE 4096 // 每包大小 void update(void) { uint8_t *oldCode = APP_CODE; uint8_t *newCode = HAL_malloc(P_SIZE); uint32_t addr = PATCH_ADDR; uint16_t count = 0; uint8_t buf[5]; if (newCode == NULL) { return -1;// 堆分配错误 } DATAFLASH_READ(buf, addr, 2); count = ((uint16_t)(buf[1] << 8u)) + buf[0]; addr += 2; for (uint16_t i = 0; i < count; ++i) { int8_t ret = 0; uint16_t diff_len = 0; uint8_t *diff = NULL; dataflash_read(buf, addr, 2); diff_len = ((uint16_t)(buf[1] << 8u)) + buf[0]; uint8_t *diff = HAL_malloc(diff_len); if (diff == NULL) { return -1;// 堆分配错误 } DATAFLASH_READ(diff, addr, diff_len); if ((ret = patchX(newCode, newCode+P_SIZE, oldCode, oldCode+P_SIZE, diff, diff+diff_len)) < 0) { return ret; // 补丁恢复错误 } MCUFLASH_WRITE((uint32_t)oldCode, newCode, P_SIZE); // next addr += diff_len; oldCode += P_SIZE; HAL_free(diff); } HAL_free(newCode) } ``` ## 待解决问题 1. diff 里带new_i 的crc16 2. patch文件的crc 使用 crc32 3. old 与patch的old不一致 如何保证? 4. 完全相同的, 考虑不擦出mcu, 提升升级效率. 5. ff的比对出是不同的. 需要特殊处理. ##### #### 码云特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)