STM32H743-ARM例程39-SD_IAP
目录
- 实验平台
- IAP(SD卡存储介质)
- STM32CubeMX生成工程
- 实验代码
- 实验现象
实验平台
硬件:银杏科技GT7000双核心开发板-ARM-STM32H743XIH6,银杏科技iToolXE仿真器
软件:最新版本STM32CubeH7固件库,STM32CubeMX v6.10.0,开发板环境MDK v5.35,TCP&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
#define FLASH_ADDRESS (uint32_t)0x8040000
bootloader程序:
1. 主函数
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函数
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 更新升级成功。
