> 技术文档 > MM32单片机IAP程序升级参考例程(包含源码协议和上位机)

MM32单片机IAP程序升级参考例程(包含源码协议和上位机)

以下是关于MM32单片机IAP(In Application Programming)程序升级的参考例程信息,包含源码、通信协议和上位机工具的相关内容:

硬件与开发环境

  • MCU型号:MM32全系列(如MM32F0140、MM32G0005等),需确认具体型号匹配例程。
  • 开发工具:Keil MDK/IAR/MM32官方IDE,建议使用最新版本支持包。
  • 通信接口:通常通过UART/USART/USB/I2C等实现IAP,需硬件支持。

IAP基本原理

  • Bootloader设计:存储在MCU起始地址(如0x08000000),负责接收新固件并写入应用程序区。
  • 应用程序跳转:Bootloader通过判断Boot flag跳转到应用程序入口(如0x08004000)。

参考源码结构

  • Bootloader部分

    int main(void){ uint8_t flag[4]; uint16_t len; FLASH_Read(flag, BootJumpFlagAddress, 4); if ((flag[0] == 0x55) && (flag[1] == 0xAA) && (flag[2] == 0xAA) && (flag[3] == 0x55)) // 如果用户程序有效,则跳转到用户程序执行用户程序。 { // Reset_Periph();//跳转之前,需要关闭boot初始化过的外设,避免导致跳到APP里面后boot里面的外设仍然在工作 __disable_irq(); __set_MSP(*(u32 *)ApplicationAddress);  // 设置SP.,堆栈栈顶地址 ((void (*)(void)) * (u32 *)(0x04 + ApplicationAddress))(); // 生成跳转函数.将复位中断向量地址做为函数指针 } PLATFORM_Init(); UART_Configure(115200); while (1) { if (USART_RX_STA & 0x8000) { len = USART_RX_STA & 0x7FFF; boot_protocol(UART_RxBuff, len); USART_RX_STA = 0; } }}
  • Boot Jump Flag信息存储区

    在Flash空间定义了1K信息存储区,目前例程只实现了一个Boot Jump Flag的存储,当Bootloader启动后先读取这个Boot Jump Flag,如果是0x55, 0xAA, 0xAA, 0x55则直接跳转到Application,如果不是则运行Bootloader升级程序等待升级。
    后续可以对这个工程进行完善,比如信息存储区间添加Bootloader程序区间校验码和Application程序区间校验码,上电后两段区间校验通过程序才会继续运行,保证系统的稳定性
    顺便多提有点,如果在这个工程上修改成自己的程序,如果程序跳转到APP后需要升级,那需要把这1K信息存储区擦除后复位即可。

     if ((flag[0] == 0x55) && (flag[1] == 0xAA) && (flag[2] == 0xAA) && (flag[3] == 0x55)) // 如果用户程序有效,则跳转到用户程序执行用户程序。 { // Reset_Periph();//跳转之前,需要关闭boot初始化过的外设,避免导致跳到APP里面后boot里面的外设仍然在工作 __disable_irq(); __set_MSP(*(u32 *)ApplicationAddress);  // 设置SP.,堆栈栈顶地址 ((void (*)(void)) * (u32 *)(0x04 + ApplicationAddress))(); // 生成跳转函数.将复位中断向量地址做为函数指针 }
  • 应用程序部分

    • MM32F5270/MM32F5330 STAR-MC1内核的需修改链接脚本(.sct文件),将程序起始地址设置为非Bootloader区域。
    • 其他M0/M0+/M3内核则可以直接修改Keil 工程Option -> Target 修改Flash RAM分配
    • 跳转到Application后,Coretx-M0 内核需要把中断向量表copy到RAM,然后配置SYSCFG_CFGR嵌入式 RAM 映射到 0x0000 0000。如果是Coretx-M0+/Cortex-M3/Cortex-M4/STAR-MC1 内核则可以直接配置SCB->VTOR将中断向量表直接偏移
    //Coretx-M0#define APPLICATION_ADDRESS (uint32_t)(0x08001400) // APP START ADDRESS#define VECTOR_SIZE 0xC0 // M0 要把APP的向量表转移到SRAM memcpy((void *)0x20000000, (void *)APPLICATION_ADDRESS, VECTOR_SIZE); // Enable the SYSCFG Peripheral Clock RCC_APB1PeriphClockCmd(RCC_APB1ENR_SYSCFG, ENABLE); // Remap SRAM at 0x00000000 将SRAM中的向量表映射到0x0000000 SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM); __enable_irq();//Coretx-M0/M3/STAR-MC1#define APP_ADDRESS_OFFSET 0x1400 SCB->VTOR = FLASH_BASE | APP_ADDRESS_OFFSET; //M0+可以对中断向量进行偏移,这样app的中断可以直接跳到自己的中断服务函数 __enable_irq();//跳转之后要确保打开总中断 

通信协议

  • 帧格式示例(自定义协议):
    链接里面带自定义通讯协议文档,同时还有配套的上位机软件

    #define GET_VERSION 0x20
    #define ERASE_APP 0x21
    #define SYSTEM_RESET 0x22
    #define WRITE_APP 0x23
    #define VERIFY_APP 0x24
    #define CLEAR_FLAG 0x25
    #define WRITE_FLAG 0x26
    #define SEG_STARTADDR 0x27 // 因支持hex文件多段下载,特需此指令
    #define MCU_INFO 0x28      // 上位机获取MCU分给APP空间大小和APP存放的起始位置

    void boot_protocol(u8 *buff, u16 len){ u8 cmd; memcpy(sendbuff, buff, len); buff = sendbuff; if (Check_data(buff)) { memcpy(buff, USB_Return_Err, 0x40); UART_SendGroup(buff, Send_Size); return; } cmd = buff[0]; switch (cmd) { case GET_VERSION: getVersion(buff); break; case ERASE_APP: eraseAppSpace(buff); break; case SYSTEM_RESET: resetMCU(buff); break; case WRITE_APP: appCodeDownload(buff); break; case VERIFY_APP: appVerify(buff); break; case CLEAR_FLAG: clearAppFlag(buff); break; case WRITE_FLAG: writeAppFlag(buff); break; case SEG_STARTADDR: segmentInfo(buff); break; case MCU_INFO: mcuInfo(buff); break; default: break; }}
    • CMD: 升级指令
    • Packet length:数据长度
    • Data 通讯数据
    • CRC: CRC16校验

 

资源获取

开源链接:

https://gitee.com/skydiver/mm32-iap-demo

建议结合具体MM32型号的参考手册,确认Flash分区大小和通信外设配置。开发时优先测试Bootloader与应用程序的独立功能,再整合联调。