原创 ARM S3C4510B与DSP6416互连的接口设计

2007-5-26 02:01 3285 5 6 分类: MCU/ 嵌入式
1、导言

随着现代计算机技术和互联网技术的飞速发展,嵌入式系统成为当前IT行业最热门的焦点之一。32位ARM嵌入式处理器具有高性能、低功耗的特性,已被广泛地应用到消费电子产品领域和无线通信、网络通信等高端设备领域。DSP芯片由于功能强大,加上接口方便、软件可用资源丰富、编程方便、稳定性好、精度高等优点,应用越来越广泛。通常在嵌入式系统的设计中,由ARM嵌入式处理器实现整个系统的协调控制和网络功能,由DSP芯片来执行复杂计算,因此需要实现ARM处理器和DSP之间的数据交换。从某种程度上来说,ARM嵌入式处理器和DSP之间数据交换的速度决定了整个系统的运行速度和性能[1]。
本文结合一个实际的基于DSP6416实现实时视频压缩编码和传输系统项目的开发,研究ARM处理器和DSP芯片之间接口的设计,并且讨论基于uCLinux下接口(HPI口)驱动程序写方法。

2、系统的整体结构

该实时视频压缩编码和传输系统的详细结构如右图1所示:
本系统由ARM系统单元,DSP系统单元和FPGA系统单元构成。ARM系统单元主要完成控制DSP系统,从DSP系统中取出已经编码好的视频数据并发送到客户端。我们选用Samsung公司的ARM CPU S3C4510B作为ARM系统单元的主芯片。ARM4510B是基于以太网应用系统的高性价比16/32位RISC微控制器,内含一个由ARM公司设计的16/32位ARM7TDMI RISC处理器核[2]。ARM7TDMI为低功耗、高性能的16/32位核,适合用于对价格及功耗敏感的应用场合。DSP系统单元主要完成对FPGA采集进来的实时视频信号进行压缩编码。我们选用TI公司的TMS320C6416 DSP作为DSP系统单元的主芯片。TMS320C6416是现在市面上功能最强大的DSP芯片之一,其工作在600MHZ的主频下,速度足以达到完成实时视频数据压缩编码的要求。FPGA系统单元主要完成视频数据采集和缓冲作用。FPGA系统单元我们选用Altera公司现场可编程门阵列(Field Programmable Gate Array)EPF10K100VRC240外加一片SDRAM来构成。

3、TMS320C6416 DSP的主机接口(HPI口)

 DSP的主机接口(HPI)是一个并行接口,通过该接口ARM微控制器可以直接访问DSP的内部存储器空间或地址映射到存储器空间的外围设备。C6416DSP中的主机接口可以被设置为HPI32和HPI16这两种模式。为了发挥ARM和DSP6416 32位机的优势,提高存取数据的速度,设置C6416工作与HPI32模式下。
TMS320C6416 DSP与外部ARM微处理器通过单独的32位数据线HD0~HD31和8条控制线进行连接。ARM微处理器通过HPI口访问DSP内部的RAM以及其他一些外部资源。在整个ARM微处理器与DSP芯片通过HPI接口进行通信和数据交换的过程中,除了中断ARM和清除ARM发过来的中断需要DSP本身参与外,其他操作DSP都处于被动的地位,几乎不用进行其他的操作[1]。所以对于ARM来说,DSP系统单元就相当与一片外接的SDRAM。
TMS320C6416的HPI口是一个16/32位宽的并行接口。它具有两条地址线HCNTRL [1:0] ,负责对HPI口的内部寄存器进行寻址。HPI口只有三个32位内部寄存器,分别是控制寄存器HPIC、地址寄存器HPIA和数据寄存器HPID。HPI口内部有一个用户不可见的EDMA地址产生器和一个8个32位字深的缓冲区,负责产生地址和数据调度[3]。用户只需对上诉三个HPI口寄存器进行相应的读写操作,就能完成对DSP内存空间的访问。

4、DSP6416与S3C4510B连接的硬件设计

 由于S3C4510B中没有完全符合DSP6416 HPI接口时序的外部接口可以直接使用,因此我们选用S3C4510B中时序最接近HPI接口时序的外部I/O接口同DSP6416进行连接。在实践中我们还使用一些其他的信号线来协助外部I/O接口完成模拟HPI接口时序的工作,最后通过编程使S3C4510B的外部I/O接口的时序完全符合DSP6416 HPI接口的需要。设计的ARM与DSP接口的硬件连线如下图2所示:

点击看大图


