当前位置: 首页 > news >正文

STM32H743-ARM例程40-U_DISK_IAP

目录

  • 实验平台
  • IAP(U盘存储介质)
  • 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(U盘存储介质)

前面章节我们介绍了IAP相关知识,并且利用UART串口和SD卡传输APP文件,本章我们采用U盘来传输APP文件。
  U盘相关知识可以参考文章STM32H743-ARM例程24-USB_MSC

STM32CubeMX生成工程

我们参考前面章节STM32H743-结合CubeMX新建HAL库MDK工程,打开CubeMX软件,重复步骤不再展示,我们来看配置USB部分如下图所示:
配置USB
在这里插入图片描述
在这里插入图片描述配置FATFAS

在这里插入图片描述

实验代码

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

bootloader程序

1. 主函数

int main(void)
{/* USER CODE BEGIN 1 *//* 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_USART6_UART_Init();MX_FATFS_Init();MX_USB_HOST_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\r\n"); LED_ON;/* USER CODE END 2 */if(ARM_KEY4_STATE == KEY_UP){                //按键松开状态直接跳向应用程序goto start;}/* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE */MX_USB_HOST_Process();/* 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. USBH_UserProcess 函数

static void USBH_UserProcess  (USBH_HandleTypeDef *phost, uint8_t id)
{/* USER CODE BEGIN CALL_BACK_1 */static FRESULT res;unsigned char buffer[6144];unsigned char * p;unsigned long int ncounter = 0;unsigned int counter;switch(id){case HOST_USER_SELECT_CONFIGURATION:break;case HOST_USER_DISCONNECTION:Appli_state = APPLICATION_DISCONNECT;break;case HOST_USER_CLASS_ACTIVE:Appli_state = APPLICATION_READY;//f_mountres = f_mount(&fatfs,"0:",0);if(res != RES_OK){USBH_UsrLog("\r\nf_mount error!");led_trade();}else{USBH_UsrLog("\r\nf_mount successful!");}res = f_open(&fil,"0:/app.bin",FA_READ);               //打开app.bin文件if(res != RES_OK){USBH_UsrLog("\r\nf_open error!");led_trade();}else{USBH_UsrLog("\r\nf_open successful!");}//f_lseekres = f_lseek(&fil,0);if(res != RES_OK){USBH_UsrLog("\r\nf_lseek error!");led_trade();}else{USBH_UsrLog("\r\nf_lseek successful!");}//获取文件信息f_stat("0:/app.bin",&finfo);while(ncounter < finfo.fsize){//读取6144Byte数据res = f_read(&fil,buffer,6144,&counter);             //读文件if(res != RES_OK){led_trade();}//写入EXT FLASH中p =(unsigned char*)buffer;  USBH_UsrLog("Read APP ...!\r\n");   iap_write_appbin(APPLICATION_ADDRESS,p ,6144);ncounter = ncounter + 6144;}   USBH_UsrLog("Load APP finish!\r\n");break;case HOST_USER_CONNECTION:Appli_state = APPLICATION_START;break;default:break;}/* USER CODE END CALL_BACK_1 */
}

3.flash相关操作函数

#include "stmflash.h"
#include "uart6.h"
//读取指定地址的字(32位数据) 
//faddr:读地址 
//返回值:对应数据.
uint32_t STMFLASH_ReadWord(uint32_t faddr)
{return *(__IO uint32_t *)faddr; 
}//获取某个地址所在的flash扇区,仅用于BANK1!!
//addr:flash地址
//返回值:0~11,即addr所在的扇区
uint16_t STMFLASH_GetFlashSector(uint32_t addr)
{if(addr >= FLASH_BANK2_ADDR) //BANK2{if(addr<ADDR_FLASH_SECTOR_1_BANK2)return FLASH_SECTOR_0;else if(addr<ADDR_FLASH_SECTOR_2_BANK2)return FLASH_SECTOR_1;else if(addr<ADDR_FLASH_SECTOR_3_BANK2)return FLASH_SECTOR_2;else if(addr<ADDR_FLASH_SECTOR_4_BANK2)return FLASH_SECTOR_3;else if(addr<ADDR_FLASH_SECTOR_5_BANK2)return FLASH_SECTOR_4;else if(addr<ADDR_FLASH_SECTOR_6_BANK2)return FLASH_SECTOR_5;else if(addr<ADDR_FLASH_SECTOR_7_BANK2)return FLASH_SECTOR_6;}else	//BANK1{	if(addr<ADDR_FLASH_SECTOR_1_BANK1)return FLASH_SECTOR_0;else if(addr<ADDR_FLASH_SECTOR_2_BANK1)return FLASH_SECTOR_1;else if(addr<ADDR_FLASH_SECTOR_3_BANK1)return FLASH_SECTOR_2;else if(addr<ADDR_FLASH_SECTOR_4_BANK1)return FLASH_SECTOR_3;else if(addr<ADDR_FLASH_SECTOR_5_BANK1)return FLASH_SECTOR_4;else if(addr<ADDR_FLASH_SECTOR_6_BANK1)return FLASH_SECTOR_5;else if(addr<ADDR_FLASH_SECTOR_7_BANK1)return FLASH_SECTOR_6;}return FLASH_SECTOR_7;	}//从指定地址开始写入指定长度的数据
//特别注意:因为STM32H7的扇区实在太大,没办法本地保存扇区数据,所以本函数
//         写地址如果非0XFF,那么会先擦除整个扇区且不保存扇区数据.所以
//         写非0XFF的地址,将导致整个扇区数据丢失.建议写之前确保扇区里
//         没有重要数据,最好是整个扇区先擦除了,然后慢慢往后写. 
//该函数对OTP区域也有效!可以用来写OTP区!
//OTP区域地址范围:0X1FF0F000~0X1FF0F41F
//WriteAddr:起始地址(此地址必须为4的倍数!!)
//pBuffer:数据指针
//NumToWrite:字(32位)数(就是要写入的32位数据的个数.) 
void STMFLASH_Write(uint32_t WriteAddr,uint32_t *pBuffer,uint32_t NumToWrite)	
{ FLASH_EraseInitTypeDef FlashEraseInit;HAL_StatusTypeDef FlashStatus=HAL_OK;uint32_t SectorError=0;uint32_t addrx=0;uint32_t endaddr=0;	uint32_t bankFlag = 1;if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return;	//非法地址
//	bankFlag = WriteAddr >= FLASH_BANK2_ADDR ? FLASH_BANK_2:FLASH_BANK_1;HAL_FLASH_Unlock();             //解锁	addrx=WriteAddr;				//写入的起始地址endaddr=WriteAddr+NumToWrite*4;	//写入的结束地址if(addrx<0X1FF00000){while(addrx<endaddr)		//扫清一切障碍.(对非FFFFFFFF的地方,先擦除){if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区{   FlashEraseInit.Banks=bankFlag;							//操作BANK1或者2FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS;       //擦除类型,扇区擦除 FlashEraseInit.Sector=STMFLASH_GetFlashSector(addrx);   //要擦除的扇区FlashEraseInit.NbSectors=1;                             //一次只擦除一个扇区FlashEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3;      //电压范围,VCC=2.7~3.6V之间!!if(HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError)!=HAL_OK) {uart6.printf("flash set operation err...\r\n");break;//发生错误了	}SCB_CleanInvalidateDCache();                            //清除无效的D-Cache}else addrx+=4;FLASH_WaitForLastOperation(FLASH_WAITETIME,bankFlag);    //等待上次操作完成}}FlashStatus=FLASH_WaitForLastOperation(FLASH_WAITETIME,bankFlag);       //等待上次操作完成if(FlashStatus==HAL_OK){while(WriteAddr<endaddr)//写数据{if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD,WriteAddr,(uint64_t)pBuffer)!=HAL_OK)//写入数据{ uart6.printf("flash write operation err...\r\n");break;	//写入异常}WriteAddr+=32;pBuffer+=8;}}HAL_FLASH_Lock();           //上锁
}//从指定地址开始读出指定长度的数据
//ReadAddr:起始地址
//pBuffer:数据指针
//NumToRead:字(32位)数
void STMFLASH_Read(uint32_t ReadAddr,uint32_t *pBuffer,uint32_t NumToRead)   	
{uint32_t i;for(i=0;i<NumToRead;i++){pBuffer[i]=STMFLASH_ReadWord(ReadAddr);//读取4个字节.ReadAddr+=4;//偏移4个字节.	}
}#define FLASH_SECTOR	256*128   //256*4 就是1KB,*128就是128K
uint32_t iapbuf[FLASH_SECTOR]; 	//1K*128字节缓存 
uint8_t binBuf[1024*200];
//appxaddr:应用程序的起始地址
//appbuf:应用程序CODE.
//appsize:应用程序大小(字节).
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 文件拷贝到U盘中,运行程序,按下 ARM-KEY 将烧写 Bootloader(IAP)程序烧写程序到GT7000上,通过读取U盘中的app.bin文件,重新上电 ARM-LED 灯闪烁,即 ARM 更新升级成功。

注:GT7000上需要用tpye-c转接器连接U盘和USB-Hs接口。

http://www.dtcms.com/a/582523.html

相关文章:

  • 网站开发 实时更新做网站做的好的公司有哪些
  • 专门做酒店设计的网站源码屋整站源码
  • Memory MCP(记忆服务器)
  • Java基础 | 基本类型与引用类型使用规范
  • 香港1核2G云服务器当网站服务器够用不?
  • 用Python来学微积分36-牛顿 - 莱布尼茨公式的深度解析
  • 网站建设规章制度软件app开发需要多少钱
  • 网站建设外出考察信息家在深圳房网论坛首页
  • 测试开发工程师面经准备(sxf)
  • 2026商业航天展,中国商业航天规模化发展的加速器
  • 网站建设与推广范文防下载 的视频网站 怎么做
  • TrueNas Scale配置immich集成GPU硬件加速,用于智能模型,人脸识别,OCR文本识别加速
  • 旅游网站建设规划报告怎么写个人做外贸网站违法吗
  • FLUX1. 代码解读
  • 朔州路桥建设有限责任公司网站新乡发布最新通告
  • 基于黏菌算法的路径规划
  • Java--HTTP(上)
  • 【软考架构】软件测试-白盒测试方法中的几种测试准则(覆盖准则)
  • 网站建设类公司排名中国建筑人才网怎么样
  • Dify 迁移后常见问题解决方案与使用腾讯云cos上传文件 FILES_URL缺失
  • 郑州网站建设培训网站域名备案认证
  • 专业制作网站公司哪家好软件开发项目总结
  • 切换海外动态IP的方法
  • 设计业务网站外贸自建站类型
  • 网站建设在哪里发布网络优化工程师工资
  • Linux环境下的C语言编程(十七)
  • JAVA算法练习题day64
  • 小华HC32F460串口性能问题与处理思路
  • Java_Hashtable使用及扩容
  • Django序列化器