【分享】+DSP/BIOS的基础应用一例

[复制链接]
4157|28
 楼主| msblast 发表于 2013-12-25 13:41 | 显示全部楼层 |阅读模式
本帖最后由 msblast 于 2013-12-25 14:55 编辑

本例中使用到的BIOS的组件有BUF,QUE,MBX,PRD,TSK等,现在将这过程与大家分享。

一、新建一个优先级最高的task,如下图


二、软件通用定时器
因为在软件运行过程中,有很多地方需要用到定时。所以写了一个软件定时器,方便使用。

在BIOS中配置,如下图



每一个定时器实例都给分配了内存空间,这是通过BIOS的内存池来实现的,如下图

CtmrCreate/CtmrRelease就是基于这个内存池来实现的


通用定时器的CtmrStart/CtmrStop是通过队列的入列和出列来实现的,也是用的BIOS的队列机制,如下图

队列的数据存储空间也是基于BIOS的BUF组件实现的,如下图


代码实现如下

  1. /*Ctmr.h*/
  2. #ifndef __CTMR_H__
  3. #define __CTMR_H__
  4. #include <std.h>

  5. #include <log.h>
  6. #include <mem.h>
  7. #include <que.h>
  8. #include <sys.h>
  9. #include <tsk.h>

  10. typedef void (*fxn_ptr)(void);
  11. typedef void (*fxn_tmr_cb)(void *cb);

  12. typedef struct _Ctmr {
  13.       Int32 tmrcnt;
  14.       Int32 delay;
  15.       Int32 exe_times;
  16.       Int32 execnt;
  17.       void *params;
  18.       fxn_tmr_cb cb;
  19.       Uint8 bSync;
  20. } CtmrObj;
  21. typedef struct _CtmrQ_Obj {
  22.       QUE_Elem    elem;
  23.       CtmrObj     *ct;
  24. } CtmrQ_Obj, *CtmrQ;

  25. #define CTMR_BASIC_TICK (10)
  26. #define CTMR_EXE_FOR_EVER (0)

  27. Uint32 CtmrCreate(Int32 dly, Int32 exe_times, void *params, fxn_tmr_cb cb);
  28. void CtmrRelease(Uint32 nHdlr);
  29. void CtmrStart(Uint32 nHdlr);
  30. void CtmrStop(Uint32 nHdlr);
  31. void CtmrExeCB(Uint32 nHdlr);

  32. #endif

  1. /*Ctmr.c*/
  2. #include <std.h>
  3. #include <tsk.h>
  4. #include <stdio.h>
  5. #include "timer.h"
  6. #include "c6x.h"

  7. #include "ctrl_task.h"
  8. #include "ctmr.h"
  9. #include "xxxcfg.h"
  10. /*xxxcfg.h由配置工具自动生成*/


  11. /*CtmrCreate给一个新创建的定时器实例分配内存并进行初始化,然后返回内存地址,如果分配不到内存则返回0*/
  12. Uint32 CtmrCreate(Int32 dly, Int32 exe_times, void *params, fxn_tmr_cb cb) {
  13.     Uint32 nHdlr = 0;
  14.     CtmrObj *hTmr = 0;
  15.     do {
  16.           hTmr = (CtmrObj *)BUF_alloc(&Ctmr);
  17.           if(!hTmr) {
  18.                 break;
  19.           }
  20.           if(!dly) {
  21.                 dly = CTMR_BASIC_TICK;
  22.           }
  23.           dly = ((dly+(CTMR_BASIC_TICK-1))/CTMR_BASIC_TICK)*CTMR_BASIC_TICK;
  24.           hTmr->cb = cb;
  25.           hTmr->delay = dly;
  26.           hTmr->tmrcnt = 0;
  27.           hTmr->exe_times = exe_times;
  28.           hTmr->execnt = 0;
  29.           hTmr->params = params;
  30.           hTmr->bSync = 0;
  31.           nHdlr = (Uint32)hTmr;
  32.     }while(0);
  33.     return nHdlr;
  34. }
  35. /*CtmrRelease释放给定时器实例分配的内存,在这之前先关闭定时器,这主要是防止使用的人忘记停止定时器*/
  36. void CtmrRelease(Uint32 nHdlr) {
  37.     CtmrObj *hTmr = (CtmrObj *)nHdlr;
  38.     if(hTmr) {
  39.         CtmrStop((Uint32)hTmr);
  40.         BUF_free(&Ctmr, (void *)hTmr);
  41.     }
  42. }
  43. /*CtmrStart启动一个定时器,将定时器实例加入队列;如果这个定时器实例之前已在队列中则先移出队列*/
  44. void CtmrStart(Uint32 nHdlr) {
  45.     Uns oldCSR;
  46.     CtmrObj *hTmr = (CtmrObj *)nHdlr;
  47.     CtmrQ ctqelem = 0;
  48.     QUE_Elem *qelem = QUE_head(&CtmrQue);
  49.     if(hTmr) {
  50.         while (qelem != &CtmrQue) {
  51.            if(((CtmrQ)qelem)->ct == hTmr) {
  52.             break;
  53.            }
  54.            qelem = QUE_next(qelem);
  55.         }
  56.         if (qelem != &CtmrQue) {
  57.             oldCSR = HWI_disable();
  58.                QUE_remove(qelem);
  59.                HWI_restore(oldCSR);
  60.                BUF_free(&CtmrQueBuf, (void *)qelem);
  61.         }
  62.         ctqelem = (CtmrQ)BUF_alloc(&CtmrQueBuf);
  63.         if(ctqelem) {
  64.             hTmr->tmrcnt = 0;
  65.             hTmr->execnt = 0;
  66.             hTmr->bSync = 0;
  67.             ctqelem->ct = hTmr;
  68.             oldCSR = HWI_disable();
  69.             QUE_put(&CtmrQue, ctqelem);
  70.             HWI_restore(oldCSR);
  71.         }
  72.     }
  73. }
  74. /*CtmrStop将定时器实例移出队列,并释放为队列分配的内存*/
  75. void CtmrStop(Uint32 nHdlr) {
  76.     Uns oldCSR;
  77.     CtmrObj *hTmr = (CtmrObj *)nHdlr;
  78.     QUE_Elem *qelem = QUE_head(&CtmrQue);
  79.     if(hTmr) {
  80.         while (qelem != &CtmrQue) {
  81.            if(((CtmrQ)qelem)->ct == hTmr) {
  82.             break;
  83.            }
  84.            qelem = QUE_next(qelem);
  85.         }
  86.         
  87.         if (qelem != &CtmrQue) {
  88.         oldCSR = HWI_disable();
  89.            QUE_remove(qelem);
  90.            HWI_restore(oldCSR);
  91.            BUF_free(&CtmrQueBuf, (void *)qelem);
  92.         }
  93.     }
  94. }

  95. /*CtmrExeCB执行CtmrCreate注册的回调函数*/
  96. void CtmrExeCB(Uint32 nHdlr) {
  97.     CtmrObj *hTmr = (CtmrObj *)nHdlr;
  98.     if(hTmr) {
  99.         if(hTmr->cb) {
  100.             hTmr->cb(hTmr);
  101.         }
  102.     }
  103. }
  104. /*CtmrExe在prd_tmr中周期执行*/
  105. void CtmrExe(void) {
  106.     MsgObj      msg;
  107.     CtmrObj *hTmr = 0;
  108.     QUE_Elem *qelem = QUE_head(&CtmrQue);
  109.     while (qelem != &CtmrQue) {
  110.        hTmr = ((CtmrQ)qelem)->ct;
  111.        if(hTmr) {
  112.         if(hTmr->bSync) {
  113.             hTmr->tmrcnt++;
  114.             if((hTmr->tmrcnt*CTMR_BASIC_TICK) == hTmr->delay) {
  115.                 msg.id = EVT_IND_CTMR_EXE_CB;
  116.                 msg.val = (Uint32)hTmr;
  117.                 MBX_post(&CtrlEvt, &msg, 0);
  118.                 hTmr->tmrcnt = 0;
  119.                 if(hTmr->exe_times != VTIMER_EXE_FOR_EVER) {
  120.                     hTmr->execnt++;
  121.                     if(hTmr->execnt == hTmr->exe_times) {
  122.                         msg.id = EVT_IND_CTMR_EXE_POST_CB;
  123.                         msg.val = (Uint32)hTmr;
  124.                         MBX_post(&CtrlEvt, &msg, 0);
  125.                     }
  126.                 }
  127.             }
  128.         }
  129.         else {
  130.             hTmr->bSync = 1;
  131.         }
  132.        }
  133.        qelem = QUE_next(qelem);
  134.     }
  135. }
  136. void prd_tmr() {
  137.   CtmrExe();
  138. }
