基于TMS320C6678的多核程序加载研究与实现

基于TMS320C6678的多核程序加载研究与实现

摘 要: 针对多核DSP系统程序加载复杂的问题,基于TMS320C6678对多核程序加载进行了研究与设计。从一级引导程序出发,设计并优化了多核程序内容存储格式。设计了简洁的二级引导程序,以修正一级引导程序只识别主核程序入口地址,而从核入口地址缺失的现象。为了快速生成特定格式的多核程序内容,设计了多个工具用于添加SPI启动参数表、DDR3启动表、从核程序入口地址以及完成程序内容格式的转换。实现了SPI Flash多核程序加载以及基于I2C主模式的Nand Flash多核程序加载。
关键词: 多核程序加载;多核程序内容存储格式;启动配置表;c_int00地址;二级引导程序
0 引言
多核DSP的程序加载是其开发过程中一个重要的研究课题。多核协同工作时,通常需要为每个核单独加载用户程序,它涉及外设的初始化、主从核任务分配以及多核程序内容存储格式等诸多问题,工程应用中要求系统能够脱机自启动加载多核程序。
随着DSP的主频越来越高以及外部接口越来越丰富,程序的加载方式也日趋复杂和多样化。以德州仪器(TI)开发的8核keystone架构的TMS320C6678(以下简称C6678)为例,它支持SPI Flash加载、I2C主从加载、网络加载以及PCIe加载等多达7种方式。由于TI官方对多核DSP程序加载技术的相关指导及目前国内外对多核程序加载的研究较少,且多核程序加载自身较复杂,大多数用户无法深入理解多核程序加载的思想,难以在工程应用中快速实现多核程序的自启动加载。本文实现了SPI Flash和基于I2C主模式的Nand Flash多核程序加载,提高了多核程序加载的效率。
1 C6678程序加载原理
C6678内部ROM中固化了一段一级引导程序,它针对不同的加载方式初始化相应外设,并从片外ROM或用户主机等不同的存储位置将用户程序搬移到指定的高速存储区中,如二级缓存(L2)或DDR3。C6678通过核索引编号(DNUM)将8个核标称为core0~core7。只有core0有执行一级引导程序的权限。C6678各核访问自己的L2时,可以采用本地地址或全局地址,但访问其他核的L2时,只能使用全局地址[1]。因此若要将多核程序存放到各核的L2中,在程序设计初期,程序各段内容都必须使用全局地址进行映射,否则core0会将所有核的程序都搬移到自己的L2中,而导致程序被覆盖无法执行的错误。图1是C6678多核程序加载的流程。C6678在每个核的L2中预留了一个被称为Boot Magic Address的空间,用来存储该核的c_int00入口地址。C6678完成多核程序的加载后,只有core0能够自动跳转到c_int00处执行程序,core1~core7都处于空闲状态(IDLE),需要core0唤醒。L2中

的IPC中断生成寄存器(IPCGRx),用于核间通信,当core0要唤醒core1,只需向IPCGR1中写1即可[2]。

2 SPI Flash多核程序加载设计
2.1 多核程序内容存储格式的设计与改进
C6678的一级引导程序能识别的SPI Flash中的数据存储格式分为两类:(1)第一类,只含SPI启动参数表和启动表两部分,其中启动参数表含CPU时钟、待加载表类型及偏移地址等信息;启动表是待加载表的一种,含程序段的大小、目的地址等信息;(2)第二类,增加了启动配置表,常用于初始化DDR3[3]。前者用于程序内容小于512 KB,可全部搬移到L2中执行的情况;当程序大于512 KB时,需搬移到DDR3中执行,因此要先初始化DDR3。为增加适用性,本文采用第二类存储格式。
文献[3]中,TI使用参数配置模板来初始化DDR3,即每一个寄存器都需要选择置位、清除、保持原值中的一种模板状态来设定每个bit位的值,用户非常容易混淆不同模板的功能;且每个寄存器需要占用3个字的空间,造成了一定程度上的空间浪费。本文提出了将文献[4]中提供的DDR3配置表转换为特殊的DDR3启动表对DDR3进行初始化的改进方式。表1以对DDR3的SDRFC寄存器进行配置为例,对两种方式进行对比。

采用参数配置模板时,当遇到连续的3个32 bit值为0的模板代表配置结束。而本文提出的方式指定了配置表的大小,不需要判定结束信息。图2右半部分是本文最终生成的多核程序数据存储格式,粗线框表示两种DDR3初始化方式的差异,其中DDR3配置表存放的目的地址由一级引导程序固定为:0x00873500,SPI启动参数表占8个字空间,DDR3配置表内容为28个字,c_int00、各段目的地址以及大小均为1个字,其他各段内容视程序而定。本文改进方式中,对DDR3的配置相当于core0的一段程序内容,因此SPI启动参数表对二者的判定亦不同,前者为启动配置表,而后者为启动表。

2.2 多核程序内容存储格式的实现
使用CCS开发的DSP程序,通常会生成一种COFF格式的.out文件,它包含重定位、符号表等辅助信息,格式解析复杂,且比有效数据要大数倍,造成存储空间的浪费[5]。为了正确且快速的生成图2所示的多核程序文件,本文采用图3中的工具链对.out文件进行转换。为了便于描述,图3只列举了core0的.out文件转换为.btbl文件的过程。其中hex6x、mergebtbl、b2i2c和b2ccs是TI官方提供的工具, addcfg和addparam是本文为完善工具链,在VS2010平台上开发的工具。hex6x去掉了.out文件中的所有辅助信息,并根据链接文件,生成特定的文件[6],.btbl文件末4个连续的值为0的字节表示文件内容的结束;mergebtbl将多个.btbl文件进行合并[1];b2i2c将.btbl文件按124 B大小分

