(一)编写Bootloader程序应该注意的一些问题

一、简介

 在嵌入式设备中通常有一个、两个或者更多的程序,它们之间相互独立但会瓜分同一个FLASH的存储空间(当然也可能存放在其他可执行的存储设备上),且每一个程序占用的地址是连续的。对于只有一个程序的单片机,上电后会直接被执行,通常被称作应用程序,然而当一个单片机的FLASH中存有多个程序,就必须有一个引导加载程序来引导单片机去执行对应的应用程序,而这个引导程序就是我们常说的BootLoader程序。BootLoader(中译:引导加载)程序在嵌入式系统上通常作为上电后执行的第一段代码,它的作用是帮助单片机引导到应用程序那块存储区域并执行应用程序。

二、说明

以SMT32单片机来介绍,通常一个程序的执行流程如下图1所示。

​图1

如果我们要加入BootLoader程序,程序的执行流程将是如下图2所示,BootLoader程序首先会被执行,照正常的流程执行到最后会跳转到应用程序的起始地址,并开始执行。其中阴影的部分是应用程序执行的过程。

​图2

 下面这段代码就是跳转到应用程序,有的人会从别的地方看到这样一段类似的代码:

if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)//检查栈顶地址是否合法

上面这段代码的判断和我的判断是一个意思,但是由于我的应用程序的栈顶前四个字节的值是0x20030000,所以我进行了一些改动,如果你确定自己的BootLoader程序本身没问题,但是就是无法跳转的应用程序,一定要检查一下此处的判断是否正确,网上大多的写法和官网的写法未必符合自己的要求这点必须要注意。

    	/* Test if user code is programmed starting from FLASH_USER_START_ADDR address
    	 * 注意:这里的判断是根据我自己的单片机的栈顶值设定的,如果该程序使用使用在其他单片机务必写成当前使用单片机的栈顶值*/
    	if(((*(__IO uint32_t*)FLASH_USER_START_ADDR) & 0x20030000 ) == 0x20030000)
    	{
    		/* Jump to user application */
    		JumpAddress = *(__IO uint32_t*) (FLASH_USER_START_ADDR + 4);
    		JumpToApplication = (pFunction) JumpAddress;

    		/* Initialize user application's Stack Pointer */
    		__set_MSP(*(__IO uint32_t*) FLASH_USER_START_ADDR);
    		JumpToApplication();
    	}

我使用的编译环境是TrueSTUDIO,如果有使用BootLoader那么应用程序需要做如下更改,该文件为.ld文件。

​图3

除了更改.ld文件还需要更改程序的向量表偏移值,找到该文件对VECT_TAB_OFFSET这个宏值进行更改,

​图4

更改该值一定要注意注释说明,修改的值必须是0x200的整数倍

​图5

更改完成后重新编译下程序,找到.map文件,查看文件的起始地址看是否修改成功,至此结束。

​图6

三、总结

BootLoader涉及到很多方面的知识,这里笔者只是简单的介绍,省去了很多东西,有兴趣的需要查找资料好好研究,这也是开发单片机必须要知道的。

原文地址:https://www.cnblogs.com/wenhao-Web/p/14056665.html