6621CxC单2.4G模式下程序自我更新

yangzh · 177次点击 · 2023-05-27

前面介绍了一篇6621CxC在BLE模式下程序自我更新的帖子,现在介绍在2.4G模式下程序自我更新的示例

1)准备新的测试固件

image.png

2)计算新固件的CRC值,通过网站http://www.ip33.com/crc.html计算

image.png

计算到新固件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)经过测试验证,可以实现新固件的更新并运行新固件




ble_app_freertos_24g_1202305279465.rar
被收藏 0  ∙  0 赞  
加入收藏
点赞
0 回复  
善言善语 (您需要 登录 后才能回复 没有账号 ?)

请先登录网站