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

相关推荐
云山工作室1 小时前
基于ZigBee的温室智能控制系统设计(论文+源码)
stm32·单片机·嵌入式硬件·物联网·课程设计
IT_阿水1 小时前
基于STM32的智慧物联网系统板
stm32·物联网·perl
小李做物联网1 小时前
为什么你的老是焊接后通信不成功,物联网焊接注意点
单片机·嵌入式硬件·物联网·课程设计
sam-zy1 小时前
PY32F406K1CU6 FLASH模拟EEPROM
单片机·嵌入式硬件·fpga开发
恒锐丰小吕1 小时前
无锡黑锋 HF6306 高性能超低静态电流低压差稳压器技术解析
嵌入式硬件·硬件工程
云山工作室1 小时前
血糖浓度测试仪设计(论文+源码)
stm32·单片机·嵌入式硬件·毕业设计·毕设
sam-zy2 小时前
PY32F403K1CU6定时器1~6基本配置,1ms中断,每隔1秒打印
单片机·嵌入式硬件·fpga开发
雨疏风骤12402 小时前
【FreeRTOS】任务、任务状态
开发语言·stm32·c#·rtos
三佛科技-134163842122 小时前
脉冲清洗机MCU方案开发设计
单片机·嵌入式硬件·智能家居·pcb工艺
Saniffer_SH3 小时前
【每日一题】PCIe 里的 RefClk (Reference Clock) 到底是干什么的?
服务器·驱动开发·单片机·嵌入式硬件·fpga开发·计算机外设·硬件架构