完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
设计一款STM32的BootLoader方法如下:
首先要理解BootLoader是什么东西,这个是源自linux上的BootLoader的概念,在linux上,BootLoader是首先执行的程序,BootLoader启动之后初始化CPU、RAM、Flash等设备,然后从Flash中读取Linux程序数据到RAM中去,最后跳转到RAM中Linux的起始地址中去启动Linux系统。除了从Flash中读取系统启动之外,BootLoader还能通过网络NFS协议从服务器上读取Linux并启动。BootLoader还能够更新Linux内核、配置Linux启动信息、测试系统等等。我们要做的STM32的BootLoader也是类似的工作原理,但是没有Linux系统的BootLoader功能那么强大。我们要做的STM32的BootLoader只有两个主要目的: 1、跳转到应用程序并执行。 2、更新应用程序。 为了实现上面的两个基础功能我们创建两个工程一个叫probooter一个叫proapp,前者是BootLoader程序工程,后者是测试用的应用程序。 我们需要规定好BootLoader和Application程序再Flash中的存储结构,我们使用的是64KB Flash的STM32进行测试,BootLoader程序占用前20KB的空间,Application占用后面的43KB的空间,最后1KB的空间不能使用,好像是用来标志Flash锁定状态的,忘了是我之前用的其他MCU上规定的的还是STM32上的规定,反正也不差这个1KB。Flash存储结构如下: 我们需要根据上面的存储结构配置BootLoader工程和Application工程。 BootLoader工程配置如下: ROM起始地址为0x08000000,大小为0x5000。 程序存储基地址为0x08000000,RAM存储基地址为0x20000000。 Jlink下载配置器件的Start地址为0x08000000,size为0x5000。 Application工程配置如下: ROM起始地址为0x08005000,大小为0x10000,这个大小大点没关系,但是BootLoader的大小必须严谨。 最重要的地方!!!这里的R/O Base一定要写0x08005000,表示程序基地址为0x08005000,所有函数、常量数据的地址以这个为基地址。R/W Base还是0x20000000。 Jlink下载配置器件的Start地址为0x08005000,size为0x10000。 配置好了两个工程之后在Application工程中里写测试程序例如: int main(void) { Initialization(); debug(“123456789rn”); int i = 0; while(1) { debug(“%d ”,i++); delay_ms(100); } } 然后通过MDK使用Jlink下载程序,发现无法运行。这是对的,因为程序存放在了0x08005000处,单片机复位的时候从0x08000000(默认向量表存放位置)处获取复位向量,而0x08000000处是空的没有数据(假设一开始单片机被整片擦除了),这样程序就跑飞了。 下面来写BootLoader程序,简单测试一下,将Application程序复制过来,编译下载之后程序可以运行,因为BootLoader程序的存放地址就是放在0x08000000处的,故可以正常运行。接下来可以测试一下从BootLoader程序跳转到Application程序运行。我本来以为可以使用汇编跳转指令“B”来实现跳转: __asm(“B 0x08005004”); 但是发现这个指令不能使用,编译器直接忽略了这个指令了,我也忘了ARM汇编指令,而且这个是Thumb-2指令,算了换一个实现方法:使用函数指针跳转。 首先要获取Application程序的复位中断向量,查看Cortex M3权威指南中写道: 可以看出来复位向量在向量表的第二个字中,那我们读取0x08005004处的一个字的数据就是复位函数的入口地址。 void (*p)(void) = (void (*)(void))(*((int*)0x08005004)); 上面这段程序就能将函数指针p指向Application程序的复位函数。 得到了Application程序的复位函数之后我们还不能急着跳转到Application程序中去,因为我们前面有提示,默认的中断向量表是在0x08000000处,而0x08000000处的中断向量表是BootLoader的,而不是Application的,我们需要重定位中断向量表,这个在权威指南中也有说明: 中断向量表是可以设置的,STM32也实现了Cortex-M的这个功能,可以调用NVIC_SetVectorTable函数: NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x08005000); 修改了中断向量表之后就可以跳转到Application程序的复位函数中去了: p(); 实验结果的确是可以跳转到Application中去执行,我们已经完成了我们要开发的BootLoader的第一个功能:跳转到应用程序并执行。 下面还要实现BootLoader的第二个功能,就是更新Application程序。更新Application程序其实很简单,调用库函数中的Flash操作函数既可以。需要注意的是要先擦除Flash页之后才能向Flash中写数据。并且无论是擦除还是写入数据到Flash,都要先进行Flash解锁操作(FLASH_Unlock),擦除或者写入到Flash完成之后进行Flash锁定操作(FLASH_Lock)。同时在操作Flash之前要清除标志位(FLASH_ClearFlag),防止之前发生的标志位影响下面的操作。 Flash的擦写实现起来很简单,还有一个重点问题是如何获取Application程序数据,假设我们使用一个串口通信,这时候需要使用一个PC端的配套下载软件将程序文件下载到MCU中,BootLoader程序要接收到程序文件并且将程序文件写入到正确的Flash地址中去。 为了方便起见,我使用X-Modem协议,串口通信中这个协议使用的比较多。 当可以正确接收到程序文件并且正确的存放到Flash中去的话就可以跳转到Application程序了,下面是我的实验结果: 执行顺序是线擦除Application空间的Flash,然后调用Xmodem协议将程序文件下载并写入到Flash中去,最后跳转到Application程序的复位函数中执行。 这里要注意的是MDK生成的HEX文件是不能下载的,需要转换成BIN文件,网上有很多HEX转BIN的工具,转换之后得到的BIN文件也不是能够直接下载的,因为生成的BIN文件是从0x08000000处开始的,为什么不是直接从0x08005000处开始呢,因为使用其他的串口下载工具下载的时候需要从头开始下载,而不是从0x08005000处开始下载,我这里是特殊应用,所以需要先删除0x08005000前面的数据,得到一个可以直接存放0x08005000处的文件。测试的时候可以自己使用winhex删除。 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
3730 浏览 0 评论
2018 浏览 2 评论
5158 浏览 2 评论
3355 浏览 0 评论
这是汽车360全景控制器上的主板,请问圆圈中的原件是什么,起什么作用?
2932 浏览 0 评论
浏览过的版块 |
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-4 02:44 , Processed in 0.401874 second(s), Total 42, Slave 35 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号