Blackfin处理器Second-stage Loader

Blackfin处理器Second-stage Loader,第1张

Blackfin理器Second-stage Loader的应用程序在线升级设计方案

本文主要介绍了ADI Blackfin处理器的启动流程、LDR文件的格式和一些高级的启动技术,最后通过一个实际的例子说明如何使用SSL (second-stage loader) 实现应用程序的在线升级。

对于嵌入式开发者来说,一种快速方便的在线升级方法不仅能够节约升级带来的额外成本,还可以提高升级效率。

随着集成电路技术的快速发展,系统的硬件方案已经变得越来越相似,一个嵌入式应用的价值和特点往往都是由应用程序来决定的。因此用户希望嵌入式系统的功能可以不断地完善和增强,这使得应用程序的升级变得非常普遍。

Blackfin处理器Second-stage Loader,第2张
图1 Blackfin处理器启动流程

通用Blackfin的启动流程和LDR文件分析

通用Blackfin处理器的启动流程

Blackfin处理器的启动可以看作是从静态存储器上读取启动码流(LDF文件格式)到Blackfin内部的L1和SDRAM存储器的过程。启动工作全部由存储在Blackfin ROM中的启动代码完成的。每款Blackfin处理器的ROM大小有所不同,但启动过程总是从ROM的起始地址0xEF00 0000开始。

Blackfin处理器的启动代码可以分为新旧两种版本,分别针对BF54x、BF52x、BF51x、BF561和BF53x。新版本启动代码以处理器的启动模式为基础来构建程序,一个通用的启动内核负责处理的启动码流的解析、装载和异常错误的处理。本文以新版的启动代码为基础进行分析和构建实例,用户可以参考已经发布的应用笔记EE-240和EE-314来学习BF53x和BF561的启动过程。

本文以图1为例讲解Blackfin处理器的启动流程。处理器复位后会从ROM的起始地址开始执行,启动代码首先读取启动码流最开始的8个字节,它们只是头信息的一部分,内核通过分析包含在这8个字节中的DMACODE位来确定DMA通道的宽度和步长。一旦DMA的配置完成后,启动码流将以子块为单位进行读取。启动代码根据头信息中的目标地址和子块长度将启动码流的每个子块传输到指定的存储器位置。当所有的块传输完成后,启动代码会自动跳转到应用程序的起始地址开始执行,默认的地址是0xFFA0 0000。这个过程就是Blackfin的启动。

LDR文件格式

LDR文件,即可装载文件,包含着全部的启动码流并保存在静态存储器中供启动使用。它可以非常容易地通过Visual DSP(VDSP)的ELFLOADER功能生成。ELFLOADER解析输入的可执行DXE文件,生成带有头信息的启动码流,过程如图2所示。

Blackfin处理器Second-stage Loader,第3张

图2 LDR文件生成过程

LDR文件由多个子块组成,每个子块可以分为头部和负载两个部分,但有部分特殊子块只有头部,没有负载区。头部区共有16个字节,分别存储着头部的CRC校验数据、标志符、目的地址、块大小和块参数,如图3所示,用户可以使用LDR VIEWER工具查看LDR文件。启动代码每次都会对头部16字节进行异或校验, BLOCK CODE的低16位用于储存头部区的校验和。一旦头部信息校验失败,启动代码就会调用错误处理函数,默认的情况是将内核置于空闲态,不处理任何后续数据。但是用户可以在初始化函数中自行替换错误处理函数。

Blackfin处理器Second-stage Loader,第4张

图3 启动码流头部区

头部的标志符共有16比特,如图4所示。这里需要着重指出的是BFLAG_FINAL、BFLAG_FIRST、BFLAG_INIT和BFLAG_FILL四个标志符,它们分别指出当前的子块为结束块、开始块、初始化块和填充块。一般情况下每个LDR文件都会存在这四个标志符,而且具有其中任何一个标志符的子块都没有的负载区。一旦启动码流解析到标志符中有BFLAG_FINAL或BFLAG_INIT,它会马上调用入口地址存储在EVT1寄存器中的函数,这个地址通常是0xFFA0 0000。也就是说,在默认的情况下,应用程序的起始位置和初始化函数的起始地址都是0xFFA0 0000。DMACODE用来配置DMA通道的宽度和传输步长,但一般只在启动开始的时候设置一次。

Blackfin处理器Second-stage Loader,第5张

图4 标志符低16位

Blackfin的高级启动功能

内核数据结构

新版的启动代码使用了一种新的数据结构,叫做ADI_BOOT_DATA。通过在初始化函数中修改这个数据结构中的成员变量,用户可以定义自己的启动过程,这里简要介绍升级过程中用到的成员。

• pSource:启动码流在FLASH存储器中的起始地址,默认情况下是0x0。但用户可以通过修改这个成员,使启动代码从FLASH存储器的其它地址开始读取启动码流。

• pLogBuffer:启动记录存储区,默认的起始地址位于0xFFB0 0400。因为这个临时数据存储区不能被DMA访问,所以多作为应用程序的堆栈。该缓冲区记录了启动码流的每个子块的头信息及一些同启动过程密切相关的重要信息,具体内容可参考BF51x的硬件手册。这些记录信息的主要用于启动调试。

• dFlags:低15位是当前正在处理的启动码流子块的头信息标志符(图4),高15位是启动数据结构的标志符,如图5所示。当SPI FLASH的类型已经确定后,用户通过设置BFLAG_TYPE,BFLAG_NOAUTO和BFLAG_ALTERNATE三个标志位可以使启动代码跳过SPI地址检测。