通用定时器的使用,遵守以下步骤

1.CtmrCreate,创建一个定时器实例
2.CtmrStart,启动定时器实例
3.CtmrStop,停止定时器实例,定时器实例仍然存在,没有销毁
4.CtmrRelease,销毁定时器实例

三、使用mailbox实现事件驱动架构

事件驱动的架使得代码看起来更清晰明了,基于BIOS的MBX和BUF实现的,如下


代码实现如下

  1. /*Ctrl_task.h*/
  2. #ifndef __CTRL_TASK_H__
  3. #define __CTRL_TASK_H__
  4. #include<stdlib.h>
  5. #include "ctmr.h"
  6. .
  7. .
  8. .

  9. typedef struct MsgObj {
  10.     Uint32 id;             /* event id */
  11.     Uint32        val;            /* message value , address of content*/
  12. } MsgObj, *Msg;

  13. enum {
  14.     .
  15.     .
  16.     .
  17.     ,EVT_IND_CTMR_EXE_CB
  18.     ,EVT_IND_CTMR_EXE_POST_CB
  19.     .
  20.     .
  21.     .
  22.     ,EVT_NUM
  23. };
  24. .
  25. .
  26. .
  27. #endif
  1. /*Ctrl_task.c*/

  2. #include <std.h>
  3. #include <c6x.h>
  4. #include "pal_os.h"
  5. #include "psputils.h"
  6. #include "ctrl_task.h"
  7. #include "xxxcfg.h"
  8. /*xxxcfg.h由配置工具自动生成*/
  9. .
  10. .
  11. .
  12. void Task_Ctrl(){
  13.   MsgObj      msg;
  14.   Uint32 Evtid;
  15.   .
  16.   .
  17.   .
  18.   do {
  19.     if (MBX_pend(&CtrlEvt, &msg, SYS_FOREVER)) {
  20.       Evtid = msg.id;
  21.       switch(Evtid) {
  22.         .
  23.         .
  24.         .
  25.         case EVT_IND_CTMR_EXE_CB:
  26.           CtmrExeCB((Uint32) msg.val);
  27.           break;
  28.         case EVT_IND_CTMR_EXE_POST_CB:
  29.           CtmrStop((Uint32)msg.val);
  30.           break;
  31.         default:break;
  32.       }
  33.     }
  34.   }while(1);
  35. }