S3C4510B只需要寻址HPI接口的3个寄存器,根据对这3个寄存器的寻址关系,将主机的两根地址线(ADDR2、ADDR3)分别接到DSP的(HCNTL0、HCNTL1),就可以在编程时使地址线出现要求的高、低电平,从而完成对不同寄存器的访问。我们用S3C4510B的外部I/O接口BANK1来同DSP6416相接,将外部I/O接口BANK1(地址为0x3FD4000-0x3FD8000)的片选信号nECS1接到HPI接口的片选信号HCS,这样只要对BANK1进行操作,就可以产生相应的片选信号。由于S3C4510B没有HR/W信号,所以选用ADDR4来代替该信号和HPI口的HR/W相接,只要对地址的ADDR4位为1或0的地址进行操作就可以产生高或低电平,从而选择HPI口处于写还是读状态。将S3C4510B的外部I/O接口BANK1的信号线nOE和nWBE1分别接到HPI口的HDS1和HDS2,使它们和nECS1一起通过一定的逻辑运算([NOT (nOE XOR nWBE1)] OR nECS1)组成数据闸门信号nHSTROBE(内部信号)。nHRDY为DSP就绪指示信号,由DSP产生。所有读写操作都必须在nHRDY信号有效时进行。将nHRDY信号经过反相后接到S3C4510B的nEWAIT(等待信号)上面,这样在DSP没有准备好数据的时候可以延长ARM的读写周期,使ARM处于等待DSP就绪的状态。nHINT信号是HPI口的中断信号,他既可以由DSP产生,从而中断ARM,也可以由ARM产生来中断DSP。我们将中断信号接到S3C4510B上的外部I/O口P8上,这样我们既可以由P8口产生信号中断DSP,也可以在P8口侦听来自DSP的中断信号。

5、DSP6416与S3C4510B连接的软件设计

在硬件连接设计好的基础上,我们还需要通过正确的编程才能实现我们预想的时序。因为我们在ARM S3C4510B上运行嵌入式操作系统uClinux,所以在写程序对HPI接口进行读/写操作时将HPI接口看作一个外部设备,将完成读/写操作的程序看成在uClinux下面的一个字符型驱动。这样软件的设计就变成了在uCLinux下面驱动程序的开发。考虑到S3C4510B不光要将DSP压缩编码完成的数据取过来,而且还要将这些数据传送到网络上去,这就需要这两者之间有很好的配合。
本程序的具体设计大体上可以分成两部分,一部分是对HPI接口进行读/写的程序,另外一部分属于网络编程。由于本文重点是讲解ARM CPU与DSP之间的接口问题,所以在这里介绍HPI接口读/写程序。
 S3C4510B与DSP6416之间的HPI接口读/写程序主要由两个部分组成:1、ARM自身的初始化;2、HPI接口读写程序。
4.1、ARM处理器自身的初始化
 ARM处理器首先要完成自身工作模式等一系列的初始化,才能正常进行HPI接口的读/写,源代码如下所示。
SYSCFG     =  0xe7fffe22;
file://关掉ARM中的Cache
EXTDBWTH  =  0x0ffff556;
file://使外部I/O接口BANK1工作于32位的模式
EXTACON0   =  0x08610000;
file://配置外部I/O接口BANK1的读写时序各控制线之//间的时序关系
上面这段代码主要是对几个寄存器进行配置。在配置好ARM处理器的工作模式后,对外部I/O接口BANK1的对应地址进行读/写操作,就可以完成对HPI接口的相应操作了。

4.2、HPI接口读写程序
以下这些宏定义了DSP6416的HPI接口寄存器的地址。对于本设计来说,已经将HPI口与外部I/O接口的BANK1相接,这样HPI口将占用外部I/O接口BAN1的地址。由于是使用ADDR4来模拟HPI32接口的HR/W,所以对同一个寄存器分别进行读/写操作时,在这里看来是对不同的地址进行相应的操作。
#define HPI_BASE        0x3fd4000      
#define  VPint     *(volatile unsigned int *)
/*定义HPIC寄存器*/                                       
#define  HPICW  (VPint (HPI_BASE+0x0))     0   0   0   0   0   0   0                 
#define HPICR   (VPint (HPI_BASE+0x40))    0   1   0   0   0   0   0  
/*定义HPIA寄存器*/
#define  HPIAW  (VPint (HPI_BASE+0x10))    0   0   1   0   0   0   0
#define  HPIAR   (VPint (HPI_BASE+0x50))    1   0   1   0   0   0   0
/*定义HPID寄存器*/
#define  HPIDW   (VPint (HPI_BASE+0x20))    0   1   0   0   0   0   0
#define  HPIDR   (VPint (HPI_BASE+0x60))    1   1   0   0   0   0   0
 
