介绍一种实时操作系统DSP/BIOS

2006-05-07 15:50:03来源: 电子技术应用

    #include <std.h>

    #include <log.h>

    /* functions */

    void func_printf();

    void func_LOG_printf();

    /* Objects created by the Configuration Tool */

    extern LOG_Obj logTrace;

    /*

    *======== main ========

    */

    void main ()

    {

    return;

    }

    void func_printf(int time)

    {

    printf(″Strart printf demo\n″);

    printf(″Current time=%d \n″ , time);

    printf(″End printf demo\n″);

    return;

    }

    void func_LOG_printf(int time)

    {

    LOG_printf(&logTrace,″Strart LOG_printf demo\n″);

    LOG_printf(&logTrace, ″Current time=%d \n″  time);

    LOG_printf(&logTrace, ″End LOG_printf demo\n″);

    return;

    }

    func_printf()和func_LOG_printf()由DSP内时钟控制每100ms周期性地分别调用一次。通过对printf()和LOG_printf()运行时间作比较发现,在C6211运行在150MHz的情况下,printf()需花费4000个周期约26.7μs,LOG_printf()只花费36个周期约0.24μs。printf()比LOG_printf()多开销100倍以上的时间,因此LOG_printf()对于实时地显示一些运行状态是非常有帮助的。而且对于熟悉C语言的开发者来说,LOG_printf()的调用格式几乎与printf()完全一样。

3 STS

    对一个软件进行分析优化时,通常会用到profile的功能。但是在实时运行的DSP的环境中使用profile等效于加入了多个程序断点。 由于现在的DSP通常具有很深的流水线结构来保证DSP的高运算能力,如德州仪器的C6000系列的流水线长度为12级,程序断点需要排空所有已经进入流水线的指令。这样也就破坏了真正的运行环境。同时profile还必须调用输出模块向主机传递时间信息。因此在profile的情况下真正的实时运行环境是没有办法得到保护的。DSP/BIOS针对这种情况引入了一个统计模块STS。STS对象只有4个数据Previous、Count、Total和Max。调用的方法(API)也只有4个,即STS_add(), STS_set(), STS_delta()和STS_reset()。这些API对数据的操作功能如表1所示。

表1 STS模块方法(API)的功能

STS_add(x) STS_set(y) STS_delta(z) STS_reset()
Previous y Z
Count +1 +1 0
Yotal +x +(z-Previous) 0
Max If x>Max,Max=x If z-Previous>Max,
最大负整数
Max=z-Previous

    如果要对某一段程序进行分析时,只需在其前后调用STS_set和STS_delta就可以了。如例2使用STS测试程序段执行周期如下:

    /* Header files needed for DSP BIOS */

    #include <sts.h>

    #include <clk.h>

    /* functions */

    void func_load();

    /* Objects created by the Configuration Tool */

    extern STS_Obj stsLoad;

    /*

    * ======== main ========

    */

    void main()

    {

    /* fall into DSP/BIOS idle loop */

    return;

    }

    void func_load()

    {

    STS_set(&stsPrintf, CLK_gethtime());

    /* 测试程序段 */

    ...

    STS_delta(&stsPrintf, CLK_gethtime());

    }

    func_load()为一个中断服务程序(ISR)。在C6211,150MHz的情况下,仅插入33个周期,约0.22μs。

4 任务调度(HWI/SWI/TSK)

    一个操作系统的核心永远都是任务的调度。在DSP/BIOS中任务的调度是通过HWI、SWI和 TSK 三个模块来实现的。这三个模块分别对应于不同的调度方法。HWI即硬件中断。在 DSP/BIOS中硬件中断主要负责从外部设备中读写数据。由于硬件中断直接与硬件打交道,所以对应的中断服务程序ISR应该尽可能地短小精悍。需要注意的是HWI并不引起任务调度,因此在ISR的入口和出口成对地调用_HWI_enter()和_HWI_exit()这两个宏是必须的。HWI在处理完数据的输入输出后调用SWI_post()来调度相应的软件中断,SWI来完成数据处理工作。SWI是 DSP/BIOS任务调度的核心,共有14个优先级,每个优先级可以有多个任务。SWI任务是抢断式的,即高优先级的任务可以抢断低优先级的任务。但是SWI任务是不可阻塞的。它的运行状态如图1所示。

    所有SWI任务共享一个堆栈,SWI任务只能在程序编制时预先定义好。DSP/BIOS中对任务的动态产生和对阻塞状态的支持是通过TSK模块来实现的。TSK有15个优先级,也是可以抢断的,但是每个TSK任务使用独立的堆栈。TSK任务是通过TSK_create()和TSK_delete()来动态生成和结束的。它的运行状态如图2所示。