块,并生成相应的校验码字[3];b2ccs将十六进制字符合并为32 bit的十六进制数据[3];addcfg用于添加DDR3配置表到指定位置处;addparam则用于添加SPI启动参数表。

待添加的DDR启动表的数据与.btbl格式一致,如SDRFC寄存器的内容保存为00 00 14 50,而addparam添加的SPI启动参数表内的数据则与.dat格式一致,如0x00300000。由于工具链较长,本文采用批处理的方式将所有命令按顺序写入一个.bat文件中,并将多核.out文件、DDR3启动表、SPI启动参数表和hex6x的链接文件放在同一目录下,即可一次性完成所有的转换工作,极大地提升了转换效率。本文所使用的hex6x工具链接文件如下:
corex.out//输入待转换的COFF文件
-a//生成支持32bit地址的 ASCII-Hex格式的目标文件
-boot//转换成启动表格式
-e _c_int00//指明程序的c_int00入口地址
-order M//生成大端格式的数据(一级引导程序默认
SPI中存储的数据是按大端格式)
ROMS
{
ROM1: org=0x0400,length=0x800000,memwidth=32,
romwidth = 32,files = { corex.btbl }
} //转换生成corex.btbl文件(x为核号);指定存储区
起始地址、位宽等信息,本文对存储区信息无要求
3 基于I2C主模式的Nand Flash多核程序加载设计



NOR Flash的存储容量通常小于16 MB,而Nand Flash则要大得多,常见的有128 MB、256 MB等。目前针对DSP系统的图像处理算法越来越复杂,代码体积急剧增加,本文设计了基于I2C主模式的Nand Flash多核程序加载方案,以供大型程序的自启动加载。由图2可知,SPI Flash加载多核程序时只包含了core0的c_int00地址,因此core0的程序中必须包含写core1~7的c_int00地址到各自Boot Magic Address中的操作。若core1~7任一核的程序有改动导致其c_int00地址发生改变 ,就必须修改core0程序,重新找到并指定相应核的c_int00地址,并重新编译core0工程,影响开发进度。本文通过基于I2C主模式的Nand Flash加载方式来解决这一缺陷。
本加载方式中C6678作为I2C主机, EEPROM作为I2C从机用于存储一段较小的可执行的搬移程序,被称为二级引导程序[7]。因为EEPROM存储容量通常只有几百KB,无法满足一般用户程序的存储需求,真正的用户程序则存储在容量更大的Nand Flash中。
3.1 Nand Flash中多核程序内容存储格式的设计
Nand Flash中多核程序内容存储格式由二级引导程序决定,本文设计了的存储格式,比图3更为简洁,它一方面降低了二级引导程序的设计难度;一方面修正了SPI Flash加载中core1~core7的c_int00地址缺失问题。图4中,merge_cint是本文对mergebtbl改进后的工具名,它增加了将core1~core7的c_int00地址保存在cint.map的文本文件中而不

是直接丢弃处理的功能,若某核的.out文件缺失,则该核的c_int00地址为0x00000000;新设计的addentry工具的作用则是将多核合并时产生的cint.map文件中的c_int00地址添加到userapp.dat文件的相应位置处。
3.2 EEPROM中二级引导程序的设计



图5是本文是针对图4所示的多核程序存储格式在CCS中开发的二级引导程序,它是一个与多核程序无关的独立工程,编译完成后,通过CCS可以直接下载到C6678系统的EEPROM中。加载不同的多核程序,每次只需修改Nand Flash中的内容即可。二级引导程序循环主体部分:对Nand Flash采用随机读的方式,每次搬移4个字节到指定的存储区中;core0~7的c_int00地址解析部分实现从Nand Flash多核程序内容中提取8个核的c_int00地址,并依次写入到相应核的Boot Magic Address中。为了保证多核程序的可靠加载,在c_int00地址解析以及循环主体部分,每当开始读取新的块时,都要检查坏块标志信息,以确定该块数据是否可用[8]。
4 设计验证
本文采用同一个多核工程对SPI Flash和基于I2C主模式的Nand Flash两种加载方式进行测试。该工程包含8个核的.out文件,分别命名为core0.out~core7.out,其中core0.out的大小为10 618 KB,core1.out~core7.out大小均为5 468 KB,core0开始执行程序便向core1~core7发送IPC中断,core1~core7成功收到中断后分别点亮系统中的一盏LED灯标示程序成功执行。本文对两种操作方式分别进行了5次实验,程序均成功执行。其中SPI Flash耗时21.87 s,基于I2C主模式的Nand Flash加载耗时34.63 s。二者的时间差异来源于:Nand Flash的数据读速率低于NOR型SPI Flash;基于I2C主模式的Nand Flash需经历二级加载,但如文中所述,二者各有优劣。实际工程中应根据情况灵活选用加载方式。
5 结论
本文总结了core0主导下的多核程序加载以及启动的流程,设计并改进了SPI Flash多核加载,采用DDR3启动配置表代替参数配置模板,并设计添加配置表,启动参数表等相关工具,降低了SPI Flash多核程序加载的开发难度。针对SPI Flash多核程序加载中存在SPI Flash存储容量偏小、core1~core7的c_int00地址缺失的问题,作为互补方案,本文设计了基于I2C主模式的Nand Flash多核程序加载,包括二级引导程序和相关工具的设计。最后通过实际的工程验证了方案的可行性。本文也可为TI推出的C66x等系列多核DSP程序的加载提供参考,具有一定的工程应用价值。

相关文档
最新文档