<?xml version="1.0" encoding="gbk"?> <rss version="2.0"><channel> <title>定阅帖子更新</title> <link>http://www.broadkey.com.cn/XML.ASP</link><description>TEAM Board - 科伟奇电子</description> <copyright>TEAM 2.0.5 Release</copyright><generator>TEAM Board by TEAM5.Cn Studio</generator> <ttl>30</ttl><item><link>http://www.broadkey.com.cn/Thread.asp?tid=374 </link><title>TMS320C6X应用中的几个关键问题</title><author>air</author><pubDate>2009/12/11 8:24:21</pubDate><description><![CDATA[TMS320C6X是TI公司针对通信应用推出的高档32位定点、浮点DSP系列产品，采用352脚BGA封装。该系列<br />
<br />
器件中C62X为定点型、C67X为浮点型，代码兼容，皆采用VelociTI结构。这种高性能、超长指令字VLIW<br />
<br />
的结构使得其成为多信道、多功能应用的首选对象。VLIW通过提高指令级的并行性获得高性能。<br />
<br />
VelociTI结构灵活，对如何及何时取指令、执行指令或存储指令的限制很少。VelociTI结构的突出特点<br />
<br />
包括：指令打包减少代码大小、可条件执行所有指令提高灵活性、根据数据类型指令的宽度可变、完全<br />
<br />
流水线的跳转。<br />
　<br />
　　TMS320C6X的CPU核由32个32bit宽的通用寄存器和8个功能单元（6个ALU和2个乘法器）组成。C6X的<br />
<br />
地址空间为32bit的可字节寻址空间，片内存储区分成独立的数据、程序空间，通过各自的内部端口访问<br />
<br />
。C6X的外围设备用于配合CPU工作，主要包括多通道缓冲串口McBSP、定时器Timer、外部存储器接口<br />
<br />
EMIF、DMA控制器、HPI及降功耗单元。<br />
　<br />
　　TMS320C6X功能强大、灵活，在性能上具有以下突出优点：C62X的指令周期为5ns、时钟速率200MHz<br />
<br />
、C67X的指令周期为6.5ns、时钟速率167MHz、每时钟周期可执行8条32bit的指令、最高峰值运算速度达<br />
<br />
1600MIPS.&nbsp;TMS320C6X的指令集更为丰富，且功能分类明确、编程简单。TI公司为TMS320C6X提供了功能<br />
<br />
强大的C编译器，支持优化功能。本文根据作者在实际工程中使用C62&nbsp;01的一些具体体会，介绍了<br />
<br />
TMS320C6X应用中的几个关键问题。作者在实践中使用的TMS320C6X&nbsp;C编译器的版本为2.0版，以下的讨论<br />
<br />
都基于该版本。<br />
　<br />
　　加载程序：1&nbsp;问题的提出：利用外部引脚BOOTMODE[4&hellip;&hellip;0]来选择BOOT配置，在MAP1及ROM&nbsp;BOOT方<br />
<br />
式下，C620&nbsp;1以DMA方式将32KB的程序从CE1空间加载到地址0上。<br />
　<br />
　　Ｃ或汇编写的程序经链接生成。obj目标文件，目标码是以段为单位组织的。可将所有的段分为两类<br />
<br />
：已初始化段和未初始化段。已初始化段。text&nbsp;段中包含所有可执行的代码以及常量，被固定连接至程<br />
<br />
序空间，存储器类型可以是ROM或RAM（一般为ROM，具体取决于编译时RAM或ROM方式的选择）；其有两个<br />
<br />
地址：load地址和run地址。。text段在C6201上电复位后会由默认的引导程序（boot.c）从外部F&nbsp;LASH<br />
<br />
中BOOT到内部程序存储区PMEM里，可引导加载的程序大小为32KB，一般应用下可以满足要求，但是当系<br />
<br />
统比较复杂、程序代码超过32KB时，在这种默认方式下程序就不能正常运行了。<br />
　<br />
　　2&nbsp;解决方案：编写一段小程序使其在上电复位后由引导程序加载到PMEM中，而它的作用就是利用DMA<br />
<br />
搬移一段程序。将真正需运行的主程序生成的。obj文件中的。text段命名为自己定义的一个段，将其<br />
<br />
LOAD（安装）到外部FLASH中，BOOT（引导）到PMEM中的程序运行后启动DMA，将其搬移到PMEM中。具体<br />
<br />
实现时需注意：（1）DMA的初始化配置，源地址为外部FLASH，目的地址为内部PMEM；若以字为单位传送<br />
<br />
，则DMA计数寄存器中的值给出的搬移块的大小也是以字为单位，必须匹配，实际搬的程序大小换算成以<br />
<br />
字为单位。<br />
　<br />
　　（2）DMA的搬移需判断是否完成。DMA基本控制寄存器中的STATUS位会有指示，当搬移完成后才可进<br />
<br />
入真正需运行的主程序。<br />
　<br />
　　（3）因默认的BOOT程序大小为32KB，所以需要DMA搬移的程序应LOAD到32KB空间以外。且映射到一<br />
<br />
个不同于。text段的自定义段中，这可在lnk.cmd文件中定义。<br />
　<br />
　　举例说明（其中example.c为需要DMA搬移的程序，。examp为自定义段，未给出其它与本例无关的内<br />
<br />
存分配及段的映射）：lnk.cmd中相关定义：PMEM1&nbsp;o=0x00000200&nbsp;l=0x00000A00&nbsp;PMEM2&nbsp;o=0x00000C00&nbsp;<br />
<br />
l=0x0000F000&nbsp;CE1PMEM1&nbsp;o=0x01400200&nbsp;l=0x00000A00&nbsp;CE1PMEM2&nbsp;o=0x01408000&nbsp;l=0x0000F000。text&nbsp;<br />
<br />
load=CE1PMEM1&nbsp;run=PMEM1。examp：&nbsp;{example.obj（。text）}&nbsp;load=CE1PMEM2&nbsp;run=PMEM2中断处理：<br />
<br />
C62X/C67X的CPU根据优先级有三种类型的中断：RESET、NMI、INT4～INT15.RES&nbsp;ET为低有效，具有最高<br />
<br />
优先级，在上电复位时正确初始化CPU；NMI为次高优先级中断，当发生严重的硬件错误时，会保护CPU；<br />
<br />
INT4~INT15为12个可屏蔽中断，它们与外部器件、片内外设有关，可软件控制。<br />
处理中断时必须包含库中提供的相关函数（intr.h、intr.c、intr_.asm），它们给出了与中断有关的函<br />
<br />
数和变量定义。用C写中断服务子程序包括以下4部分：（1）选择中断源并写中断服务子程序ISR；（2）<br />
<br />
产生并初始化中断向量表；（3）设置相应的寄存器使能并处理中断；（4）在链接命令文件中将各部分<br />
<br />
链接在一起。<br />
　<br />
　　下面以响应外部中断4为例，给出具体的中断处理流程：（1）初始化中断intr_init（），初始化<br />
<br />
ISTP，其值为中断服务表的首地址；（2）将外部中断源4映射到CPU中断4上：intr&nbsp;map（CPU&nbsp;INT4，ISN&nbsp;<br />
<br />
EXT&nbsp;INT4），置中断选择寄存器相应位置处值为中断服务号4；（3）装载中断服务子程序：intr_hook（<br />
<br />
fp，CPU_INT4），函数指针指向中断处理表中的相应表项；（4）手动清除中断标志寄存器IFR中的中断<br />
<br />
标志位：INT_CLR_FLAG（CPU_INT4），保证IFR任何比特域中没有不必要的值；（5）使能非屏蔽中断NMI<br />
<br />
，否则其余中断皆不能处理，中断使能寄存器IER中的NMI&nbsp;E位置１：INTR_ENABLE（CPU&nbsp;INT&nbsp;NMI）；（6<br />
<br />
）使能CPU中断4，中断使能寄存器IER中的相应位置１：INTR_ENABLE（CPU&nbsp;INT４）；（7）通过设置控<br />
<br />
制状态寄存器CSR中的GIE位，全局使能所有可屏蔽中断：INTR_GL&nbsp;OBAL_ENABLE（）。<br />
　<br />
　　CPU实际处理中断时，参考中断服务表IST.IST是一个用于服务中断的含代码的取包表，IST包含16个<br />
<br />
FP，每个ISFP包含8条指令，一个中断服务子程序匹配一个FP。中断到达时，将该ISR的入口地址装入到<br />
<br />
跳转表isr_jump_table中相应的表项里，中断执行完后，&ldquo;中断返回指针&rdquo;指令B&nbsp;IRP保证可返回到主程<br />
<br />
序中。C中可直接处理中断，或用关键字interrupt&nbsp;void&nbsp;函数名（）来定义一个中断服务子程序，或用<br />
<br />
#pragma&nbsp;INTERRUPT（函数名）。下面举例说明：#include&lt;intr.c&gt;&nbsp;int&nbsp;n=0；interrupt&nbsp;void&nbsp;<br />
<br />
intr_prg（void）&nbsp;定义中断服务子程序{&nbsp;n=1；&nbsp;}&nbsp;void&nbsp;main（）<br />
　<br />
　　{&nbsp;intr_init（）；intr_map（CPU_INT4，ISN_EXT_INT4）；intr_hook（&amp;intr_prg，CPU_INT4）；<br />
<br />
INT_CLR_FLAG（CPU_INT4）；INTR_ENABLE（CPU_INT_NMI）；INTR_ENABLE（CPU_INT4）；<br />
<br />
INTR_GLOBAL_ENABLE（）；while（n==1）&nbsp;{&hellip;&hellip;}&nbsp;}&nbsp;C与汇编的嵌套调用：虽然，C语言是一种相对高效<br />
<br />
的高级语言，并且TI提供的C编译器还结合硬件特点支持三级优化功能，但生成的汇编代码效率仍可能会<br />
<br />
不尽人意。采用C与汇编的混合调用，既可以用C做高层控制，又可以通过汇编提高效率。<br />
　<br />
　　1&nbsp;C调汇编：在C语言中使用汇编语言，可采取两种方式：一是调用汇编子程序，二是使用嵌入汇编<br />
<br />
。<br />
　<br />
　　（1）调用汇编子程序TMS320C6X&nbsp;C编译器在处理函数调用时，关于如何传递入口参数以及如何返回<br />
<br />
出口参数制定了一套严格的规则。在TMS320C6X&nbsp;C程序中调用汇编语言子程序，必须遵循这些规则。首先<br />
<br />
在C中声明调用的汇编函数为外部的，若其返回值为整形则可不声明。在严格遵循入出口参数传递及寄存<br />
<br />
器约定的前提下，调用汇编子程序和调用C子程序一样。<br />
　<br />
　　（2）嵌入汇编在C中调用汇编语言子程序，要求严格遵循其参数传递规则。由于TMS320C6X&nbsp;C编译器<br />
<br />
支持在C源代码中直接用asm语句嵌入汇编，故在C编译器所产生的中间汇编代码的基础上，可局部使用嵌<br />
<br />
入汇编，格式为：asm（<em>&quot;</em>&nbsp;assemble&nbsp;statement<em>&quot;</em>）。这样，一方面可大大提高一些频繁使用的代码段的<br />
<br />
效率，另一方面，又不用改变原来的程序框架，也便于对照仿真结果进行调试。在进行嵌入汇编时，要<br />
<br />
特别注意流水线的冲突。TMS320C6X&nbsp;采用3级流水线结构，在出现流水线冲突的地方，可插入空操作<br />
<br />
（nop）指令来解决。<br />
　TMS320C6X&nbsp;的应用一般较为复杂，因此，完全采用汇编语言进行编程将是一件很困难、也很低效的事<br />
<br />
情。而C语言以其灵活性、易移植性，已成为单片机开发的一种趋势，对于更为复杂的DSP应用来说，更<br />
<br />
是如此。在汇编中调用C子程序同样必须遵循其函数调用规则和寄存器使用规则。首先在汇编中声明C子<br />
<br />
程序为。global型，传递的参数依次在A4、B4、A6、B6、A8、B8、A10、B10、A12、B12或堆栈中，传递<br />
<br />
数组或指针皆只是将其地址置于相应的参数寄存器中，返回值存在A4中。<br />]]></description></item></channel></rss>