在定义好上面的宏以后,通过HPI驱动程序就可以将DSP中压缩编码好的视频数据通过HPI口读出来,并送到开辟的用户缓冲区中,等待取完2k大小的数据后再通过网络发送到用户端去。给出HPI驱动程序中读/写数据部分的关键源代码如下[4]:

for(i=0;i<hpiSize;i++)
{
  HPICW=0x00000000;
file://初始化HPI口的控制寄存器
HPIAW=0x80000000;
file://初始化HPI口的地址寄存器,读DSP中地址为0x80000000的存储单元的数据
hpiBaseAddr=HPIDR;
file://通过HPI口读出2K大小的编码数据,并送到数组hpiBaseAddr[ ]中暂存
 }
  CpLen= hpiSize;
  if(copy_to_user( buffer ,(__u8 *)(&hpi->hpiBaseAddr[j]), CpLen))  return -EFAULT;
  file://将暂存在数组hpiBaseAddr[ ]中的数据拷贝到用户缓冲区进行保存。
return CpLen;


6、结束语

 随着科技技术的不断发展,以后基于DSP芯片来执行计算密集型操作,ARM芯片来完成控制,两者配合工作的系统会得到越来越多的应用。而这两者之间能够高效、快速并且稳定的进行数据交换将是影响系统性能的关键部分之一。本文给出的S3C4510B和C6416之间的硬件连接方法和软件设计已经得到过实践的验证,是可行的和满足要求的。不同型号的ARM和DSP之间的接口设计也可以参照本文介绍的方法进行。

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户1425166 2009-4-2 11:20

Nucleus 操作系统 产品描述: Nucleus操作系统是Mentor Graphics嵌入式家族的标志性产品。Nucleus与EDGE开发环境和Inflexion应用设计一起构成一个完整的嵌入式应用开发平台。 除核心模块Kernel外,Nucleus还有文件系统、图形包、网络、USB和总线协议等各种组件,是连接硬件和上层应用之间的完美平台。Nucleus在手机、数字设备、汽车电子、医疗、工控、航空航天、网络、通信等领域得到了广泛应用。 主要特性 Nucleus 95%的代码是用ANSI C写成的,利于移植和支持不同的处理器。Nucleus 采用了软件组件的方法,每个组件具有单一而明确的任务,提供清晰的外部接口,易于替换和复用。Nucleus内核精炼而高效,在典型的目标环境中一般不超过20K。而丰富的功能组件和完备的开发环境更是为嵌入式系统的高级应用奠定了基础。 提供全部源代码 既有利于调试,也有利于学习与研究,更不必担心软件的“后门”。 灵活的授权(Licensing)模式 支持大多数处理器架构 ARM、MIPS、X86、PowerPC、ColdFire、DSP、NIOS II、μBlaze…。 模块化结构 可裁剪、可扩展、可配置。 所有产品同出一源 代码的一致性、兼容性得到保证,与EDGE和Inflexion无缝集成。 无需DSP开发 没有了“抹黑”的烦恼,易学易用,移植方便。 详情请联络:embedtool@163.com 13928420547
相关推荐阅读
用户71670 2010-01-20 16:38
GUN make 语法
译者按: 本文是一篇介绍 GNU Make 的文章,读完后读者应该基本掌握了 make 的用法。而 make 是所有想在 Unix(当然也包括 Linux )系统上编程的用户必须掌握的工具。如果你写的...
用户71670 2009-12-29 10:24
latch与dff区别
6 标签: 无标签 ...
用户71670 2009-12-08 15:09
wxWidgets编译多种库(转载)
这几天研究了一下如何在Debian Lenny下编译wxWidgets,实现多个库共存。有点入门,写出来与感兴趣的朋友一起研究。这里编译的是wxGTK 2.8.7版本,解压后,进入解压的目录,建立4个...
用户71670 2009-10-29 09:10
字符串转化为数字
6.1.2  字符串转化为数字面试例题3:使用库函数将字符串转换为数字。考点:C库函数中字符串转换为数字的使用。出现频率:★★★★解析与上节数字转换为字符串类似,C/C++语言提供了几个标准库函数,可...
用户71670 2009-09-27 16:23
ucf文件约束法
1.约束文件的概念 FPGA设计中的约束文件有3类:用户设计文件(.UCF文件)、网表约束文件(.NCF文件)以及物理约束文件(.PCF文件),可以完成时序约束、管脚约束以及区域约束。3类约束文件的关...
用户71670 2009-09-06 10:12
#pragma使用详解
在所有的预处理指令中,#Pragma>指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全...
EE直播间
更多
我要评论
1
5
关闭 站长推荐上一条 /3 下一条