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 更新升级成功。

相关推荐
jl48638214 分钟前
【选型指南】气密性检测仪显示屏如何兼顾IP65防护、-40℃~85℃宽温与快速交付?
大数据·人工智能·stm32·单片机·物联网
恶魔泡泡糖13 分钟前
51单片机I2C-EEPROM
c语言·单片机·嵌入式硬件·51单片机
代码游侠20 分钟前
学习笔记——Linux字符设备驱动
linux·运维·arm开发·嵌入式硬件·学习·架构
来自晴朗的明天25 分钟前
10、LM2904 单电源反向比例运算放大器电路
单片机·嵌入式硬件·硬件工程
1+α1 小时前
工业通讯中的“顶梁柱”——RS485科普
c语言·stm32·嵌入式硬件·网络协议
逐步前行1 小时前
STM32_芯片介绍
stm32·单片机·嵌入式硬件
ting_zh1 小时前
使用ARM DSP库去音频直流偏置
stm32·dsp·fir·iir·直流偏置
听风吹雨yu2 小时前
STM32F407-LWIP-Onvif协议控制海康相机
stm32·嵌入式硬件·数码相机
1+α2 小时前
汽车里的“神经网络”——CAN总线科普
c语言·stm32·嵌入式硬件·信息与通信
Amrzs_hp10 小时前
stm32温度采集
stm32·单片机·嵌入式硬件