使用WCH的BackupUpgrade_OTA例程进行OTA升级时程序始终是在A区运行程序的,B区只是做个中转用来存放升级文件,这样的好处是用于升级的程序好管理,只需要A区起始地址的升级文件即可,若需在B区也可以运行则需B区起始地址的升级文件。
那么下面就讲解下如何实现AB区来回交替升级:
一.BackupUpgrade_JumpIAP例程无需修改,其实现的功能是跳转到BackupUpgrade_IAP;
二.BackupUpgrade_IAP 需做简单的修改,其功能原先是读取dataflash标志为升级标志时将B区文件拷贝到A区然后跳转A区,现在需修改为根据dataflash标志直接跳转A区或B区;
#define jumpApp_imageA ((void (*)(void))((int *)IMAGE_A_START_ADD)) #define jumpApp_imageB ((void (*)(void))((int *)IMAGE_B_START_ADD)) void jump_APP(void) { if(CurrImageFlag == IMAGE_A_FLAG) { jumpApp_imageA(); } if(CurrImageFlag == IMAGE_B_FLAG) { jumpApp_imageB(); } }
三.BackupUpgrade_OTA imageA
1.将例程中的3处地址偏移屏蔽,因为B区升级文件的起始地址为0x37000为220k,hex文件的偏移地址已在OpAdd体现无需偏移,使用bin文件时需收到填入地址0x37000(B区起始地址)或0x1000(A区起始地址)
//OpAdd += IMAGE_A_SIZE;
2.编程程序后原先是修改DataFlash切换至IAP FLAG,需修改为B区FLAG方便IAP进行跳转;
/* 编程结束 */ case CMD_IAP_END: { PRINT("IAP_END \r\n"); /* 当前的是ImageA */ /* 关闭当前所有使用中断,或者方便一点直接全部关闭 */ DisableAllIRQ(); /* 修改DataFlash,切换至ImageB */ SwitchImageFlag(IMAGE_B_FLAG); /* 等待打印完成 ,复位*/ mDelaymS(10); SYS_ResetExecute(); break; }
3.在手机APP软件获取INFO时默认上报的是send_buf[0] = IMAGE_B_FLAG;此处可根据需求进行修改,决定了手机APP可以从imageA或imageB文件夹选择文件;
case CMD_IAP_INFO: { uint8_t send_buf[20]; PRINT("IAP_INFO \r\n"); /* IMAGE FLAG */ send_buf[0] = IMAGE_B_FLAG; /* IMAGE_SIZE */ send_buf[1] = (uint8_t)(IMAGE_SIZE & 0xff); send_buf[2] = (uint8_t)((IMAGE_SIZE >> 8) & 0xff); send_buf[3] = (uint8_t)((IMAGE_SIZE >> 16) & 0xff); send_buf[4] = (uint8_t)((IMAGE_SIZE >> 24) & 0xff); /* BLOCK SIZE */ send_buf[5] = (uint8_t)(FLASH_BLOCK_SIZE & 0xff); send_buf[6] = (uint8_t)((FLASH_BLOCK_SIZE >> 8) & 0xff); send_buf[7] = CHIP_ID&0xFF; send_buf[8] = (CHIP_ID>>8)&0xFF; /* 有需要再增加 */ /* 发送信息 */ OTA_IAP_SendData(send_buf, 20); break; }
四.BackupUpgrade_OTA_imageB
1.将例程中的3处地址偏移屏蔽,因为A区升级文件的起始地址为0x1000为4k,hex文件的偏移地址已在OpAdd体现无需偏移,使用bin文件时需收到填入地址0x37000(B区起始地址)或0x1000(A区起始地址)
//OpAdd += IMAGE_A_SIZE;
2.编程程序后原先是修改DataFlash切换至IAP FLAG,需修改为A区FLAG方便IAP进行跳转;
/* 编程结束 */
case CMD_IAP_END:
{
PRINT("IAP_END \r\n");
/* 当前的是ImageB */
/* 关闭当前所有使用中断,或者方便一点直接全部关闭 */
DisableAllIRQ();
/* 修改DataFlash,切换至ImageA */
SwitchImageFlag(IMAGE_A_FLAG);
/* 等待打印完成 ,复位*/
mDelaymS(10);
SYS_ResetExecute();
break;
}
3.在手机APP软件获取INFO时默认上报的是send_buf[0] = IMAGE_A_FLAG;此处可根据需求进行修改,决定了手机APP可以从imageA或imageB文件夹选择文件;
case CMD_IAP_INFO: { uint8_t send_buf[20]; PRINT("IAP_INFO \r\n"); /* IMAGE FLAG */ send_buf[0] = IMAGE_A_FLAG; /* IMAGE_SIZE */ send_buf[1] = (uint8_t)(IMAGE_SIZE & 0xff); send_buf[2] = (uint8_t)((IMAGE_SIZE >> 8) & 0xff); send_buf[3] = (uint8_t)((IMAGE_SIZE >> 16) & 0xff); send_buf[4] = (uint8_t)((IMAGE_SIZE >> 24) & 0xff); /* BLOCK SIZE */ send_buf[5] = (uint8_t)(FLASH_BLOCK_SIZE & 0xff); send_buf[6] = (uint8_t)((FLASH_BLOCK_SIZE >> 8) & 0xff); send_buf[7] = CHIP_ID&0xFF; send_buf[8] = (CHIP_ID>>8)&0xFF; /* 有需要再增加 */ /* 发送信息 */ OTA_IAP_SendData(send_buf, 20); break; }
4.在B区往A区升级时擦除判断需按照如下修改,因为A区边界和B区边界不同;
/* 擦除 -- 蓝牙擦除由主机控制 */ case CMD_IAP_ERASE: { OpAdd = (uint32_t)(iap_rec_data.erase.addr[0]); OpAdd |= ((uint32_t)(iap_rec_data.erase.addr[1]) << 8); OpAdd = OpAdd * 16; // OpAdd += IMAGE_A_SIZE; EraseBlockNum = (uint32_t)(iap_rec_data.erase.block_num[0]); EraseBlockNum |= ((uint32_t)(iap_rec_data.erase.block_num[1]) << 8); EraseAdd = OpAdd; EraseBlockCnt = 0; /* 检验就放在擦除里清0 */ VerifyStatus = 0; PRINT("IAP_ERASE start:%08x num:%d\r\n", (int)OpAdd, (int)EraseBlockNum); if(EraseAdd < IMAGE_A_START_ADD || (EraseAdd + (EraseBlockNum - 1) * FLASH_BLOCK_SIZE) > IMAGE_B_START_ADD) { OTA_IAP_SendCMDDealSta(0xFF); } else { /* 启动擦除 */ tmos_set_event(Peripheral_TaskID, OTA_FLASH_ERASE_EVT); } break; }
...
浙公网安备 33010602011771号