STM32H743-ARM例程39-SD_IAP

目录

实验平台

硬件:银杏科技GT7000双核心开发板-ARM-STM32H743XIH6,银杏科技iToolXE仿真器

软件:最新版本STM32CubeH7固件库STM32CubeMX v6.10.0,开发板环境MDK v5.35TCP&UDP测试工具,串口工具putty

网盘资料包:链接: https://pan.baidu.com/s/1Y3nwaY4SMxfoUsdqPm2R3w?pwd=inba 提取码: inba

IAP(SD卡存储介质)

在上一章节我们介绍了IAP相关知识,并且利用UART串口传输APP文件,本章我们采用SD卡来传输APP文件。

SD卡相关知识可以参考文章STM32H743-ARM例程13-SDIO

STM32CubeMX生成工程

我们参考前面章节STM32H743-结合CubeMX新建HAL库MDK工程,打开CubeMX软件,重复步骤不再展示,我们来看配置SDMMC部分如下图所示:
配置SDMMC1

配置FATFS

实验代码

本章实验包含两个程序,APP和bootloader,APP程序可以参考STM32H743-ARM例程34-BootROM,把启动地址修改为0x8040000

c 复制代码
#define FLASH_ADDRESS     (uint32_t)0x8040000

bootloader程序:

1. 主函数

c 复制代码
int main(void)
{
  /* USER CODE BEGIN 1 */
    int cnt;
    int k;
    unsigned char buffer[6144];
    unsigned char * p;
    unsigned long int ncounter = 0;
    unsigned int counter;
    
  /* Enable the CPU Cache */
    CPU_CACHE_Enable();
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI5_Init();
  MX_USART6_UART_Init();
  MX_SDMMC1_SD_Init();
  MX_FATFS_Init();
  /* USER CODE BEGIN 2 */
    uart6.initialize(115200);   
    uart6.printf("\x0c"); 
    uart6.printf("\033[1;32;40m");
    uart6.printf("Hello,I am GT7000\r\n");
    LED_ON;
  /* USER CODE END 2 */
    if(ARM_KEY4_STATE == KEY_UP){     //按键松开状态直接跳向应用程序
        goto start;
    }
    
    //SD卡初始化
    if(BSP_SD_Init() != MSD_OK){
        led_trade();
    }

    res = f_mount(&fatfs,"0:",1);
    //判断是否成功
    if(res != RES_OK){
        led_trade();
    }else{
        uart6.printf("f_mount is ok!\r\n");
    }
    res = f_open(&fil,"0:/app.bin",FA_READ); //打开app.bin文件
    
    //判断文件打开是否成功
    if(res != RES_OK){
        led_trade();
    }else{
        uart6.printf("f_open is ok!\r\n");
    }
    res = f_lseek(&fil,0);                   //将指针移动到第一个位置
    
    //指针是否移动成功
    if(res != RES_OK){
        led_trade();
        uart6.printf("f_lseek is error!\r\n");
    }else{
        uart6.printf("f_lseek is ok!\r\n");
    }
    
    //获取文件信息
    f_stat("0:/app.bin",&finfo);
    
    while(ncounter < finfo.fsize)
    {
        //读取6144Byte数据
        res = f_read(&fil,buffer,6144,&counter);  //读文件
        if(res != RES_OK){
            uart6.printf("Read APP error!\r\n");
            led_trade();
        }
        uart6.printf("%d\r\n",counter);
        p =(unsigned char*)buffer;  
        uart6.printf("Read APP ...!\r\n");      
        iap_write_appbin(APPLICATION_ADDRESS,p ,6144);
        ncounter +=6144;    
    }

    uart6.printf("Load APP finish!\r\n");
    
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  start:
    
        if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x24000000){ 
            
            //跳转至用户程序
            JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
            JumpToApplication = (pFunction) JumpAddress;
            
            //初始化用户程序的堆栈指针
            __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
            
            //跳转至应用程序
            JumpToApplication();
        }
        else{               
            led_trade();
        }
  /* USER CODE END 3 */
}

2. iap_write_appbin函数

c 复制代码
void iap_write_appbin(uint32_t appxaddr,uint8_t *appbuf,uint32_t appsize)
{
    uint32_t t;
    uint16_t i=0;
    uint32_t temp;
    uint32_t fwaddr=appxaddr;//当前写入的地址
    uint8_t *dfu=appbuf;
    
    for(t=0;t<appsize;t+=4)
    {                          
        temp=(uint32_t)dfu[3]<<24;   
        temp|=(uint32_t)dfu[2]<<16;    
        temp|=(uint32_t)dfu[1]<<8;
        temp|=(uint32_t)dfu[0];   
        dfu+=4;//偏移4个字节
        iapbuf[i++]=temp;       
        if(i==FLASH_SECTOR)
        {
            i=0; 
            STMFLASH_Write(fwaddr,iapbuf,FLASH_SECTOR);
            fwaddr+=FLASH_SECTOR*4;//偏移2048  512*4=2048
        }
    } 
    if(i)STMFLASH_Write(fwaddr,iapbuf,i);//将最后的一些内容字节写进去.  
}

实验现象

我们将app.bin 文件拷贝到SD卡中,运行程序,按下 ARM-KEY 将烧写 Bootloader(IAP)程序烧写程序到GT7000上,通过读取SD卡中的app.bin文件,重新上电 ARM-LED 灯闪烁,即 ARM 更新升级成功。

相关推荐
hollq2 小时前
STM32F103RCT6+STM32CubeMX+keil5(MDK-ARM)+Flymcu完成轮询方式检测按键
arm开发·stm32·嵌入式硬件
d111111111d4 小时前
STM32外设学习--DMA直接存储器读取(AD扫描程序,DMA搬运)--学习笔记。
笔记·stm32·单片机·嵌入式硬件·学习
EVERSPIN4 小时前
基于灵动MCU微控制器的呼吸机主控单片机方案
单片机·嵌入式硬件·mcu微控制器
清风6666668 小时前
基于单片机的多模式智能洗衣机设计
数据库·单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
无人装备硬件开发爱好者8 小时前
《STM32 江湖 SPI 双绝:硬件外设与软件模拟的深度解析》
嵌入式硬件·移植·软件模拟spi
点灯小铭8 小时前
基于单片机的预约保温型智能电饭锅控制系统设计与实现
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
奋斗的牛马9 小时前
硬件工程师-基础知识电阻(四)
单片机·嵌入式硬件·学习·fpga开发
axuan1265110 小时前
15.【NXP 号令者RT1052】开发——实战-XBAR
单片机·嵌入式硬件·mcu
xiaohai@Linux10 小时前
STM32上使用HAL库完美实现驱动MAX98357声卡模块(I2S+DMA+音频环形缓冲区)
stm32·单片机·嵌入式硬件·音视频