5 同步(SEM/ATM/QUE/MBX

    多任务系统中多个任务之间的协调同步工作可以通过多种方法来实现。常用方法如信号量、原子量、队列和邮箱等。在DSP/BIOS中对这些方法的支持分别通过模块SEM、ATM、QUE和MBX来实现。由于这些方法的使用与一般的操作系统完全一样,在这里就不再赘述了。仅就最灵活的在SWI中使用Mailbox的方法来加以简单地说明。每个SWI任务都带有一个Mailbox,对它的操作可以是计数型的SWI_inc(), SWI_dec() 也可以是比特位操作型的 SWI_or(), SWI_andn()。Mailbox控制SWI任务被调度的条件。这些操作的功能如表2所示。

表2 SWI中Mailbox的操作功能

Mailbox是比特操作 Mailbox是计数操作
总是引起任务调度 SWI_or SWI_inc
仅在Mailbox=0时引起任务调度 SWI_andn SWI_dec

    or操作是将Mailbox中的某一位置1,同时引起SWI任务的调度。当一个SWI任务可能由多个事件触发时,使用or操作可以方便地表示出触发的事件。如例3使用or操作指示触发事件:

    andn操作是将Mailbox中的某一位清0,如果Mailbox为0,则引起SWI任务的调度。一个SWI任务需要多个条件都满足时才运行的情况下,使用andn操作可以方便地表示出这些条件的状态。如例4用andn操作来表示多条件时SWI任务调度:

    inc和dec操作则更加灵活,用户可以借此实现多种应用。唯一需要注意的是,inc操作总是引起任务调度,而dec操作仅在Mailbox减到0时才引起一次任务调度。

6 通讯(PIP/SIO/HST)

    一个系统如何从外部设备中取得数据,向外部设备输出数据,如何在两个任务之间进行数据正常交换是多样灵活的。但是这种多样性也给软件的维护升级以及模块化工作带来许多不利因素。因此在保持多样性的同时,保持接口的一致性对于一个软件来说是非常有帮助的。考虑到DSP大多数是通过某种类型的串行接口如中继线E1、IIS、SPI、同步串行口等与外部设备进行数据交换的,所以在DSP/BIOS中提供了两种非常有用的接口对象PIP和 SIO。

    PIP对象包含一个缓冲队列,与之对应的有两个任务读和写。图3很好地说明了PIP的逻辑关系和操作方式。例5,例6分别是一个PIP对象对应的读任务和写任务的示范程序。

    例5 PIP对应的读任务:

    extern far PIP_Obj pip;

    reader()

    {

    Uns size;

    Ptr addr;

    if(PIP_getReaderNumFrames(&pip)>0)

    {

    PIP_get(&pip);

    addr=PIP_getReaderAddr(&pip);

    size=PIP_getReaderSize(&pip);

    /*Code to empty the frame*/

    PIP_free(&pip);

    }

    else{

    LOG_error(″no frames available″);

    /* or you could just return;*/

    }

    }

    例6 PIP对应的写任务:

    extern far PIP_Obj pip;

    writer()

    {

    Uns size;

    Ptr addr;

    if(PIP_getWriterNumFrames(&pip)>0){

    PIP_alloc(&pip);

    addr=PIP_getWriterAddr(&pip);

    size=PIP_getWriterSize(&pip);

    /* fill the frame up to size */

    PIP_put(&pip);

    }

    else{

    LOG_error(″no frames available″);

    /* or you could just return;*/

    }

    }

    由逻辑关系可以看到,通过使用PIP应用程序可以保持一个简单统一接口而不必关心具体的硬件操作,因此当该软件移植到不同环境中时,至多只需要改写设备驱动程序。使用PIP的一个具体实例就是HST模块。HST模块在主机和DSP之间建立起一条数据链路,该链路就是一个PIP对象。对HST的操作方式与PIP一致。其差别仅仅在于HST在初始化时指向了预定义的DSP上的HPI接口而已。

    SIO:从PIP的逻辑关系可以看出,读写PIP就是一个数据拷贝的过程。这在某些应用中,如实现网络协议TCP/IP时,不是非常有效。因为数据每向上传递一层就需要进行一次数据拷贝,其效率非常差。如果采用SIO来实现就会有很大的改善。SIO的操作只有get()和 put()两种。与PIP不同的是SIO没有自己的缓冲队列。每次get() 或 put() 操作时都会在应用程序和设备驱动程序之间交换缓冲的指针。所以SIO操作的实质是数据地址的交换。由于没有数据拷贝,其运行效率就很高。SIO的运行逻辑如图4所示。

7 RTDX

    实时数据交换Real-Time-Data-eXhange是DSP/BIOS提供的一个全新的功能。在很多应用中要求DSP不能够停下来,而需要从主机中实时地读取数据或者向主机实时地输出数据。德州仪器的C5000,C6000系列的DSP都可以通过JTAG接口来实现这个功能。其逻辑结构如图5所示。

    RTDX在主机端可以与任何符合OLE接口的应用程序交换数据。例7是一个使用RTDX在主机和DSP之间进行数据传递的例子。主机端是一个基于VB的小程序。

    例7 DSP程序:

    #include<rtdx.h>

    RTDX_CreateInputChannel(writeload);

    RTDX_CreateOutputChannel(readload);

    int main()

    {

    RTDX_enableInput(&writeload);

    RTDX_enableOutput(&readload);

    return;

    }

    void doExchange()

    {

    if(!RTDX_channelBusy(&writeload)){

    RTDX_readNB(&writeload,&loadVoal,sizeof(load-Val));

    }

    RTDX_write(&readload,&loadVal,sizeof(loadVal));

    }

    使用VB编制的主机端程序

    set r=CreateObject("RTDX")

    status=r.open("readload","R")

    set w=CreateObject("RTDX")

    status=w.open("writeload""W")

    status=r.ReadI4(data)

    status=w.WriteI4(value,bufferstate)

    综上所述,DSP/BIOS针对DSP的应用环境,通过一系列的对象模块向开发者提供了一个实用优秀的实时操作系统。它可以帮助用户提高软件的模块化、并行性和维护性等,有利于降低系统成本和缩短开发周期。同时由于它是免费的,可以预计DSP/BIOS将对DSP技术在中国的推广使用起到积极的推动作用。

编辑: 引用地址:http://www.eeworld.com.cn/designarticles/dsp/200605/2858.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
论坛活动 E手掌握
微信扫一扫加关注
论坛活动 E手掌握
芯片资讯 锐利解读
微信扫一扫加关注
芯片资讯 锐利解读
推荐阅读
全部

小广播

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 安防电子 医疗电子 工业控制

北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2016 EEWORLD.com.cn, Inc. All rights reserved