Blackfin处理器Second-stage Loader,第6张

图5 标志符高16位

可用于启动过程的API函数

为了方便开发者定义客户化的启动过程,启动的ROM提供了11个API函数供用户使用,它们的接口参数请详见BF51x硬件手册,这里介绍将会用到的BFROM_SPIBOOT,BFROM_CRC32和BFROM_CRC32POLY函数。

BFROM_SPIBOOT函数的C语言原型是:

s32 bfrom_SpiBoot (s32 dSpiAddress,

s32 dFlags,

s32 dBlockCount,

ADI_BOOT_HOOK_FUNC* pCallHook);

SPI启动代码需要四个参数,分别是启动码流在SPI FLASH内存中的起始位置,启动标志符(图5和图4)、子块数量(非负数时正常启动)和回调函数。通过使用这个函数,SPI启动代码可以装载已经存储在SPI FLASH的启动码流。利用回调函数,用户可以修改SPI的波特率,SPI的slave select pin等配置,加快启动速度。

BFROM_CRC32POLY函数的C语言原型是:

s32 bfrom_Crc32Poly (unsigned s32 *pLut,

s32 dPolynomial);

该函数根据用户提供的多项式建立CRC校验需要的查询表,多项式可从LDR文件的INIT块中找到(必须使用-CRC32选项生成LDR文件)。查询表要在使用bfrom_Crc32函数之前建立好。

BFROM_CRC32函数的C语言原型是:

s32 bfrom_Crc32 (s32 *pLut,

void *pData,

s32 dByteCount,

s32 dIniTIal);

该函数用于校验LDR文件的负载区,头部信息已经有头部区的校验和来保证正确性。使用该函数之前需要建立CRC校验查询表。函数会返回每个子块负载区的CRC值。

基于SSL的在线升级方法

当前的升级方法多是基于ping-pong的方法,每次都会更新最旧的版本,这样的设计保证了即使升级失败,系统也能够正常启动。但是使用这种方法,系统需要启动码流两倍大小的FLASH存储器,增加了系统成本。

本节将根据前面介绍的Blackfin处理器启动流程和高级启动技术,使用SSL来构建一个在线升级的方案。通过使用SSL,用户能够控制升级和启动过程,即使出现升级失败,也不会导致系统瘫痪,而且不需要增加额外的FLASH存储器空间。这个例子基于BF518处理器,但也可以推广到BF54x或BF52x处理器。本文选用比较通用的SPI FLASH作为SSL和应用程序的存储介质,同时BF518工作在external SPI boot的模式。SSL通过串口接收升级数据,同上位机进行通讯。

SSL的工作原理

SSL主要包括两部分功能,启动码流的接收和升级。接收部分通过串口从上位机接收LDR文件,然后存储到SDRAM中,使用Blackfin提供的bfrom_Crc32函数校验接收到的码流。升级部分将SDRAM中的LDR文件烧写到SPI闪存中,并更新文件状态。升级过程如图6所示。

Blackfin处理器Second-stage Loader,第7张

图6 升级过程

升级应用程序首先需要软/硬重启系统来加载SSL。SSL启动后首先初始化系统硬件,向上位机发出是否升级的确认信息。如果在5秒内没有得到上位机的回复,系统将进行正常的启动流程。用户也可以自定义等待时间(不超过10秒)。如果SPI FLASH中没有有效的启动码流,SSL会强制让用户升级新的应用程序。得到确认升级的消息后,SSL要求上位机发送启动码流。当上位机发送完成全部码流后,它要发送一个用户定义的结束标志符(不要和LDR文件中的数据重合)通知SSL传输过程完成。然后SSL对缓存在SDRAM中的数据进行CRC校验并将结果反馈到上位机。如果校验失败,SSL会让用户选择重新升级,还是放弃升级后启动上一次使用的应用程序。CRC校验成功后,SSL将更新SPI FLASH中LDR文件和状态标志位。全部过程结束后SSL直接调用bfrom_SpiBoot函数加载应用程序,不需要重新启动系统。

SSL和应用程序的LDR文件生成和FLASH烧写

应用程序的LDR文件生成如下图7所示,需要增加-CRC32选项使ELFLOADER生成带有校验多项式的文件(请参考VDSP帮助文档获得该选项的具体信息)。SSL需要单独生成一个LDR文件,并烧写到SPI FLASH起始地址0x0。一般SPI FLASH的最小擦除单位是扇区,所以应用程序要从SSL后面的第二个扇区开始烧写,并且要空出头4个字节用来保存当前LDR文件的状态标志位。

Blackfin处理器Second-stage Loader,第8张

图7 Load OpTIon配置

总结

本文首先介绍了BF51x处理器的启动过程,LDR文件的解构和一些高级的启动技术,并在这些知识的基础上实现了一个基于SSL的应用程序在线升级。本文描述的SSL只实现了一个基本的程序升级要求,根据实际应用的需要,嵌入式开发者可以继续扩展SSL的功能,比如支持网络升级等或定制自己的SSL。通过使用SSL,嵌入式开发者可以非常迅速方便地升级应用程序,节约升级成本,为客户提供额外的产品价值。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/dianzi/2433399.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-08-02
下一篇 2022-08-02

发表评论

登录后才能评论

评论列表(0条)

保存