前面介绍了一篇6621CxC在BLE模式下程序自我更新的帖子,现在介绍在2.4G模式下程序自我更新的示例 1)准备新的测试固件 2)计算新固件的CRC值,通过网站http://www.ip33.com/crc.html计算 计算到新固件CRC是0x5e02; 3)新固件烧录地址,我们这里填0x33000 4)原固件需要调用的接口函数 // 新固件CRC 0x5e02 // 新固件存放地址 0x33000 // 新固件长度 0xc7b8 modify_mbr_run_new_program(0x5e02, 0x33000, 0xc7b8); // 开启看门狗重启芯片。 wdt_enable(1); while (1); uint8_t flash_addr_offset = 0; // 用于修改mrb内容时操作对应的数组地址 CO_ALIGN(4) uint8_t write_buffer[16 * 9]; CO_ALIGN(4) uint8_t read_buffer[16 * 9]; void modify_mbr_run_new_program(uint16_t file_crc, uint32_t file_new_addr, uint32_t file_size) { // 使能flash读写操作 sf_enable(HS_SF, 0); // 先读取0x1170开始的位置的mbr信息,一共是16*9个数据 sf_read(HS_SF, 0, 0x1170, read_buffer, 16 * 9); log_debug("\nread original mbr data="); log_debug_array(read_buffer, 16 * 9); // 将读取出来的mbr数据,备份来做修改 memcpy(write_buffer, read_buffer, 16 * 9); log_debug("\ncopy mbr info="); log_debug_array(write_buffer, 16 * 9); /*注意:addr 4 bytes这里的地址需要右移12 bit,比如0x3000的地址,对应的是 03 00 00 00,0x33000地址对应的是33 00 00 00 0x117B~0x117D:频率(MHz),1/2/4线,Delay值 0x117E~0x118D:FF(Status) FF FF FF(FirstSector) 60(应用程序) FF(LastSector) [CRC 2 bytes] [addr 4 bytes] [lenght 4 bytes] */ flash_addr_offset = 16 * 1; // 修改的是应用程序的mbr信息 // app crc ,根据你的程序计算得到的crc填写进来 write_buffer[flash_addr_offset + 4] = (uint8_t)(file_crc & 0xff); // 低位 write_buffer[flash_addr_offset + 5] = (uint8_t)((file_crc >> 8) & 0xff); // 高位 // app addr ,根据你程序存放的位置填写进来 file_new_addr = file_new_addr >> 12; write_buffer[flash_addr_offset + 6] = (uint8_t)((file_new_addr >> 0) & 0xff); // 新固件存放地址 0x33000 write_buffer[flash_addr_offset + 7] = (uint8_t)((file_new_addr >> 8) & 0xff); // write_buffer[flash_addr_offset + 8] = (uint8_t)((file_new_addr >> 16) & 0xff); // write_buffer[flash_addr_offset + 9] = (uint8_t)((file_new_addr >> 24) & 0xff); // // app lenght ,根据你程序的长度填写进来 write_buffer[flash_addr_offset + 10] = (uint8_t)(file_size & 0xff); // 低位 write_buffer[flash_addr_offset + 11] = (uint8_t)((file_size >> 8) & 0xff); // write_buffer[flash_addr_offset + 12] = (uint8_t)((file_size >> 16) & 0xff); // write_buffer[flash_addr_offset + 13] = (uint8_t)((file_size >> 24) & 0xff); // 最高位 // 有需要的话,修改其他内容 flash_addr_offset = 16 * 8; // 这个区域的内容只能是这个,或者是FF FF(无用) write_buffer[flash_addr_offset + 14] = 0x55; write_buffer[flash_addr_offset + 15] = 0xAA; log_debug("\nmodify mbr info="); log_debug_array(write_buffer, 16 * 9); // 先擦除0x2000的4k内容,修改0x2170开始的内容,做好备份工作 sf_erase(HS_SF, 0, 8 * 1024, 4 * 1024); sf_write(HS_SF, 0, 0x2170, write_buffer, 16 * 9); // 再擦除0x1000的4k内容,修改0x1170开始的内容 sf_erase(HS_SF, 0, 4 * 1024, 4 * 1024); log_debug("\nerase mbr for 4k"); sf_read(HS_SF, 0, 0x1170, read_buffer, 16 * 9); log_debug("\nafter erase mbr, data is="); log_debug_array(read_buffer, 16 * 9); sf_write(HS_SF, 0, 0x1170, write_buffer, 16 * 9); sf_read(HS_SF, 0, 0x1170, read_buffer, 16 * 9); log_debug("\nre_write mbr data="); log_debug_array(read_buffer, 16 * 9); // 调用这个函数重启芯片。 // pmu_force_reboot(); } 5)经过测试验证,可以实现新固件的更新并运行新固件 |