利用OFD工具创建DSP启动镜像文件

在一个数字信号处理系统中,它往往包含有多个的DSP,另外还有一个主机(它可以是DSPMCUFPGA等),DSP的初始化代码一般都驻留在主机的存储空间中,上电时把初始化代码被拷贝到DSP的特定的存储空间,从而DSP可以正常的执行应用代码。但是DSP代码需要转换成一种特殊的数据格式,这样它才能在主机的应用程序中被包含,并被加载到目标DSP存储空间中。我们称具有这种特殊数据格式的DSP应用代码为其镜像。就工程应用来说,DSP镜像一般在C源程序中被包含。本文着重讨论一种区别于创统方法的镜像文件生成方式。本文将描述怎样用COFF以及XML文件创建一个DSP引导镜像文件,并给出一个简单的Perl描述符。。得出的镜像是一个C程序,它能够包含到主机的应用程序中并能通过HPIPCI接口下载到目标DSP中。

1 OFD 工具介绍

目标文件显示工具(Object File Display OFD),用于处理公共目标格式(COFF)文件,将COFF文件包含信息转换成XML格式文件。OFD工具在CCS3.0或更高版本中提供。

11 DSP镜像传统生成方法

创建一个DSP镜像的传统方法[1][2]

1)用TI的连接器(Linker)在*.obj文件基础上创建一个COFF*.OUT)文件

2)用TIHEX工具把COFF文件转换成ASCII镜像

3)写一个描述符或者一段C代码把ASCII镜像转换成的头文件。

这种方法的缺点是:HEX工具本身仅能支持为数较少的通用数据格式,用户经常需要额外的工具对HEX的输出文件格式进行转换或者从目标文件中提取信息,比如段(Section)长度信息。当目标文件的格式改变时,就转换工具随之改变。因此,如果有一种工具,即使用户不用懂得目标文件格式也能用它轻松应对目标文件进行处理,那对广大用户来说是大有益处的。

1利用OFD生成DSP启动镜像

OFD工具把COFF文件作为输入,并生成一个XML格式的输出文件。输出内容可以自定义,并可通过进一步处理将COFF文件转换到理想输出格式,比如C。利用OFD还可以提取出COFF文件中的一些特别信息。比如,段(Section)的数量、类型、大小,目标的端模式等。对OFD输出XML文件的操作首先是进行XML文件的解析。XML本质上是一种文本文件,为了从XML文件中提取信息,通常的做法是使用现有的XML语法分析器模块。XML语法分析器模块在大多数编程语言中都有包含,比如,PerlVBC++,JAVA

ActiveStateActivePerl包含了一系列的XML语法解析模块。在下面的应用例程中,我们将对如何在ActivePerl环境下处理OFD输出文件进行处理作大致描述。此前,须在TI的网站上下载一个Perl描述符文件 bootimage.pl ,通过它,CCS可以在工程链接的最后阶段自动调用OFD工具生成XML中间文件,并且调用Perl XML语法解析模块从中解析出有用的信息并以C的格式输出。

2.应用实例

现有一个数字信号处理系统,主要由3DSP组成。如框图所示,TMS320C6416作为HOST。在其总线EMIFA上边同时挂有两颗TMS320C6713芯片。

2010年07月26日 - Bibby - 我的博客

图一 系统示意图

系统的应用程序、初始化数据都存储在位于TMS320C6416 EMIFB总线上的FLASH中,上电时TMS320C6416开始从FLASH中引导应用程序,同时把TMS320C6713的程序通过HPI口加载[3][4][5]  为了得到TMS320C6713的加载代码,操作步骤如下:

1. ActiveState下载一个ActivePerl,安装ActivePerl并重启电脑。

2.在CCS3.1中新建工程A,输入调试代码,编译链接。并下载到目标DSP进行调试。保证生成的代码有效。

3.第二步不是本文阐述的重点,在第二步完成后。工程目录下会生成一个debug的文件夹。我们将bootimage.pl拷贝到其中,并在CCSProject\Build Options\General选项卡中的Final buid step栏中新建 perl debug/bootimage.pl debug/a.out

2010年07月26日 - Bibby - 我的博客

图二 CCS设置选项

4.重新进行目标文件的链接,此时在debug文件夹中就会新生成两个文件:A.out.C  A.out.h。这就是我们所需的C代码形式出现的镜像文件。例如:

A.out.h

extern const unsigned char _const[0x161];

extern const unsigned char _text[0x90c0];

extern const unsigned char _vec[0x200];

extern const unsigned char _cinit[0x634];

A.out.c

/********************************

_const[0x161]: paddr = 0x0000b3f0

********************************/

const unsigned char _const[0x161] = {0x00, 0x20, 0x20, 0x20,…………….};

/********************************

** _text[0x90c0]: paddr = 0x00000800

********************************/

const unsigned char _text[0x90c0] = {0xf6, 0x54, 0xbc, 0x01,……………..};

/********************************

_vec[0x200]: paddr = 0x00000000

********************************/

const unsigned char _vec[0x200] = {0x2a, 0xc0, 0x4a,…………………….};

/********************************

** _cinit[0x634]: paddr = 0x0000a3b8

********************************/

const unsigned char _cinit[0x634] = {0x30, 0x02, 0x00, 0x00,…………….};

文件给我指出了各个段的类型、大小以及在目标DSP中的位置。在HOST的应用程序中我们只需把A.out.c文件加入源文件,把A.out.h进行头文件包含。而且把相应数组通过HPI口写到目标DSP即可。以下是写_const段的部分代码。

#include "A.out.h"

…………………….

void subsystem_load(int HPI_base)

{

int i=0;

short * ip;

int HPICL_W=(HPI_base+0x0);

int HPICH_W=(HPI_base+0x2);

int HPIAL_W=(HPI_base+0x4);

int HPIAH_W=(HPI_base+0x6);

int HPIDL_W=(HPI_base+0x8);

int HPIDH_W=(HPI_base+0xA);

int HPIDL_R=(HPI_base+0x18);

int HPIDH_R=(HPI_base+0x1A);

REG16(HPICL_W)=0x0001;

REG16(HPICH_W)=0x0001;

ip=(short *)_const;

REG16(HPIAL_W)=0xb3f0;

REG16(HPIAH_W)=0x0000;

for(i=0;i<sizeof(_const)/4;i++)

{

REG16(HPIDL_W)=*ip++;

REG16(HPIDH_W)=*ip++;

}

末了,把HPICL_Wbit1位置为高,此时目标DSP即脱离复位状态,程序开始从0x0000000的地方开始执行。

结束语

经过工程实践证明,该方法较传统简单有效。工程人员能在工程中轻松应对繁杂的镜像文件制作问题,减小代码在调试过程中的出错环节。

你可能感兴趣的:(利用OFD工具创建DSP启动镜像文件)