CH32V32的IAP的小应用

    CH32的MCU配置了USB-IAP的下位机与上位机,便于客户后续迭代升级使用,其实就是利用MCU的通信外设(USB与串口),将升级的固件下发到芯片ram里,然后执行flash编程,结束后即可跳转程序执行APP,

此处可以不局限于升级APP,也可以通过此方式,将数据转发出去,已实现更多的功能,一下列举几个例子。

   1、通过IAP上位机,将数据转换成其他接口,例如IIC,SPI。对于需要大量数据进行刷新文件系统或者字库,还有固定的配置信息等,可以直接在USB通信流程种,将本来需要flash编程的数据转发出去。

u8 RecData_Deal(void)
{
u8 s, Lenth;
u16 i;
Lenth = isp_cmd_t->other.buf[1];

switch ( isp_cmd_t->other.buf[0]) {
case CMD_IAP_ERASE:
// FLASH_Unlock_Fast();
s = ERR_SUCCESS;
break;

case CMD_IAP_PROM:
for (i = 0; i < Lenth; i++) {
Fast_Program_Buf[CodeLen + i] = isp_cmd_t->program.data[i];
}
CodeLen += Lenth;
if (CodeLen >= 256) {
// FLASH_Unlock_Fast();
// FLASH_ErasePage_Fast(Program_addr);
// CH32_IAP_Program(Program_addr, (u32*) Fast_Program_Buf);
/*这里写外部flash长度256字节,buf首地址Fast_Program_Buf,写入外部flash地址Program_addr,这里是个宏,改成外部flash的地址即可,将这些数据通过SPI或者并口发送至外部flash*/
CodeLen -= 256;
for (i = 0; i < CodeLen; i++) {
Fast_Program_Buf[i] = Fast_Program_Buf[256 + i];
}

Program_addr += 0x100;

}
s = ERR_SUCCESS;
break;

case CMD_IAP_VERIFY:

if (Verify_Star_flag == 0)
{
Verify_Star_flag = 1;
if(CodeLen != 0)
{
for (i = 0; i < (256 - CodeLen); i++)
{
Fast_Program_Buf[CodeLen + i] = 0xff;//不足一页256字节的补ff
}
/*这里写外部flash长度不足256字节的部分,*/
// FLASH_ErasePage_Fast(Program_addr);
// CH32_IAP_Program(Program_addr, (u32*) Fast_Program_Buf);
CodeLen = 0;
}
}
s = ERR_SUCCESS;
for (i = 0; i < Lenth; i++) {
if (isp_cmd_t->verify.data[i] != *(u8*) (Verify_addr + i)) { //此处校验,可以将外部flash读取后再对比,不想要的话直接屏蔽即可。
s = ERR_ERROR;
break;
}
}

Verify_addr += Lenth;
break;

case CMD_IAP_END://不想要屏蔽即可
Verify_Star_flag = 0;
End_Flag = 1;
Program_addr = FLASH_Base;
Verify_addr = FLASH_Base;
s = ERR_End;

FLASH_ErasePage_Fast(CalAddr & 0xFFFFFF00);
FLASH->CTLR |= ((uint32_t)0x00008000);
FLASH->CTLR |= ((uint32_t)0x00000080);

break;
case CMD_JUMP_IAP:

s = ERR_SUCCESS;
break;
default:
s = ERR_ERROR;
break;
}

return s;
}

此处为示例代码,主要是增加注释处的接口转发或者处理代码。

2、同样的可以增加二次开发与脚本功能,我们IAP程序完全开源,为高级用户或开发者提供更开放的能力。

 定义应用层协议:在原始的“固件数据包”协议之上,封装一层指令协议。示例协议帧:[帧头][指令码][数据长度][数据域][校验和][帧尾]

   isp_cmd_t->other.buf[0];IAP程序中的指令码结构体

指令码用于区分不同功能:0x01代表升级APP,0x02代表读Flash,0x03代表写配置,0x04代表读取传感器数据等。

#define Uart_Sync_Head1   0xaa
#define Uart_Sync_Head2   0x55

#define CMD_IAP_PROM      0x80
#define CMD_IAP_ERASE     0x81
#define CMD_IAP_VERIFY    0x82
#define CMD_IAP_END       0x83
#define CMD_JUMP_IAP      0x84

#define ERR_SUCCESS       0x00
#define ERR_ERROR         0x01
#define ERR_End           0x02
可以对应增加cmd命令码与IAP上位机对应即可。
IAP程序主要
  • 解析上位机下发的指令帧。

  • 根据指令码执行对应操作(编程Flash、读取数据、配置参数等)。

  • 将执行结果或请求的数据打包成响应帧,返回给上位机。

不过此处的上位机更改可能有些大,但是IAP下位机程序的框架结构,适用于客户CDC/HID通信通道:专门用于产品功能的所有其他交互:参数配置、数据读取、诊断日志、文件传输等通信。

如果要通过升级流程更新数据,请采用方案一:定制固件容器格式,让IAP做“傻”的搬运工,让智能的APP去解析和处理数据。这是对现有架构最有效的利用。

posted @ 2025-09-02 17:13  WCH_CH32  阅读(72)  评论(0)    收藏  举报