四、一些体会和建议
掌握通过通用定时器和事件驱动框架,可以很方便的扩展和衍生出很多的功能。


有些问题是在实践过程中才逐步暴露出来的,一段成熟的代码需要一个不断完善的过程。


有细心的童鞋会发现我没有用malloc/free和MEM_alloc/MEM_free,而是用了BUF_alloc/BUF_free 。如果你没有经过我的提醒就意识到了这个问题,我会很高兴看到同道。是的,BIOS HWI中不允许调用malloc/free和MEM_alloc/MEM_free。另外,就算是在TSK中也不要过于频繁的调用malloc/free和MEM_alloc/MEM_free。这是我的体会,也是建议。
你也可以来补充。









本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评分

参与人数 1威望 +3 收起 理由
zhangmangui + 3 很给力!

查看全部评分

zhangmangui 发表于 2013-12-25 14:40 | 显示全部楼层
顶  楼主多多分享这方面的东西
 楼主| msblast 发表于 2013-12-26 11:12 | 显示全部楼层
zhangmangui 发表于 2013-12-25 14:40
顶  楼主多多分享这方面的东西

多谢支持:lol
希望TI论坛以后多搞点活动啊

用过多家的平台之后,个人最喜欢的就是TI的了。
zhangmangui 发表于 2013-12-26 11:30 | 显示全部楼层
msblast 发表于 2013-12-26 11:12
多谢支持
希望TI论坛以后多搞点活动啊

只要兄弟们多多支持   我一定会争取的
拿起书本 发表于 2013-12-26 15:37 | 显示全部楼层
正在学习掌握TMS320C6000系列芯片软件编程中,进来取经来了,受益了,顶起来。
zhangmangui 发表于 2013-12-26 17:51 | 显示全部楼层
拿起书本 发表于 2013-12-26 15:37
正在学习掌握TMS320C6000系列芯片软件编程中,进来取经来了,受益了,顶起来。 ...

好好学习   6000系列的问题还望你多多帮忙解答~
陌路绝途 发表于 2013-12-26 20:48 | 显示全部楼层
zhangjin_comeon 发表于 2013-12-27 21:51 | 显示全部楼层
很充实的分享
 楼主| msblast 发表于 2013-12-28 12:31 | 显示全部楼层
拿起书本 发表于 2013-12-26 15:37
正在学习掌握TMS320C6000系列芯片软件编程中,进来取经来了,受益了,顶起来。 ...

谢谢你的肯定。
MyMary 发表于 2013-12-28 21:20 | 显示全部楼层
顶  感觉不错
waitingf 发表于 2013-12-28 21:39 | 显示全部楼层
希望楼主多分享一些呀
someonewho 发表于 2013-12-28 23:20 | 显示全部楼层
学习了 多谢
justbybing 发表于 2013-12-28 23:28 | 显示全部楼层
适合初学者 很不错
specialfrin 发表于 2013-12-29 18:16 | 显示全部楼层
学习一下 哈哈
someontime 发表于 2013-12-29 18:52 | 显示全部楼层
学习啦 不错
haidixibahe 发表于 2013-12-29 18:57 | 显示全部楼层
学会了 多谢楼主
chao11yue 发表于 2013-12-29 19:35 | 显示全部楼层
不错的分享 楼主分享辛苦了哈
engtafanzhuan 发表于 2013-12-29 19:54 | 显示全部楼层
想知道代码能直接用吗
xichengmadia 发表于 2013-12-29 20:51 | 显示全部楼层
一步一步讲解的好详细啊
huigoushang 发表于 2013-12-29 22:09 | 显示全部楼层
学习了 非常有价值的资料
您需要登录后才可以回帖 登录 | 注册

本版积分规则

20

主题

770

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部