DSP实时嵌入系统DSP/BIOS学习入门

一、为何接触了DSP/BIOS?

为了得到某些DSP运行中的数据,在尝试了断点实时刷新、printf函数、保存在数组中等三种方式,由于我的系统属于高速时钟以及实时性要求较为严格,前两者直接pass,这两个操作非常费时间,实时性很差,后来了解到了DSP/BIOS这个神奇的方式,尽管最终由于时间的原因没有采取这种方式,但是还是觉得很好奇,就是进行了研究。

二、那点事

本人是机械工程专业,但是感兴趣的确实各种嵌入式系统,没人教、没人指导,全靠谷歌,学的很慢,不知道与其他人比怎么样,更不知道这样学习以后的竞争力又有多少。只能说迷茫,我这样的人可能一抓一大把,学习的入门时间太短。

DSP/BIOS入门学习——以 mailbox example例程为主

跟着官网的说明手册,搭建了一个简单的hello工程,步骤什么的就不作介绍了,跟着文档说的,或者在CCS的help中搜索相关的即可,我的芯片是28335,,属于C28XX系列,总之跟着官网说明走,肯定没问题,至于英文什么的,耐心点总能理解的。以下是mailbox example程序:

C代码

#include <std.h>
#include <log.h>
#include <mbx.h>
#include <tsk.h>
#include "mailboxcfg.h"


#define NUMMSGS         3       /* number of messages */
#define TIMEOUT         10
typedef struct MsgObj {
    Int         id;             /* writer task id */
    Char        val;            /* message value */
} MsgObj, *Msg;


Void reader(Void);
Void writer(Arg id_arg);

/*
 *  ======== main ========
 */
Void main()
{
    /* Does nothing */
}

/*
 *  ======== reader ========
 */
Void reader(Void)
{
    MsgObj      msg;//声明一个结构体变量
    Int         i;

    for (i=0; ;i++) {

        /* wait for mailbox to be posted by writer() */
        if (MBX_pend(&mbx, &msg, TIMEOUT) == 0) {
            LOG_printf(&trace, "timeout expired for MBX_pend()");
            break;
        }
/*MBX_pend这个函数用来读取mailbox里的信息,将第一条信息复制到msg所指向的存储空间。如果邮箱是空的,或是说没有有效的信息,MBX_pend会阻塞。直到等待时间结束,或者进行第二个task。
这个超时时间就是 TIMEOUT,如果设置为0就是不等待,那么就不会读到任何数据*/
        /* print value */
        LOG_printf(&trace, "read '%c' from (%d).", msg.val, msg.id);
    }
    LOG_printf(&trace, "reader done.");
}
/*
 *  ======== writer ========
 */
Void writer(Arg id_arg)//Arg是一个指向类型为空的指针(**问题1**)
{
    MsgObj      msg;
    Int         i;
    Int id =    ArgToInt (id_arg);/*把id_arg转化为long类型,然后与oxffff相与,将结果转化为int类型,任何与oxffff相与都是结果本身。(**问题二**)*/
    for (i=0; i < NUMMSGS; i++) {
        /* fill in value */
        msg.id = id;
        msg.val = i % NUMMSGS + (Int)('a');//分别发送a,b,c三个数据(**问题三**)

        /* enqueue message */
        MBX_post(&mbx, &msg, TIMEOUT);
       /*MBX_post是用来发送信息的。如果mailbox是满的话,MBX_post会阻塞。
        在这种情况下,timeout参数会让进程等待到超时结束,或是不等。等不来的话呢,返回0,就说明什么也没发出去咧,返回1呢,就是发送成功
        */
        LOG_printf(&trace, "(%d) writing '%c' ...", id, (Int)msg.val);

        /* what happens if you call TSK_yield() here? */
        /* TSK_yield(); */
    }

    LOG_printf(&trace, "writer (%d) done.", id);
}

DSP/BIOS

这里主要用到了三个module(clk module已经配置好),一个是LOG module,用来实时显示,如图1
图1:LOG module
一个是TASK module,用来做多任务线程
图2 task module
这个module定义了四个任务,reade0、writer0、writer1、writer2,其中reade0执行reader函数,writer0、writer1、writer2执行writer函数(都是这一个)。
最后一个是MBX module,这个module主要定义邮箱的数据宽度和长度(深度),需要注意的是这里的宽度应该遵循16位编译器,例如TC编译器,int在这个编译器中的长度为2.
图3 MBX module

程序执行分析

图4 执行结果
根据执行的结果起始很容易理解整个程序,首先四个任务的优先级是同等,因此按照顺序执行,在邮箱中的数据为空的时候,reader函数会被堵塞,因此接着执行writer0任务,此时邮箱数据为空,因此写入a、b两个数据,这两个数据类型都被强制转化为了int型因此都是2位长度,写完后邮箱满了,因此writer函数被堵塞,按照顺序执行reader函数,此时数据不为空因此从0中读取a、b数据,然后writer0接着执行,写入c,此时writer0执行完了,只写进去了一个c,然后执行writer1,邮箱只剩一个空位因此只能写入一个a,随后被堵塞,执行任务reader,以此类推。

问题详解

逻辑其实很好理解,应用也不难,关键在于C代码的书写和理解,bios那一部分基本上都是gui的形式,还是很好操作的。
首先最大的问题在于,为什么两个任务函数不是在main函数中,反而main函数是一个空的,do nothing?
这是由于DSP/BIOS是一种实时嵌入式系统,其不是面向过程的编程,而是面向系统,面向过程的编程是对main函数的无限循环,所有的执行函数都在这个main函数中无限循环,而面向系统的编程则是多线程的,可以理解为多条道路,可以在多个函数中无限循环,而main函数则主要起系统初始化的作用,例如要用这种编程方法实现一个LED灯的闪烁,只要在BIOS系统中建立任务,定时、开关,并将这些任务与函数链接起来就可以。

问题1:为什么reader函数没有输入,而writer函数有Arg id_arg?

这是由于writer函数有三个执行任务,这三个任务共同使用一个函数,那么怎么确定是哪个任务在使用这个函数呢?就需要task function arguement来区分,如图5
图5 task function arguement
因此这个实际上输入的是各个任务的 arguement,也就是该例程的任务编号,当然也可以自定义。

问题2: Int id = ArgToInt (id_arg),这一句什么意思?

查看其源代码,这一句的意思是把id_arg转化为long类型,然后与0xffff相与,将结果转化为int类型,任何与oxffff相与都是结果本身,很明显这里是为了提取其id号,id_arg就是输入的arguement,并将其转化为long型,与0xffff相与,然后转化为int型。

问题3:这个问题其实已经说过了

邮箱宽度为2,因此要将数据转化为两位int类型。

补充

有人在运行例程的时候可能会出现这样的问题:
undefined symbol “HW_RESET” used in expression
或者
undefined symbol “PIE_INTXX” used in expression
这是由于hwi.h28文件中有一句代码有问题,找到这样一句: .if (:“cflag”: != 0),将双引号去掉,重新加入include中这个文件的路径即可。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值