ST意法半导体
直播中

马占云

8年用户 1645经验值
私信 关注
[问答]

有没有哪位大神提供一个STM32H523或者STM32H563的串口升级的IAP程序?

有没有哪位大神提供一个STM32H523或者STM32H563的串口升级的IAP程序

回帖(1)

程成

2025-6-18 17:52:09

以下是一个基于STM32H523/H563的串口IAP程序框架,采用USART1作为升级接口。这个程序实现了基本的Flash擦写、应用程序跳转和数据接收验证功能,请根据实际硬件调整引脚和Flash参数。




1. IAP核心代码 (Bootloader)


#include "stm32h5xx.h"

#define APP_ADDR        0x08010000    // 应用程序起始地址
#define FLASH_PAGE_SIZE 2048          // H5系列Flash页大小(2KB)

void SystemClock_Config(void);
void USART1_Init(void);
void FLASH_ErasePage(uint32_t addr);

int main(void) {
    // 初始化
    HAL_Init();
    SystemClock_Config();
    USART1_Init();

    // 检查是否跳转到APP
    if((*(volatile uint32_t*)APP_ADDR & 0x2FFE0000) == 0x20000000) {
        // 设置向量表
        SCB->VTOR = APP_ADDR;

        // 跳转到应用程序
        void (*app_entry)(void) = (void (*)(void)) * (volatile uint32_t*)(APP_ADDR + 4);
        app_entry();
    }

    // IAP主循环
    uint8_t rx_buffer[256];
    while(1) {
        uint8_t cmd = USART_ReceiveByte();  // 自定义接收函数

        if(cmd == 0xC0) {  // 开始传输指令
            uint32_t file_size;
            USART_ReceiveData((uint8_t*)&file_size, 4);

            // 计算需要擦除的页数
            uint32_t pages = (file_size + FLASH_PAGE_SIZE - 1) / FLASH_PAGE_SIZE;

            // 擦除Flash
            FLASH_ErasePage(APP_ADDR);

            // 接收并写入数据
            uint32_t addr = APP_ADDR;
            for(uint32_t i = 0; i < file_size; i += sizeof(rx_buffer)) {
                uint16_t chunk = (file_size - i) < sizeof(rx_buffer) ?
                                (file_size - i) : sizeof(rx_buffer);

                USART_ReceiveData(rx_buffer, chunk);
                FLASH_Program(addr, rx_buffer, chunk);
                addr += chunk;
            }

            // 发送成功响应
            USART_SendByte(0xA0);
        }
    }
}

// Flash页擦除
void FLASH_ErasePage(uint32_t addr) {
    HAL_FLASH_Unlock();

    FLASH_EraseInitTypeDef erase = {
        .TypeErase = FLASH_TYPEERASE_PAGES,
        .Page = (addr - FLASH_BASE) / FLASH_PAGE_SIZE,
        .NbPages = 1
    };

    uint32_t fault;
    HAL_FLASHEx_Erase(&erase, &fault);

    HAL_FLASH_Lock();
}

// Flash编程
void FLASH_Program(uint32_t addr, uint8_t *data, uint32_t len) {
    HAL_FLASH_Unlock();

    for(uint32_t i = 0; i < len; i += 8) {
        uint64_t word = *(uint64_t*)&data[i];
        HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr + i, word);
    }

    HAL_FLASH_Lock();
}



2. 应用程序修改要求




  1. 修改链接脚本(.ld文件)


    MEMORY {
    RAM    (xrw)    : ORIGIN = 0x20000000, LENGTH = 64K
    FLASH  (rx)     : ORIGIN = 0x08010000, LENGTH = 192K  /* 前64KB留给IAP */
    }



  2. main函数开头添加向量表重定位


    int main(void) {
       // 中断向量表重定位
       SCB->VTOR = 0x08010000;
       // ...其他初始化
    }





3. 上位机通信协议示例










































指令 方向 说明
0xC0 PC→MCU 开始升级
[4字节] PC→MCU 固件大小(小端格式)
[固件数据] PC→MCU 二进制文件内容
0xA0 MCU→PC 升级成功响应
0xE1 MCU→PC 擦除失败
0xE2 MCU→PC 编程失败



4. 关键配置说明




  1. 时钟配置



    • 使用HSE时钟源
      RCC_OscInitTypeDef osc = {
      .OscillatorType = RCC_OSCILLATORTYPE_HSE,
      .HSEState = RCC_HSE_ON
      };
      HAL_RCC_OscConfig(&osc);




  2. 串口配置(USART1)


    void USART1_Init(void) {
    __HAL_RCC_USART1_CLK_ENABLE();
    USART1->BRR = HAL_RCC_GetHCLKFreq() / 115200; // 波特率
    USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
    }



  3. Flash保护配置



    • 在IAP中关闭写保护
      HAL_FLASH_Unlock();
      HAL_FLASH_OB_Unlock();






5. 使用注意事项




  1. Flash安全



    • 操作前必须解锁FLASH和OB(选项字节)

    • 擦除/编程时禁用中断




  2. 防变砖措施


    // 在APP中设计返回Bootloader的入口
    void Enter_Bootloader(void) {
       __disable_irq();
       *((volatile uint32_t*)0x2000FFF0) = 0xDEADBEEF; // 标记内存
       NVIC_SystemReset();
    }

    // IAP启动时检查标记
    if(*((volatile uint32_t*)0x2000FFF0) == 0xDEADBEEF) {
       *((volatile uint32_t*)0x2000FFF0) = 0; // 清除标记
       // 留在IAP模式
    }



  3. 固件校验


    // 接收完成后添加CRC校验
    if(Calculate_CRC(APP_ADDR, file_size) != expected_crc) {
       USART_SendByte(0xE3); // CRC错误
    }





6. 完整项目依赖



  1. STM32CubeH5库 (v1.1.0或更高)

  2. 串口驱动实现(接收中断/DMA)

  3. CRC计算模块(使用STM32硬件CRC)



注意:实际使用时需要根据开发板调整以下内容:



  1. USART引脚配置(PA9/PA10等)

  2. 系统时钟配置

  3. Flash大小和页地址

  4. 协议细节(超时处理、分包大小等)



建议参考STM32CubeH5官方库中的IAP示例工程,路径:

STM32Cube_FW_H5_Vx.x.x/Projects/STM32H5xx-Nucleo/Applications/IAP

举报

更多回帖

发帖
×
20
完善资料,
赚取积分