首页 | 登录 | 现在注册  [2009年1月9日]
Global Sources
电子系统设计网站

嵌入式系统设计专区 首页 / 论坛 / 自由论坛 / 嵌入式系统设计专区
嵌入式系统已经深人到我们生活的方方面面,未来是嵌入式系统的天下!性能、可靠性、成本、体积和功耗,一个都不能少。遇到困难了么?进入嵌入式系统设计专区,和高手们分享设计经验和技巧!
发表新主题 发表新主题 
加入个人信息中心收藏夹 收藏   打印这个帖子... 打印   关注该主题... 关注   推荐这个帖子... 推荐
楼主      问题: ADSP-TSl01S嵌入式系统的混合编程
发布时间: 2008-9-12 下午3:58

作者: kaifabanlyn
等级: 崭露头角
积分: 459 分

发送消息

查看用户的所有发言

   ADSP-TSl01S是美国ADI公司推出的一款具有极高性能的数字信号处理器(DSP)芯片,其专为大信号处理任务和通信应用进行了结构上的优 化设计,在嵌人式信号处理中得到广泛应用。

        ADSP-TSl01S的软件设计可以采用汇编语言、高级语言(C/C++)或高级语言与汇编语言混合编程。完 全采用汇编编程,执行效率高,但对于复杂算法编写难度大,开发周期长,可读性和可移植性差;而完全采用C编程虽然可以弥补汇编的缺陷,但是程序的执行效率 相对较低,大概只有汇编程序的10%~20%,对于实时性要求很高的处理,如雷达信号处理,很难满足要求。采用混合语言编程,用c语言构建框架,用汇编完 成运算量较大的核心处理模块及硬件底层管理,就可以把两者的优点有效地结合起来。C和汇编语言的混合编程有三种形式:一是对C程序编译后形成的汇编程序进 行手工修改与优化;二是直接在C代码中插入汇编语句,只需在汇编语句两边加上双引号和括号,在括号前面加上标识“asm",如asm (“汇编语句”);三是分别编写C程序和汇编程序,再独立编译成目标代码模块链接。第一种方法对程序可读性负面影响较大。第二种 方法适用于C与汇编效率差异较大的情况,如进入中断的中断子程序等。第三种方法最常用,需要遵循一些规定的接口规范和标准。

        1 混合编程的接口规范和标准   

        CC++环境下,TigerSHARC定义了一套严格的寄存器规则,它分为三类:
   

         第一类是保留寄存器,j16j25k16k25xr24xr31yr24yr31,共40个,作为编译系统库函数专门使用的寄存器。编写程 序时应避免使用这些寄存器,以免误改了系统库函数。若在子程序中使用到,必须在被调用时保存,调用完后释放。
   

        第二类是堆栈专用寄存器,k2627j26j27四个,这些寄存器在调用时都需要保护。
   

        第三类是高速暂存寄存器,包括除了以上两类寄存器以外的所有寄存器。用法和汇编中的普通寄存器是一样的,使用前不需要保存寄存器内容。

        在默认情况下,cjmp寄存器用作存放被调函数的返回地址,但在嵌套调用中,这个值会被修改。为了保证安全返回,一般把返回地址存放在堆栈顶偏移地址为0的地方。

        函数调用有时需要参数传递,通常,若参数少于5个,则通过寄存器传递

如果在CC++调用函数中作了正确的函数返回声明,则被调用的汇编函数可使用寄存器j8xr8xr9返回有效值。j8用于返回整数或地址;xr9 8可提供双字结果返回。若返回值大于2个字长,则必须为它们分配存储空间,令j8为返回值,指向该空间的首地址即可。

       CC++中声明的全局变量及函数,汇编中加前缀才能使用;在汇编中的对象必须用前缀 命名,并用.g10bal声明为全局变量,才可在CC++中访问到。

每调用一 次函数,就建立一个新帧。C环境利用局部帧来实现如下功能:

       保护函数的返回地址及相关寄存器:把函数返回地址保存在j27+0的位置(栈顶),同时设置jZ6j27-0x40(栈底),得到长度为64的栈区,并在栈区内保护相关寄存器。
      
分配局部变量:在局部变量赋初值的时候,系统在堆栈内给它分配一个空间。
       
