学海荡舟手机网

主页 > 实用文摘 > 教育文摘_07 > > 详细内容

TMS320C62x HPI引导过程的实现_DSP论文

摘要:tms320c62x和tms320c67x dsps提供了几种不同的启动模式,不同的启动模式决定了dsp复位后的初始化以及代码装载方式。本文就tms320c62x dsp的hpi启动模式进行详细的说明。

    关键词:tms320c62x    dsp     hpi   启动模式

    1 绪言

    在tms320c62x系列dsp中,主机口hpi是一个16位宽度的并行端口。主机(也称上位机)掌管该接口的主控权,通过它可以直接访问cpu的存储器空间。另外,主机还可以直接访问tms320c62x片内的存储映射的外围设备。

    hpi与cpu存储空间的互连是通过dma控制器实现的。借助专门的地址和数据寄存器,通过dma辅助通道,完成hpi对存储空间的访问。主机和cpu都可以对hpi控制寄存器hpic进行访问,主机一方还可以访问hpi地址寄存器hpia和hpi数据寄存器hpid。

    2 tms320c62x引导模式

    tms320c62x系列dsp提供了三种引导方式:

    (1) 没有自举过程:cpu直接从地址0开始执行代码;

    (2) rom自举:由dma/edma控制器从外部ce1空间中的rom中拷贝固定数量的一段代码到地址0,拷贝结束后,cpu从地址0开始运行;

    (3) hpi自举:由外部主机通过hpi对芯片的存储器空间进行初始化,初始化结束后,外部主机通过hpi中断唤醒cpu,cpu开始从地址0运行。

    所有这些设置项都是在芯片复位的时候才进行检查。一旦复位信号有效(reset=0),所有的三态输出管脚恢复为默认状态,然后在reset信号的上升沿处检查设置管脚bootmode[4:0]的状态,自举逻辑开始生效。其中c6201/c6701有专门的管脚作为bootmode[4:0],c6211/c6711则是利用主机口的hd[4:0],c6202/c6203利用扩展总线的xd[4:0]作为bootmode[4:0]信号。

    对于tms320c62x的hpi自举模式过程如下:首先需要设置boot模式,boot模式设置如表1所示。当dsp被复位时,如果选择了hpi boot模式,那么只有dsp的内核进入复位状态,dsp其余模块均保持激活状态。这样,主机就可以通过hpi接口访问dsp的整个存储空间,包括片内、片外存储器和片内的外设寄存器,对它们进行初始化。主机对dsp做完了有关设置后,向hpic寄存器的dspint位写1,将dsp从复位状态唤醒,接下来cpu就从地址0开始执行程序。主机对dsp可以进行的操作包括:初始化cpu和emif,向dsp加载程序以及数据等。

表1 tms320c62x hpi boot配置
 

bootmode[4:0]

memory map

memory at address 0

boot

00110

map 0

external; default values

hpi

00111

map 1

internal

hpi

    3 tms320c62x hpi引导模式的实现

    3.1 创建启动代码

    实现tms320c62x hpi引导模式的第一步是生成hpi引导的dsp代码,并把它与主处理器应用程序合并在一起,使dsp应用程序可以和主处理器应用程序一起远程下载。为了简化,采用下列方案:把dsp应用程序转换成头文件中的数组,并和主处理器应用程序一起编译连接。

    具体实现分为两步:1)利用转换工具hex6x把coff文件转换成ascii-hex格式十六进制文件;2)利用自编工具hex2aray.exe将ascii-hex格式的文件转换成包含数组的头文件。

    (1)利用转换工具hex6x把coff文件转换成ascii-hex格式十六进制文件

    利用转换工具hex6x把coff文件转换成十六进制文件,使用转换工具hex6x需要一个.cmd文件说明具体的转换格式,如下面文件hexcom.cmd所示:hex6x把coff文件test.out转换成两个ascii-hex格式的文件:一个是代码段,包含在文件test.a00中;另一个是初始化的数据段,包含在文件test.a10中。在dos命令行中执行hex6x hexcom.cmd将产生test.a00和test.a10两个文件。

文件hexcom.cmd:
..\object\test.out
-a
-byte
-image
-memwidth 16
-romwidth 16
-order m

roms
{
/* size of the internal pgm memory */
pgm: org = 0x00000000, length = 0x10000
/* size of the internal data memory */
data: org = 0x80000000, length = 0x10000
}

    (2)利用工具hex2aray.exe生成头文件

    然后利用hex2aray.exe将两个ascii-hex格式的文件:test.a00和test.a10分别转换成两个个包含数组的头文件:code.h和init.h。工具hex2aray.exe为自编工具。在dos命令行中分别执行hex2aray –i test.a00 –o code.h和hex2aray –i test.a10 –o init.h两条命令将产生两个头文件code.h和init.h。在文件hexcom.cmd中的选项:- a,指示hex6x按ascii-hex格式转换文件,ascii-hex文件格式如下所示:

^b
$axxxx,
xx xx xx xx xx xx xx xx xx xx. . .
^c

    文件开始是ascii stx 字符 (ctrl-b, 02h),结束是ascii etx 字符 (ctrl-c, 03h);$axxxx,代表地址;其余为代码。转换后的头文件格式如下:

const char code[]={0x12,0x18,0x01,0x00,0x28,0x00,0x00,0x00,0x2a,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,
0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

};

    3.2 主机对hpi接口的操作

    tms320c62x提供了三个16位寄存器:hpic、hpia、hpid和16位数据线与主处理器通信。主处理器通过hpic、hpia、hpid和16位数据线来与tms320c62x进行数据交换,数据交换的过程如下:

    1)首先初始化hpic;
    2)然后把地址写到hpia;
    3)最后通过hpid读或写数据。

    假设主机cpu也是tms320c62x,那么主机与目标机之间的连接如图1所示:

    如图1所示,假如target 6201的/hcs连接到主机6201的ce1上。target 6201的hpi寄存器映射到host 6201dsp内存中,hcntrl[1:0]和hhwil连接到主机cpu的地址线上,那么hpic、hpia、hpid寄存器的地址分配如表2所示。,那么在c语言中,可以通过指针访问hpic、hpia、hpid,例如:

#define c6201_hpi 0x01400000  /* host address on which c6x hpi is mapped */
int *hpi_ptr;      /* define and initialize pointer*/
hpi_ptr = (int *)c6201_hpi;

/* write dest_address to hpia, with hob=1 */
ptr_hpi = (int)(dest_address & 0x0ffff);
ptr_hpi = (int)((dest_address>>16)&0x0ffff);

表2  hpic、hpia、hpid各寄存器的地址分配
 

映射到主机的地址

hpi控制线

hpi寄存器访问

hcntl[1:0]

hhwil

hpi base address + 0x00

00

0

hpic 1st  halfword

hpi base address + 0x04

00

1

hpic 2st  halfword

hpi base address + 0x08

01

0

hpia 1st  halfword

hpi base address + 0x0c

01

1

hpia 2st  halfword

hpi base address + 0x10

10

0

hpid 1st  halfword

hpia 自增

hpi base address + 0x14

10

1

hpid 2st  halfword

hpia自增

hpi base address + 0x18

11

0

hpid 1st  halfword

hpia不自增

hpi base address + 0x1c

11

1

hpid 2st  halfword

hpia不自增

    3.3 主机通过hpi下载代码和数据段到目标dsp

    一个程序由初始化区和非初始化区两部分组成,主机处理器必须根据.cmd命令文件把这两个区装载到dsp正确的地址。下面这段代码就是将代码段和数据段两部分分别下载到指定地址(即程序ram和数据ram)。它主要是从*source中读出32位长的数据,然后通过hpi将此数据写到dsp的dest_add地址(即程序ram和数据ram)中。*source中的数据就是dsp的启动代码段和数据段中的数据。

void c6x_write_section(int *ptr_hpi, short *source, int dest_add, int length)
{
int i;
/* write hpic with hwob=1,1st halfword transferred is least significant */
/* hcntrl1 hcntrl0 hhwil */
ptr_hpi[0] = 0x0001; /* 1st halfword 0 0 0 */
ptr_hpi = 0x0001; /* 2nd halfword 0 0 1 */
/* write destination address to hpia, 1st halfword is least significant */
/* hcntrl1 hcntrl0 hhwil */
ptr_hpi = (int)(dest_add & 0x0ffff); /* 0 1 0 */
ptr_hpi = (int)((dest_add>>16)&0x0ffff);/* 0 1 1 */
for(i=0 ; i < length ; i++)
{
/* write source_word to hpid with address post-increment */
/* 1st half-word transferred is least significant */
/* hcntrl1 hcntrl0 hhwil */
ptr_hpi = (int) *source++; /* 1 0 0 */
ptr_hpi = (int) *source++; /* 1 0 1 */
}
}

    3.4 目标dsp开始执行所下载的代码

    主机通过hpi下载代码段和数据段到目标dsp以后,那么目标dsp就需要执行所下载的代码了。通过写hpic寄存器的dspint位为1让dsp退出复位状态后,dsp就开始从地址0执行所下载的代码了。具体实现代码为:

/* write hpic with dspint=1 */
/* hcntrl1 hcntrl0 hhwil */
/* 1st halfword 0 0 0 */
/* 2nd halfword 0 0 1 */
ptr_hpi[0] = 0x0002; /* 1st halfword */
ptr_hpi = 0x0002; /* 2nd halfword */

    4

    根据前面所述,tms320c62x hpi启动过程如图2所示。