《BootLoader.pdf》由会员分享,可在线阅读,更多相关《BootLoader.pdf(9页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、LM3Sxxxx 学习笔记第三章Boot Loader 现今,嵌入式系统越来越受到人们的重视。随着系统复杂程度的提高,小型化和网络化也成为嵌入式系统发展的必然趋势。如何利用现成的通信网络,安全、快捷的对各个节点单片机进行在线软件升级(ISP),成为了嵌入式系统发展的一项重要课题,对工业控制、航空航天、通信等领域意义重大。而实现这一功能,需要一段核心代码的支持,这段代码就是BootLoader。Luminary Micro 公司设计并生产的Stellaris 系列单片机,基于先进的ARM Cortex-M3 内核,芯片提供的高效的性能、广泛的集成功能,适用于各种关注成本并明确要求具有过程控制以及
2、连接能力的应用方案。不可多得的是,Luminary 官方提供了BootLoader 的全部源代码,大大减小了开发难度。本章将分析Stellaris BootLoader 的组成、结构及设计思路,试图掌握其关键技术,以更好地应用BootLoader。3.1 简介BootLoader 是 位 于Flash 起 始地 址 处的 一小 段代 码,占 据空 间默 认 为2K。如果 没 有BootLoader,硬件启动成功后,将直接运行用户应用程序(Application)。反之,BootLoader 的启动代码(Start-up Code)将先被执行,进行一系列的初始化操作后,根据预先设定的条件,选择执
3、行用户应用程序(Application)或升级控制程序(Updater)。Updater 在升级Flash 的过程中,需要与上位机通信,通信的端口可选用UART,SSI,I2C 或以太网端口。为了保证数据的无差错传输,BootLoader采用了控制传输的通信协议:UART,SSI,I2C 端口均采用了自定义的串行加载协议;而以太网采用了 UDP 协议。对接收到的格式正确且校验成功的数据包,Updater 能够将其解包,并将得到的加载命令转化为对Flash 底层寄存器的操作。由于官方提供了BootLoader 的全部源代码,用户也可自行修改通信端口、通信协议等相关组件,使其更好地符合用户需求。B
4、ootLoader 的源代码由多个文件组成(图3.1):图 3.1 BootLoader 文件组成在图 3.1 中可以看出主要有6 个文件组成部分,同时还有几个头文件。bl_packet.c 串行数据包收发控制bl_uart.c UART 端口数据传输bl_autobaud.h 自动获取波特率bl_ssi.c SSI 端口数据传输B臼S阳Ml,tJ胡lob剧dc i土boot_loader.c 日囡packet_handle.r.c l;j bool_loader.h 囡臼i_h皿也町CZ司.百1iil.,.,r,自K.:t国uarl叫er.c 白白Libraries包:些苦ibftlU界豆:
5、 因3.1BootLoader文件组成”%LM3Sxxxx 学习笔记3.2 原理分析3.2.1 存储器映射图 3.2 存储器映射总体来说,Cortex M3 支持 4GB 存储空间,如图3.2 所示地被划分成若干区域。从图 3.2 中可见,不像其它的ARM 架构,它们的存储器映射由半导体厂家说了算,CortexM3预先定义好了“粗线条的”存储器映射。通过把片上外设的寄存器映射到外设区,就可以简单地以访问内存的方式来访问这些外设的寄存器,从而控制外设的工作。结果,片上外设可以使用C 语言来操作。这种预定义的映射关系,也使得对访问速度可以做高度的优化,而且对于片上系统的设计而言更易集成(还有一个重
6、要的,不用每学一种不同的单片机就要熟悉一种新的存储器映射)。CortexM3的内部拥有一个总线基础设施,专用于优化对这种存储器结构的使用。在此之上,CM3 甚至还允许这些区域之间“越权使用”。比如说,数据存储器也可以被放到代码区,而且代码也能够在外部RAM 区中执行(但是会变慢不少)。处于最高地址的系统级存储区,是CM3 用于藏“私房钱”的包括中断控制器、MPU 以及各种调试组件。所有这些设备均使用固定的地址。通过把基础设施的地址定死,就至少在内核水平上,为应用程序的移植扫清了障碍。由于Cortex-M3内核具有固定的存储器映射,这使得相同内核的芯片具有了更好的兼容性Cortex-M3 的地址
7、空间中,00.5G 被映射为 Flash 空间,0.5G1G 被映射为SRAM 空间。由于 SRAM是易失性存储器,故系统上电时,SRAM 中并没有内容,系统必须从Flash 开始启动。Flash 空间起始地址处必须存放向量表。向量表是异常产生时获取异常处理函数入口的一块连续内存,每一个异常都在向量表固定的偏移地址处(偏移地址以字对齐),通过该偏移地址可以获取异常处理函数的入口指针。向量表中前4 个字分别为:栈顶地址、复位处理函数地址、NMIISR 地址、硬故障ISR 地址。一OxFFFFFFFF OxEO以)()(阳OxOFFFFFFF OxA创沟)00Ox9FFFFFFF OX60)()(
8、)()()O xSFFFFFFF Ox4000创)00Ox3FFFFFFF Ox2000创mOx1FFFFFFF OxOOOO)()()SU MB Syst凹nLev创!GB Ext由nalDev也!GB ExtemalRAM SUMB P制阶erals 512MB SAAM 512M8 C创始服务于CM3的秘房外泼,包括NVIC寄存链,MPU寄存以及片上涌试组件主要用于扩展片步怡9夕卡设像8051部82SS似的用于扩展外部穆储量用于片上外设用于片上房态RAM代码,ti辞届运鹉锦启后续叠脚辑警号c:!;:,LM3Sxxxx 学习笔记张向量表至少由这四项组成。在程序代码开始运行后,向量表的基地址
9、也可以改变。通过软件设置NVIC 中的向量表偏移寄存器(NVIC_VTABLE,0 xE000ED08),可以在任意32 字对齐处建立向量表。3.2.2 硬件启动原理Stellaris 系列单片机硬件启动原理如下:硬件复位时,NVIC_VTABLE复位为 0,向量表默认位于Flash 空间起始地址处(0 x00000000)。内核读取向量表第1 个字设置主堆栈(SP_main),读取第2 个字设置 PC 指针,之后跳转到复位处理函数中运行。自此,系统的控制权交由软件接管。3.2.3 Boot Loader启动原理BootLoader 启动需先执行以下一系列操作:配置向量表、初始化存储器、复制B
10、ootLoader 代码到SRAM、从SRAM 中执行代码。BootLoader 的作用之一,是提供运行时修改Flash 的功能。而由于Stellaris 系列单片机具有单周期的Flash 读写能力,因此默认的代码段本身就位于Flash 中。这样,如果内核直接从Flash 中加载修改其自身的指令,则既容易造成时序上的混乱,又有可能因Flash 中某些关键指令被自修改而导致整个系统崩溃。图 3.3 BootLoader 复制针对这个问题,Stellaris 系列单片机采取的方案为:在SRAM 中建立BootLoader 的映像,即把BootLoader 复制到 SRAM 中,然后从 SRAM 中
11、加载指令。如图 3.3 所示。这样,指令的加载源(SRAM)与修改操作的目标(Flash)相分离,一定程度上保证了软件升级的可靠性和安全性。这样的存储器映射允许修改Flash 的全部代码。此外,BootLoader 也提供了保护机制,用于保护Flash 中的 BootLoader代码本身,以及Flash 空间顶部的一段存储区(保存即使Flash 升级也不需要擦除的代码)。除非相应的配置选项使能,否则,这两段代码不可随意修改。1PP START _ADORE SS Flash Fla俯室”(F融醺用户应用程序用户破F事向.Bo蝇。缸”.衍由化区B锐地。“阳只11战刚L帽曲e代a量Bootload
12、er向篝袋Bootloade伪币童医SRAM F初由化区初自化”用零填充8似地。“阳且.Boe施应酬恤只11队刚1.oederft码”矜Ult2削t!序位子,EBootl佣der向组曙A电子1在阴界 Bootloader1A fj区”筝E耐:t LM3Sxxxx 学习笔记在 Keil 版本的Boot Loader 中有这样一段代码,用于Boot Loader 复制到 SRAM 中,请看下面一段代码:01.EXPORT Reset_Handler 02.Reset_Handler 03.;04.;Call the C library enty point that handles startup
13、.This will copy the.data section initializers from 05.;flash to SRAM and zero fill the.bss section.It will then call _rt_entry,which will be either the 06.;C library version or the one supplied here depending on the configured startup type.07.;08.IMPORT _main 09.;10.;Copy the code from flash to RAM
14、11.;12.mov r0,#0 13.mov r1,#0 x20000000 14.orr r2,r1,#0 x0800 15.copy_loop 16.ldr r3,r0,#4 17.str r3,r1,#4 18.cmp r1,r2 19.bne copy_loop 20.b _main 从上面一段代码中可以看出,Boot Loader 占用 0 x800 个单元,上面代码的作用是从Flash 中把Boot Loader 复制到 SRAM 中,并调到 _main 函数中去运行,实际上是运行SRAM 中的 Boot Loader。3.2.4 运行条件在 SRAM 中映像建立完毕并开始执行后
15、,BootLoader 将检测某特定引脚(默认的是PB4,也可以自己修改为其它管脚)的极性,该极性可通过硬件修改,以决定运行Application 还是 Updater(默认情况下,复位时PB4 引脚为低则运行Updater,为高则运行Application),如图3.4 所示。引脚的选择及其极性的意义可在配置文件中修改。LM3Sxxxx 学习笔记图 3.4 运行条件3.2.5 由 BootLoader 加载 Application 由 BootLoader 加载Application,与系统复位后直接加载Application 有所不同。区别在于,在运行 BootLoader 的系统中,Ap
16、plication 的向量表并不位于Flash 起始地址处。Application 有自己的向量表,且不与BootLoader 共用向量表。这样做的目的,就是将BootLoader 本身与Application 分离开来,使两者具有一定的独立性。这也是由实际应用决定的:BootLoader 需在系统投入使用之前编译完成并通过JTAG 口或其它方式烧写进单片机,而Application 作为Flash 的升级程序,则通常在系统运行一段时间后才编写完成。向量表能够分离,关键在于向量表偏移寄存器(NVIC_VTABLE)的使用。如表3.1 所示。在硬件启动时,该寄存器会被复位为全0,即向量表位于Fl
17、ash 空间起始地址处;当 BootLoader 在 SRAM中建立映像之后,该寄存器被设置为0 x20000000,表示向量表位于SRAM 空间 起 始 地 址 处;如果 选 择 执 行 Application,那 么 该 寄 存 器 又 被 设 置 为 APP_START_ADDRESS(默认为0 x800,即2K),表示用户应用程序的向量表位于Flash 空间BootLoader 以上的某一地址处(BootLoader 的代码量不能超过APP_START_ADDRESS)。表 3.1 向量表偏移取值由 BootLoader 加载 Application 的关键代码:01.;*02.;Th
18、is function reads the stack pointer from the base address passed in and also moves the vector table 03.;to point to the vector table provided by the application.Once the vector table and stack are 04.;configured this function reads out the start address for the application and branches to it.05.;*06
19、.AREA|.text|,code,readonly,align=2 胁。IL阅derSRAM中运行配置更tli偏口 n-C之m”企m-h,-dm 0”“R e e 寄存器取ffi运行时刻 lI 1,J 41 nt 跳转烹SRAM运行ffl,.科,r-OxOOOOOOOO Ox20000000 APP START ADDRESS 备注Flash 巾,战侈Os LM3Sxxxx 学习笔记07.EXPORT CallApplication 08.CallApplication 09.mov r1,#0 xE0000000 10.orr r1,r1,#0 x0000ED00 11.str r0,r1
20、,#8;修改向量表偏移寄存器(NVIC_VTABLE)12.ldr sp,r0,#4 13.ldr r0,r0 14.bx r0 对于需要由BootLoader 加载的Application,则在KEIL 开发应用程序时Target 必须做好相关的设置,因为Boot Loader 的区域是0 x0000 x800,所以设置如图3.5。图 3.5 on-chip ROM 设置3.3 BootLoader 配置BootLoader 配置是通过一些编译预处理进行的,可以通过注释掉或者去掉相关注释掉的编译预处理进行 BootLoader 配置,主要在bootloader.h 中进行配置。请看bootl
21、oader.h 中的一段源码:01.;*02.!This defines the crystal frequency used by the microcontroller running the 03.!boot loader.If this is unknown at the time of production,then use the 04.!AUTOBAUD feature to properly configure the UART.05.;*06.#define CRYSTAL_FREQ 6000000 07./*08./!Enable this to call a decryp
22、tion routine during download of code to the microcontroller.09./*10.#define ENABLE_DECRYPTION 11./*12./!If the boot loader is going to use the UART port for transmitting data,13./!then this define must be turned on.14./*15.#define UART_ENABLE_UPDATE 16./*17./!Enable this to allow automatically detec
23、t the baud rate when the crystal Read/Only lolnoly Pt曹剖defd off:hp Sl!III Size Slatup 广f r、广设置五;800产on:hp IROMl:协商7萨布c;,IROM2 I【I电子I宿Lii界_”事”左LM3Sxxxx 学习笔记18./!value used in the system is unknown.This requires that UART_ENABLE_UPDATE 19./!also be defined.20./*21./#define AUTOBAUD 22./*23./!If the bo
24、ot loader is going to use the SSI port for transmitting data,then 24./!this define must be enabled.25./*26./#define SSI_ENABLE_UPDA TE 27./*28./!This definition controls which GPIO port to use for checking boot mode.29./*30.#define FORCED_UPDA TE_PORT(GPIO_PORTB_BASE)31./*32./!This definition sets t
25、he GPIO pin in FORCED_UPDATE_PORT to use for checking 33./!boot mode.This is a zero-based number and the valid values are 0-7.34./*35.#define FORCED_UPDA TE_PIN(4)36./*37./!This definition sets the level of the specified GPIO pin that causes the 38./!boot loader to enter update mode.If this value is
26、 set to 0,it indicates 39./!that a low voltage level on the GPIO pin indicates an update request.The 40./!only other valid value is 1 indicating that a high voltage level indicates 41./!an update request.42./*43.#define FORCED_UPDA TE_POLARITY(0)44./*45./!This sets the start address of the applicati
27、on.It is also used to detect 46./!if the application at this address in the flash contains a valid47./!application.48./*49.#define APP_START_ADDRESS(0 x0800)50./*51./!This defines the number of bytes reserved by the boot loader for stack 52./!space.53./*54.#define STACK_SIZE(64)55./*56./!This define
28、s the SSI chip select pin that is being used by the boot loader.57./*58.#define SSI_CS(GPIO_PIN_3)59./*60./!This defines the SSI clock pin that is being used by the boot loader.61./*LM3Sxxxx 学习笔记62.#define SSI_CLK(GPIO_PIN_2)63./*64./!This defines the SSI transmit pin that is being used by the boot
29、loader.65./*66.#define SSI_TX(GPIO_PIN_5)67./*68./!This defines the SSI receive pin that is being used by the boot loader.69./*70.#define SSI_RX(GPIO_PIN_4)71./*72./!This defines the combination of pins used to implement the SSI port used by 73./!the boot loader.74./*75.#define SSI_PINS(SSI_CLK|SSI_
30、TX|SSI_RX|SSI_CS)76./*77./!This defines the UART receive pin that is being used by the boot loader.78./*79.#define UART_RX(GPIO_PIN_0)80./*81./!This defines the UART transmit pin that is being used by the boot loader.82./*83.#define UART_TX(GPIO_PIN_1)相关配置项说明:1.CRYSTAL_FREQ 系统的晶振频率2.ENABLE_DECRYPTIO
31、N Application 代码加密3.UART_ENABLE_UPDATE UART 下载程序到Flash 4.AUTOBAUD 自动获取波特率(一般不用这项)5.SSI_ENABLE_UPDA TE SSI 下载程序到Flash 6.FORCED_UPDA TE_PORT Updater 关键引脚基地址7.FORCED_UPDA TE_PIN Updater 关键引脚的管脚位8.FORCED_UPDA TE_POLARITY运行 Bootloader 时管脚极性,默认为“0”,如果要运行用户程9.序则让对应管脚为高,即“1”。10.APP_START_ADDRESS Application
32、 起始地址11.STACK_SIZE BootLoader 堆栈深度12.SSI_CS、SSI_CLK、SSI_TX、SSI_RX、SSI_PINS SSI 下载程序管脚定义13.UART_RX、UART_TX UART 下载程序管脚定义看下面一个配置实例:01./请看 bootloader 文件夹中的bootloader.h 02.#define CRYSTAL_FREQ 6000000 03.#define ENABLE_DECRYPTION 04.#define UART_ENABLE_UPDATE 05./#define AUTOBAUD LM3Sxxxx 学习笔记06./#defin
33、e SSI_ENABLE_UPDA TE 07.#define FORCED_UPDA TE_PORT(GPIO_PORTB_BASE)08.#define FORCED_UPDA TE_PIN(4)09.#define FORCED_UPDA TE_POLARITY(0)10.#define APP_START_ADDRESS(0 x0800)11.#define STACK_SIZE(64)12.#define SSI_CS(GPIO_PIN_3)13.#define SSI_CLK(GPIO_PIN_2)14.#define SSI_TX(GPIO_PIN_5)15.#define SSI_RX(GPIO_PIN_4)16.#define SSI_PINS(SSI_CLK|SSI_TX|SSI_RX|SSI_CS)17.#define UART_RX(GPIO_PIN_0)18.#define UART_TX(GPIO_PIN_1)
限制150内