传递函数参数:前4个参数传递给相应寄存器(见表1),后续参数按顺序装载到堆栈j27+0xC起始的空间中。注意,如果传递的参数是结构类型,则其所 有元素将入栈。例:第五个参数是两元素的结构体,则元素一放于jZ7+0xC,元素二放于j27+0xD,汇编子程序在使用参数时只需从对应的位置上读取 即可。

        C环境在调用C函数时自动管理这些操作,当汇编与C接口时,必须采用与C一样的方式进行操作。这个过程可用图1详细描述。特别需要注意的是,由于C编译器 不提供检查堆栈溢出的任何手段,因此必须保证有足够的空间用于堆栈;否则若发生溢出现象,将破坏程序的运行环境,从而导致程序的瘫痪。

      2.2
   

       中断是DSP控制程序执行的重要方式。通常,DSP工作在包含多个外部异步事件的环境中,这些异步事件的随机发生要求DSP能中断当前的处理程序并转向执行 该事件处理程序,执行完后又要求返回被中断的原程序继续处理步骤,这一过程就是中断。中断源可以来自片内或片外的设备,例如时钟、AD等。中断的设置包 含两步——打开中断屏蔽寄存器的相应中断位,设置中断服务程序的入口地址,这样就能实现中断的正常运行。中断服务程序是特殊 的函数,不能带返回值,不能传递参数,内容须短而有效。标准运行模式为:保存断点地址并保护所有用到的寄存器,执行中断服务程序,释放寄存器并返 回。

       ADSP-TSl01sC语言中断实现有两种方法:一种是采用interrupt(intvuid(*func(int)))函数来设置中断矢量表, 这个函数定义在signal.h头文件中。第一个参量表示需响应的中断位,在这个头文件中也有定义;第二个参数即是中断服务程序。应该引起注意的是,采用 这种方法时,IMASK寄存器的异常中断位必须打开,因为interrupt()库函数要使用trap语句来产生陷阱,必须打开异常中断,陷阱才能设置成 功,中断矢量表的设置才能完成,否则,中断来l临并不会进入指定的中断服务程序。另一种与汇编语言中断服务程序的实现类似。以定时器O为例,设置好 IMASK后,用_builtin_sysreg_write(_TIMEROHP(int)timer0h_isr)函数设置中断矢量表,用 #pragma interrupt来标识中断服务程序即可。这种方法更简单快捷,但它只适用于Visua1DSP++3.5以上版本,而第一种方法适用于任何版本。

      3 程序优化
   

      程序优化包括汇编优化和C优化。手写汇编程序的优化空间相当大,可以产生非常高效的程序代码。由于许多相关书籍都有介绍,就不再赘述,这里主要介绍C程序的优化。

        一般DSPC编译器都会提供优化编译器,采用优化编译就可以生成效率更高的汇编代码,在某些情况下,执行优化的程序代码要快1020倍。从某种程度上 说,C程序的效率主要取决于C编译器所能进行优化的范围和数量。应说明的是,TSl01S编译器的默认设置是不使用优化器,它可以进行以下几个不同级别的 优化,优化程度由低到高:

        Debugging“-g”开启。编译器产生调试信息,以确保目标码与相应的源代码匹配。
       
DefauIt:编译器进行基本的高级优化。例如对明确标明的内联函数进行内联。
        
Procedural optimization“-o”启动。编译器对要编译的文件中的每一过程进行高级优化。如果同时开启“- g”,由于“-O”项有更高的优先级,会限制调试功能。

        
Interprocedural optimization“-ipa"打开。除了基本优化外,编译器将对所有源文件的整个程序进行高级优化操作,将删除从没被调用的函数和变量,会明显减少代码长度。

        以上“-g”“-O”“-ipa”在编译信息中可以看到。优化级越高,优 化的范围就越广。应注意的是,使用C优化编译可以提高程序的运行效率,但由于优化时采用了一些优化措施,使得C和汇编的交叉列表文件不如在不用优化时得到 的那样清晰。因此,在调试程序时,最好先不用优化编译进行调试,待程序调试成功后再用优化编译进行优化。采用C优化编译时,为了保证程序的正确性,特别需 要注意几点:

        使用asm行汇编语句时必须特别小心。优化器在优化过程中会对程序代码重新进行组织,寄存器使用也比较灵活,同时程序中的有些变量或表达式可能会被删 除。虽然asm语句不会被删除,但asm语句的前后环境可能因优化而发生很大的变化。因此,当asm语句涉及到C环境或访问C变量时,使用优化器可能会得 到不正确的结果。此时,必须对编译后得到的汇编语句进行仔细的检查,以确保asm语句在程序中的正确性。一般而言,当asm语句仅涉及诸如控制中断寄存器 I0口等硬件操作时,使用优化是比较安全的。

       在高级优化中,C语言源函数中从未使用过的变量和函数将被删除。若汇编子函数的C外部变量在C程序中从未使用过,有可能被删除并导致编译失败。使用retain_name pragma可以避免变量和函数因优化而被删除。

