文档OTA流程说的明白, 但是CRC32的计算没有说明 我穷举各种CRC32的算法, 结果都不能和库中crc32函数算出的结果一样, 因为crc32这个函数不可见, 所以不能知道其具体算法. uint32_t crc32(uint32_t crc, const uint8_t *buf, uint32_t len); 我的OTA操作方式如下: 把编译出的bin文件原封不动直接下载到B区. 1.下载成功之后, 让单片机自己去计算B区的信息数据, 然后写入B区信息位置(4-8K的位置). 复位单片机,让自带的bootloader将B区固件升级到A区. 代码如下. #define A_ZONE_INFO_OFFSET 0 #define B_ZONE_INFO_OFFSET SZ_4KB #define A_ZONE_IMAGE_OFFSET SZ_8KB #define B_ZONE_IMAGE_OFFSET SZ_8KB if (cmd_code == CMD_DOWNLOAD_B_ZONE_IMAGE) { uint32_t b_zone_image_base_addr = (pcmd_data[0] << 8 | pcmd_data[1]) * SZ_4KB; //BIN的下载地址 uint32_t image_length = (pcmd_data[2] << 8 | pcmd_data[3]) * SZ_1KB; //BIN的下载长度 uint32_t image_offset = b_zone_image_base_addr + B_ZONE_IMAGE_OFFSET; //bin中程序代码的偏移, bin的前4KB+4KB都是固件信息数据, if(Download_data(b_zone_image_base_addr, image_length) != true) { Printf_info("■->固件下载失败."); return; } //==== Printf_info("->下载完成."); Printf_info("->设置B区固件信息."); struct image_info_t info = { 0 }; flash_read(b_zone_image_base_addr, sizeof(struct jump_table_t), (uint8_t *)&info); info.compressed_info.compressed_label = 0xFFFFFFFF; info.compressed_info.compressed_image_crc = 0; info.crc.image_crc = crc32(0xffffffff, (const uint8_t *)(QSPI0_DAC_ADDRESS + image_offset), image_length); info.crc.jump_table_crc = crc32(0xffffffff, (const uint8_t *)(&info), (uint32_t)&(((struct jump_table_t *)0)->checkword)); info.image_storage_offset = image_offset; info.image_length = image_length; info.flash_protect_mask = 0x7C;//0xFFFFFFFF; info.image_valid = JUMP_TABLE_OTA_IMAGE_VALID; //--- GLOBAL_INT_DISABLE(); uint16_t status = flash_read_status(false); flash_write_status(status & (0xff), false); //擦除扇区 flash_erase(B_ZONE_INFO_OFFSET, SZ_4KB); flash_write_status(status, false); //写入数据 flash_write_status(status & (0xff), false); flash_write(B_ZONE_INFO_OFFSET, sizeof(struct image_info_t), (uint8_t *)&info); //校验写入的数据 flash_write_status(status, false); GLOBAL_INT_RESTORE(); uint8_t* Ps = (uint8_t *)&info; uint8_t* Pd = (uint8_t*)(QSPI0_DAC_ADDRESS + B_ZONE_INFO_OFFSET); for (int i = 0; i < sizeof(struct image_info_t); i++) { if (*Ps++ != *Pd++) { Printf_info("■->数据写入错误."); Printf_info("->."); return; } } Printf_info("->设置B区固件信息完毕."); Printf_info("->软复位,进行自动升级."); Printf_info("->."); Delay_ms(123); NVIC_SystemReset(); }