完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
硬件:stm32f103cbt6
软件:STM32F10x_StdPeriph_Lib_V3.5.0 1 预备知识 基于标准外设库(STM32F10x_StdPeriph_Lib_V3.5.0)的IAP升级相关资料可以参考 IAP ST官方资料汇总。 STM32升级的三种方式:IAP,ICP,ISP;具体有什么区别可以自行Google; 本文需要实现STM32的Bootloader(后面Bootloader/IAP不加以区分),文件传输基于ymodem协议通过串口进行传输,这里参考了ST官方的DEMO —— STM32F10xxx in-application programming using the USART AN2557,在此基础上做了部分修改,增加了延时启动的功能,最终可以实现想要的效果。 整体架构分为两个部分;Bootloader和Application,具体如下图所示; 由上图可知,STM32内置的Flash被分成了两个部分,分别用来保存Bootloader和Application程序,这里有两个有两个FLASH起始地址0x8000000和0x8003000; 为什么是0x8000000这个地址呢?而不是其他地址呢? 这是由M3内核硬件上的设计就已经这么做了,人为设计好了,可以参考M3内核权威指南; 0x8003000这个地址则是由我们自己来规定的,这个地址的范围必须在0x8000000和0x8020000之间,所以一般根据Bootloader程序的最终大小,在这范围之间取一个比较合理的值即可。如下图所示; 注意:本文使用的stm32f103cb,属于中等大小Flash,128K = 0x20000,所以地址范围是0x8000000~0x8020000;2 Bootloader 2.1 启动流程 这里的Bootloader即为IAP程序,它具备以下几个功能;
由该图可以知道程序正常启动流程;以下表格一四个向量是必须的,从图中也可以了解到; [tr]地址异常编号值[/tr]
在主函数中可以看到如下程序;甚是不解和迷茫;沉思一会儿才恍然大悟; /* Test if user code is programmed starting from address "ApplicationAddress" */ if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000) { /* Jump to user application */ JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4); Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) ApplicationAddress); Jump_To_Application(); } 本文中ApplicationAddress = 0x8000000; 那么*(__IO uint32_t*)ApplicationAddress)则是这个地址中所保存的值,由表格一可以知道,程序起始地址的第一个向量地址保存的栈顶的,因此,地址0x800_0000和0x800_3000中保存的值都是指向栈顶,如下图所示; 栈是在RAM上分配,因此RAM的有效范围要做一个检测,栈顶地址和0x2FFE0000做与运算可以推算出,要校验的RAM范围是0x2000_0000—0x2001_FFFF,所以RAM大小是128K,官方DEMO默认使用HD高密度系列,所以是128K,本文是CBT6,20K的RAM,则需要改成0x2FFFB000: /* Test if user code is programmed starting from address "ApplicationAddress" */ if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFFB000 ) == 0x20000000) { /* Jump to user application */ JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4); Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) ApplicationAddress); Jump_To_Application(); } 计算方式: 20K = 20*1024= 0x5000, 0x2FFF_FFFF - (0x5000 - 1) = 0x2FFF_B000 2.3 Keil工程IAP的相关设置 2.3.1 修改Flash地址 设置程序起始地址0x800000和大小0x3000; 设置Debug工具烧写时Flash的起始地址0x800000和大小0x3000; 2.3.2 使用自己的链接脚本 该项为选配,与上述配置二选一即可,如果仍然想使用自己的链接脚本,在Option-->Linker下将Use Memort Layout from Target Dialog选项勾选去掉,然后选择自己的链接脚本,如下图进行配置; 参考ARMCC的链接脚本编写方法,可以自己编写的srt文件,参考ARM分散加载技术; ; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x08000000 0x00003000 { ; load region size_region ER_IROM1 0x08000000 0x00003000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) .ANY (+XO) } RW_IRAM1 0x20000000 0x00005000 { ; RW data .ANY (+RW +ZI) } } 如果用的gcc工具链,则要编写gcc的链接脚本ld文件; 2.3.3 下载固件 配置完成之后进行Build,然后通过SWD的方式先下载固件,进行实验; 3 Application 3.1 启动流程 用户的Application需要在IAP启动完成后,才能正常执行;具体启动过程,比正常应用的启动多了一个IAP启动的过程,并最终通过IAP引导进入Application;具体如下图所示; 白色部分为IAP; 灰色部分为Application; 图中的0x8000004+N+M 就等于0x8003004,所以Application的启动地址需要进行修改,另外还有其他需要修改的地方,下面会详细指出。 3.2 IAP中的引导部分 参考IAP中的引导程序; define ApplicationAddress 0x8003000 /* Jump to user application */ JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4); Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) ApplicationAddress); Jump_To_Application(); 可以发现的是SP的值为0x8003000,指向栈顶,而0x8003004则为ResetHander的地址,系统会进行复位,然后开始Application正常启动流程; 3.3 关于 VTOR VTOR是向量表偏移量寄存器,它将用来告诉CPU,从Flash的哪个地方去取向量地址,第一个要取的是MSP的值,然后就是复位向量地址ResetHandler,如果这里设置错误,那么程序是无法正常启动的。下面是标准库中与其相关的代码片段; __IO uint32_t VTOR; /*!< Offset: 0x08 Vector Table Offset Register */ /*!< FLASH base address in the alias region */ #define FLASH_BASE ((uint32_t)0x08000000) /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ #define VECT_TAB_OFFSET 0x0 /* Vector Table Relocation in Internal FLASH. */ SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; 所以Application中还需要修改VECT_TAB_OFFSET的值为0x3000; 参考M3权威指南: 如果需要动态地更改向量表,则对于任何器件来说,向量表的起始处都必须包含以下向量:3.4 Keil工程设置 3.4.1 Flash地址设置 与IAP工程设置类似,这里的Application是另一个Keil工程,同样的需要对Flash进行设置,如下图所示; 这里Application工程的Flash地址偏移了0x3000,正是之前Bootloader所占用的Flash空间大小,这里和VTOR的设置也必须保持一致; 3.4.2 hex2bin 配置工程最终生成hex文件,如下图所示; 最终我们需要使用的是bin文件,所以,这里需要使用将hex文件转成bin文件,本文使用hex2bin的工具;配置工程运行之后执行转换文件的脚本; create_bin.bat echo %cd% set ROOT_PATH=..... set SRC=%ROOT_PATH%..ProjectSTM32F10x_StdPeriph_TemplateMDK-ARMSTM3210B-EVAL*.hex set TOOL=%ROOT_PATH%..Binhex2bin.exe if exist %SRC% (%TOOL% %SRC%) exit copy_firmware.bat echo %cd% set ROOT_PATH=..... set HEX_FILE=%ROOT_PATH%..ProjectSTM32F10x_StdPeriph_TemplateMDK-ARMSTM3210B-EVAL*.hex set BIN_FILE=%ROOT_PATH%..ProjectSTM32F10x_StdPeriph_TemplateMDK-ARMSTM3210B-EVAL*.bin set DST_DIR=%ROOT_PATH%..Firmware if exist %HEX_FILE% (XCOPY /Y /S /F %HEX_FILE% %DST_DIR%) if exist %BIN_FILE% (XCOPY /Y /S /F %BIN_FILE% %DST_DIR%) exit 最终在Build之后,可以在Firmware中找到STM321-APP.bin,这个文件就是要用来IAP程序进行串口下载的程序。 3.4.3 用户程序串口下载测试 SecureCRT软件支持ymodem协议,可以安装该软件,打开串口连接,设置ymodem的协议; 打开菜单选项:Options–Session Options,配置如下; 为了便于测试,在STM32F1-APP进行串口发送以下信息,便于观察APP是否正常启动; usart_printf(" rn STM32F1-APP start running*******************"); 打开连接的串口,并根据终端提示进行操作,最终下载固件STM32F1-APP成功,并成功运行; |
||
|
||
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1617 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1543 浏览 1 评论
977 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1595 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
645浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
516浏览 3评论
532浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
505浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 11:24 , Processed in 1.018322 second(s), Total 76, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号