|
目的:介绍如何使用邮箱在两个任务间发送消息。 方法: 1. 直接从CCS安装目录的tutorial\sim64xx文件夹中将例子文件目录mbxtest复制到一个新文件夹中。这个工程中使用的文件包括以下几种。 ·mbxtest.c:程序的源代码 ·mbxtest.cdb:该例子的DSP/BIOS配置文件。 ·mbxtestcfg.cmd:程序使用的内存定位文件,它由CDB配置工具自动生成。 2. 检查CDB配置文件 在DM642实验板上运行这个例子。该例程的CDB配置文件已经创建了1个MBX邮箱对象、4个TSK任务对象和1个显示消息的LOG对象。为了在DM642上运行,需要修改VECT中断向量表的位置,设置RTDX的模式为JTAG模式,再将LOG_system对象的buflen参数改为512,以及将“logtype”项设为“fixed”;然后保存该配置文件。 3. 查看源代码 在CCS的Project View区域中,双击mbxtest.c文件来查看源代码。下面是各部分的说明。 ·声明部分:这个部分包含了程序用到的各种头文件,以及程序中使用的函数原型。它也包含mbxtestcfg.h头文件,这个头文件包含在配置文件中创建的DSP/BIOS对象的声明。常量NUMMSGS定义为消息数量,常量TIMEOUT定义为等待邮箱存满的时间。MsgObj结构包含一个写入邮箱的信息。 ·main函数:Main()直接返回DSP/BIOS内核。 ·reader函数:这个函数先等待邮箱被写满。在等待过程中,其他线程可以运行。当邮箱写满时,它将从邮箱读取信息,并在LOG记录窗口打印输出。如果它在指定的TIMEOUT个系统时钟后邮箱仍然没有写满,它将跳出循环并结束任务。 ·writer函数:这个函数将循环NUMMSGS次。在每次循环中,它将一个MsgObj结构变量存入邮箱,同时在LOG窗口中打印存入邮箱的内容。如果邮箱已满,它将等待可用空间。在它等待的过程中,其他线程可以运行。 4. 在CCS中运行 编译、连接后,装入该程序。选择菜单命令“DSP/BIOS”|“RTA Control Panel”,打开DSP/BIOS分析工具的控制面板窗口,请只选择“Enable CLK logging”、“Enable TSK logging”和“Global host enable”三项,这样,DSP/BIOS执行图会更加清晰。同时,打开执行窗口和LOG输出窗口,按F5键开始运行程序。 mbxtestcfg.h代码
/* Do *not* directly modify this file. It was */ /* generated by the Configuration Tool; any */ /* changes risk being overwritten. */
/* INPUT mbxtest.cdb */
#define CHIP_6416 1
/* Include Header Files */ #include <std.h> #include <hst.h> #include <swi.h> #include <tsk.h> #include <log.h> #include <mbx.h> #include <sts.h>
#ifdef __cplusplus extern "C" { #endif
extern far HST_Obj RTA_fromHost; extern far HST_Obj RTA_toHost; extern far SWI_Obj KNL_swi; extern far TSK_Obj TSK_idle; extern far TSK_Obj reader0; extern far TSK_Obj writer0; extern far TSK_Obj writer1; extern far TSK_Obj writer2; extern far LOG_Obj LOG_system; extern far LOG_Obj trace; extern far MBX_Obj mbx; extern far STS_Obj IDL_busyObj; extern far void CSL_cfgInit();
#ifdef __cplusplus } #endif /* extern "C" */
mbxtestcfg_c.c代码 /* Do *not* directly modify this file. It was */ /* generated by the Configuration Tool; any */ /* changes risk being overwritten. */
/* INPUT mbxtest.cdb */
/* Include Header File */ #include "mbxtestcfg.h"
#ifdef __cplusplus #pragma CODE_SECTION(".text:CSL_cfgInit") #else #pragma CODE_SECTION(CSL_cfgInit,".text:CSL_cfgInit") #endif
#ifdef __cplusplus #pragma FUNC_EXT_CALLED() #else #pragma FUNC_EXT_CALLED(CSL_cfgInit) #endif
/* Config Structures */ /* Handles */
/* * ======== CSL_cfgInit() ======== */ void CSL_cfgInit() { }
mbxtest.c代码 /* * Copyright 2003 by Texas Instruments Incorporated. * All rights reserved. Property of Texas Instruments Incorporated. * Restricted rights to use, duplicate or disclose this code are * granted through contract. * */ /* "@(#) DSP/BIOS 4.90.270 06-11-03 (barracuda-m10)" */ /* * ======== mbxtest.c ======== * Use a MBX mailbox to send messages from multiple writer() * tasks to a single reader() task. * The mailbox, reader task, and three writer tasks are created by the * Configuration Tool. * * This example is similar to semtest.c. The major differences * are: * - MBX is used in place of QUE and SEM. * - the 'elem' field is removed from MsgObj. * - reader() task is *not* higher priority than writer task. * - reader() looks at return value from MBX_pend() for timeout */
#include <std.h>
#include <log.h> #include <mbx.h> #include <tsk.h>
#include "mbxtestcfg.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; }
/* print value */ #ifdef _28_ LOG_printf(&trace, "read '%c' from (%d).", (Arg)msg.val, (Arg)msg.id); #else LOG_printf(&trace, "read '%c' from (%d).", msg.val, msg.id); #endif } LOG_printf(&trace, "reader done."); }
/* * ======== writer ======== */ Void writer(Arg id_arg) { MsgObj msg; Int I; Int id = ArgToInt (id_arg);
for (I=0; I < NUMMSGS; I++) { /* fill in value */ msg.id = id; msg.val = I % NUMMSGS + (Int)('a');
/* enqueue message */ MBX_post(&mbx, &msg, TIMEOUT);
#ifdef _28_ LOG_printf(&trace, "(%d) writing '%c' …", (Arg)id, (Arg)msg.val); #else LOG_printf(&trace, "(%d) writing '%c' …", id, (Int)msg.val); #endif
/* what happens if you call TSK_yield() here? */ /* TSK_yield(); */ } #ifdef _28_ LOG_printf(&trace, "writer (%d) done.", (Arg)id); #else LOG_printf(&trace, "writer (%d) done.", id); #endif }
|