STM32F105实现U盘IAP升级程序
1、理论分析
理论依据很重要,这里稍微介绍一下原理和数据的操作过程。实际实现U盘的IAP升级一共分为两个部分,一部分是bootloader程序,这部分需要使用烧录器或者串口烧写进芯片。另一部分是用户的APP程序,这部分是真正的设备需要执行的程序。实际操作过程就是芯片连接U盘后从U盘读取一部分bin文件的数据到RAM再写入到芯片的flash用户app区,然后循环这个写入过程直到将整个bin文件写入到芯片flash中。然后执行一条指令跳转到用户app程序区开始执行。另外用户app区执行时在systemInit初始化完成后需要将中断表偏移一个地址。实现U盘升级程序需要移植两部分代码,一个是U盘驱动代码,一个是FAT文件系统代码。同时将U盘格式化为FAT32格式,4k对齐。
2、bootloader关键代码
bootloader部分的关键代码如下,U盘的状态机和读取文件并写入到芯片flash的过程。IAP部分代码参考了原子哥的串口IAP代码,但发现直接使用跳转时无法执行。经过测试跳转之前必须要增加__ASM(“CPSID I”);这句关闭中断。但是很奇怪我曾经做过一个串口IAP的bootloader,不加这句是完全没问题的。这个很是让人费解啊。
//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(u32 appxaddr)
{if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法.{ __ASM("CPSID I");jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址) __set_MSP(*(__IO uint32_t*) appxaddr);//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)jump2app(); //跳转到APP.}
} int USBH_USR_Application(void)
{UINT Len = 0;u16 FramesLen = 0;//最后帧长度char FilePath[] = "0:/PROGRAM.bin";if(HCD_IsDeviceConnected(&USB_OTG_Core) != 0)//判断U盘连接{switch(UDiskState){case FileSysInit: //文件系统初始化{if(f_mount(&fatfs, "", 0)!=FR_OK)//判断是否挂载{return 1;}UDiskState = OpenFile;break;}case OpenFile: //打开文件{f_mount(&fatfs, "", 0);//挂载if(f_open(&file,FilePath,FA_OPEN_EXISTING|FA_READ) != FR_OK )//打开文件,如果不存在则失败{f_close(&file); //关闭文件f_mount(NULL, "", 0); //卸载USBDiskSig = USBDiskBreak;RunNumber = 0;return 1;}USBDiskSig = USBDiskLink;//U盘已连接,确认能够打开文件以后才认为U盘有效连接FileSize = f_size(&file);//获取文件大小WriteInteger = FileSize/WriteUSBLen;WriteRemSIG = FileSize%WriteUSBLen;Write_Count = 0;//清空次数UDiskState = UDiskWriteData;break;}case UDiskWriteData://读取数据并执行IAP{if((WriteInteger > 0)&&(Write_Count < WriteInteger)){if(f_read(&file,FileReadBuf,WriteUSBLen,&Len) != FR_OK)//读取指定长度的数据到RAM{f_close(&file);f_mount(NULL, "", 0);USBDiskSig = USBDiskBreak;RunNumber = 0;return 1;}iap_write_appbin(((WriteUSBLen*Write_Count)+FLASH_APP1_ADDR),FileReadBuf,WriteUSBLen);//更新FLASH代码Write_Count++;}else{if(WriteRemSIG != 0)//有剩余数据{FramesLen = FileSize-(Write_Count*WriteUSBLen);//得到最后一次写入的长度if(f_read(&file,FileReadBuf,FramesLen,&Len) != FR_OK)//读取指定长度的数据到RAM{f_close(&file);f_mount(NULL, "", 0);USBDiskSig = USBDiskBreak;RunNumber = 0;return 1;}iap_write_appbin(((WriteUSBLen*Write_Count)+FLASH_APP1_ADDR),FileReadBuf,FramesLen);//更新FLASH代码}f_close(&file);//关闭文件f_mount(NULL, "", 0);//断开连接Write_Count = 0;UDiskState = FileSysInit;if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.{
// RCC_DeInit();//关闭外设
// __set_PRIMASK(1); //关闭总中断iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码}else //非FLASH应用程序,无法执行!{USBDiskSig = USBDiskBreak;RunNumber = 0;}}}default:break;}}else{f_close(&file);f_mount(NULL, "", 0);return 1;}return 0;
}
3、用户APP程序关键代码
此部分是用户APP的初始化代码,代码中必须要添加中断向量表偏移和打开中断。偏移量需要根据自己定义的用户APP地址修改。本人程序使用IAR编译器编译,所以用户APP程序配置如下图:
void ALL_Init(void)
{SystemInit(); //系统时钟源配置 NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x6400);//设置中断向量表偏移__ASM("CPSIE I");//打开中断ChipDeInit();//芯片外设复位NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
}
实际这里配置就是修改了stm32f105xC.icf文件中的以下部分:
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08006400;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08006400;
define symbol __ICFEDIT_region_ROM_end__ = 0x0803FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
整个程序的源码在我的资源中可以找到地址如下。
https://download.csdn.net/download/u010552215/12016457
STM32F105实现U盘IAP升级程序相关推荐
- 完成MSP430的IAP升级程序(总结)
这几天测试写好的IAP升级程序,真是一个糟,能将程序下载进去,但无法运行. 经过各种测试,修改终于找到了问题的原因,现在大致总结下我在写IAP程序的时候 遇到的问题和解决方案.首先要实现单片机的IAP ...
- stm32 模拟U盘IAP升级 与 FAT16文件系统
如果用的MCU有USB接口,那么使用模拟U盘升级程序,不失为一个好办法,因为 第1,模拟U盘,不需要驱动,也不需要上位机,现场操作非常方便, 第2,USB传输速度快,升级过程耗时少,且可靠. 这项技术 ...
- 基于STM32的IAP升级程序
基于STM32的IAP升级程序 IAP介绍 功能设计 硬件设计 软件设计 软件设计流程如下 完整程序 具体实现 设计功能程序 IAP实现程序 主程序 后续 IAP介绍 IAP(In Applicati ...
- STM32F103 通过SD卡IAP升级程序,带MD5校验,(带源码)可在实际项目中使用
一.将APP程序从SD卡搬运到MCU中 首先从sd卡通过FAFTS文件操作系统打开程序文件,然后记录下复制开始地址和程序文件大小 fileOperionResult = f_open(&upd ...
- 电子产品如何使用IAP方式升级程序
目录 1.ICP.ISP和IAP的概念 2.IAP升级程序的原理 3.IAP升级程序的流程 4.IAR环境下IAP的实现 4.1.BootLoader程序设计 4.2.User Application ...
- 关于STM32单片机IAP升级中if(((*(__IO uint32_t*)ulAddr_App) 0x2FFE0000) == 0x20000000)语句的理解
没有标题 初见if(((*(__IO uint32_t*)ulAddr_App) & 0x2FFE0000) == 0x20000000) 语句理解 语句功能 为什么ulAddr_App里存的 ...
- 现场升级方案:LPC1788采用U盘方式进行程序IAP升级功能的实现
现场升级方案:LPC1788采用U盘方式进行程序IAP升级功能的实现 闲来无事,总结一下前段时间做过的U盘升级项目.一个新手的成长之路在于善于总结,生活也是一样扯远了,我准备了两个软件环境,一个带操作 ...
- RT-thread应用讲解——通过U盘升级程序固件
RT-thread应用讲解--通过U盘升级程序固件 目录 RT-thread应用讲解--通过U盘升级程序固件 前言 一.挂载U盘 二.使能OTA 三.U盘升级代码 四.运行测试 五.结束语 前言 我前 ...
- 21.国民技术N32G45X例程之-U盘模式IAP升级固件
21.国民技术N32G45X例程之-U盘模式IAP升级固件 文章目录 前言 一.准备工作 1.国民技术N32G45X提供的库 2.下载本作者原创BIN文件合成软件 3.为什么要合成BIN文件? 二.U ...
最新文章
- Yii2 中cookie的用法(2)
- poj1236-Tarjan算法
- RSA攻击手法及相应例题解析
- 血管分割技术文献综述
- 写给小白的Python之006:数据类型之列表
- Please use torch.load with map_location=torch.device(‘cpu‘),If you are running on a CPU-only machine
- oracle归档切换,oracle 切换归档方式
- matlab怎么画map图,用MATLAB自带的worldmap及相关函数画地图
- 改命术:怎么赚50万以上的问题
- 形参和实参的储存单元是否一致?
- 【English】十大词性之感叹词(感叹句)
- Ubuntu18.04录屏并生成gif图片
- 逻辑回归分类器(linear_model.LogisticRegression)
- 华为路由器和交换机的简单命令
- swift新手进阶30天一 自定义上图片下文字的UIButton的几种方式
- cmd的发送 mmc_mmc/sd 卡介绍
- Teamcenter之RCP的简单创建与运行
- 《数据结构》(一)时间复杂度和空间复杂度(超硬核八千字)
- 微信手气红包算法 php,PHP实现微信/QQ手气红包,随机算法分享
- 好用的录音转文字方法