使用volatile变量避免优化。一个定义为volatile的变量是说这个变量可能会被意想不到地改变,比如,并行设备的硬件寄存器(如状态寄存 ),一个中断服务子程序中会访问到的非自动变量,多线程应用中被几个任务共享的变量。采用volatile限定词,优化器在用到这个变量时必须每次都重 新读取这个变量的值,而不是使用保存在寄存器里的备份。

       C语言程序应尽量避免使用指针运算。指针转换会在一定程度上降低运行效率。
       
“-ipa'’使能的情况下,在循环前使用#pragmann_alias可以起到进一步优化程序的功能。一般来说,对于循环中不存在迭代运算(使用上一次结果)的情况,优化效果很好。
      
使用PM限定词定义数据块。默认情况下数组存放在DM区,即第一块数据区(0x80000-0x8ffff)中。使用PM限定的数组放在第二块数据区 (0x100000-0x10ffff)中。由于两块数据区有独立的128位数据总线相连,因此可以实现单周期内的双数据同时访问。

      4 混合编程在系统程序管理中的应用

      下面是一个嵌入式系统管理实例。系统由4 DSP构成,作为系统管理的DSP0负责通过IRQ0接收控制台从RS232串口传来的控制字,译码,并通过控制flag3产生下降沿触发IRQ3中断来 启动其他各片DSP。这里用C搭建框架,汇编控制底层硬件,效率高,可读性强。由于篇幅限制,这里略去了串口初始化、串口数据接收函数以及其他芯片的处理 程序。

5    

       实践证明,采用混合编程的软件更加符合一般系统对时间和空间的严格约束。设计良好的混合编程软件既能有效满足嵌入式系统对功能与性能的需求,也可以为程序的扩展和移植预留足够的空间。总之混合编程是嵌入式系统软件优化的重要途径。


掌声 (
0
)
板砖 (
0
)
   回复该主题... 回复   引用这个帖子... 引用 
发表新主题 发表新主题

实用内容通道
最新行业新闻
系统设计指南
技术资料下载中心
实用电路设计
近期最热文章
网站专题总汇
 
精品设计专栏赏析
绿色能源设计专栏
医疗电子设计专栏
HDTV设计专栏
汽车电子设计专栏
4G/3G设计专栏
机器人设计专栏
HDMI接口设计专栏
ESD保护设计专栏
工业控制应用设计专栏
微波与射频设计专栏
 

更多专题...


个性化主页


电子系统设计个性化主页!
境界决定成就,
开辟属于您的专属"境界" !


共享资源
上千份技术资料免费提供!嵌入式软件EDA/IC设计两大栏目上线!

软件编程论文30篇
数字信号处理教程
华为PCB布线规范
嵌入式入门笔记
51单片机C语言编程手册

进入资源首页 分享资料
 
返回论坛首页
 
eMedia: 电子工程专辑 | 手持电子设备 | 家庭娱乐系统 | 工业控制 | 汽车电子设计 | 电源系统 | 模拟混合信号 | 国际电子商情
环球资源: 环球资源企业网 | 环球资源内贸网 | 供应商服务网站 | 世界经理人 | Electronic Components | Computer Products | China Sourcing Fairs
 
 
RSS新闻聚合 | 意见反馈 | 网站导航 | 帮助 | 关于我们 | 隐私政策 | 联系我们 | 使用条款 | 安全承诺
Copyright ©   eMedia Asia Ltd. 本网站所有内容均受版权保护。
未经版权所有人明确的书面许可,不得以任何方式或媒体翻印或转载本网站的部分或全部内容。