您的位置:首页 > 其它

任务的通信和同步中利用旗语解决冲突

2011-11-06 15:11 381 查看
1、 利用旗语解决冲突

目的:说明如何使用旗语来阻止另一个任务线程访问该数据结构。

方法:两个任务线程共享一个数据结构,当其中一个任务线程修改这个数据结构时,就产生了冲突。为了解决这个冲突,两个任务都有一段通过使用同一个旗语调用SEM_pend来保护的代码。在第一个任务执行这段受保护代码期间,另一个任务即使抢先了第一个任务,也不能执行这段受保护的代码(互斥)。

步骤:

1. 复制并打开工程

从CCS安装目录的tutorial﹨sim64xx文件夹中将例子文件目录mutex复制到一个新文件夹中,该工程中使用的文件如下。

mutex.c:程序的源代码

mutex.cdb:DSP/BIOS的配置文件

2. 检查CDB配置文件

在DM642实验板上运行这个例子。该程序的CDB配置文件已经创建了1个SEM旗语对象、2个TSK任务对象和1个现实消息的LOG对象。为了在DM642上运行,还需要修改VECT中断向量表的位置,设置RTDX的模式为JTAG模式,再将LOG_system对象的buflen参数改为512,以及将“logtype”项设为“fixed”;然后保存该配置文件。

3. 查看源代码

在CCS的Project View区域中,可以双击mutex.c文件来查看源代码。下面是各个部分的详细介绍。

·变量声明部分:包含了程序用到的各种头文件,以及程序中使用的函数的原型。同时,还定义了maincoun全局变量,它是由两个任务共同使用,并通过旗语来实现互斥访问。另外,两个全局变量tsk1count,tsk2count分别用于记录任务运行次数。

·main函数:该例子中的main()为空函数,简单地返回DSP/BIOS内核地IDL循环。

·mutex1函数:该函数在任务线程task()中调用。其程序代码如下。

* ======== mutex1 ========

*/

Void mutex1()

{

LgUns tempvar;

LgUns time;

for (;;) {

LOG_printf(&trace, "\n Running mutex1 function");

if (SEM_count(&sem) == 0) {

LOG_printf(&trace, "Sem blocked in mutex1");

}

SEM_pend(&sem, SYS_FOREVER);

tempvar = maincount;

time = CLK_getltime();

while (CLK_getltime() <= (time + 1)) {

;

}

tsk1count++;

maincount = ++tempvar;

#ifdef _28_

LOG_printf(&trace, "mutex1: loop 0x%04x%04x;", (Arg)(tsk1count >> 16), (Arg)(tsk1count & 0xffff));

LOG_printf(&trace, " total count = 0x%04x%04x", (Arg)(maincount >> 16), (Arg)(maincount & 0xffff));

#else

LOG_printf(&trace, "mutex1: loop 0x%04x%04x;", (Int)(tsk1count >> 16), (Int)(tsk1count & 0xffff));

LOG_printf(&trace, " total count = 0x%04x%04x", (Int)(maincount >> 16), (Int)(maincount & 0xffff));

#endif

SEM_post(&sem);

TSK_sleep(1);

}

}

该函数是一个无限循环,在进入循环时首先打印输出信息,表示该任务函数已经开始运行。然后判断旗语计数器,如果计数器为0,则输出一条该任务即将暂停等待旗语地信息。接下来调用SEM_pend函数等待旗语。当收到旗语后,对全局变量maincount加1,输出计算结果,最后发送旗语信号,并使该任务线程暂停一会儿。在这个函数中,SEM_pend和TSK_sleep函数地调用都会导致任务切换。

·mutex2函数:mutex2函数由任务task1调用,它将首先运行(task1的优先级比task()高)。该函数与前面介绍的mutex1函数非常相似,这里不再重复。比较两个任务函数可以看出,两个函数都需要对全局变量maincount进行操作,所以在每个任务对maincount操作前,都需要得到旗语信号。在没有这个信号前,任务都处于暂停状态,即使优先级高的任务也如此。

4. 在CCS中运行

编译、连接后,装入该程序。选择菜单命令“DSP/BIOS”|“RTA Control Panel”,打开DSP/BIOS分析工具的控制面板窗口,只选择“nable CLK logging”、“Enable TSK logging”和“lobal host enable”三项,这样,DSP/BIOS执行图更加清晰。同时,打开执行图窗口和LOG窗口,按F5键开始运行程序。

所有源程序如下:

mutexcfg.h代码

#define CHIP_6416 1

#include <std.h>

#include <hst.h>

#include <swi.h>

#include <tsk.h>

#include <log.h>

#include <sem.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 task0;

extern far TSK_Obj task1;

extern far LOG_Obj LOG_system;

extern far LOG_Obj trace;

extern far SEM_Obj sem;

extern far STS_Obj IDL_busyObj;

extern far void CSL_cfgInit();

#ifdef __cplusplus

}

#endif

mutexcfg_c.c代码

#include "mutexcfg.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

void CSL_cfgInit()

{

}

mutex.c代码

#include <std.h>

#include

#include <log.h>

#include <tsk.h>

#include <sem.h>

#include "mutexcfg.h"

Void mutex1();

Void mutex2();

LgUns tsk1count = 0;

LgUns tsk2count = 0;

LgUns maincount = 0;

Void main()

{

}

Void mutex1()

{

LgUns tempvar;

LgUns time;

for (;;) {

LOG_printf(&trace, "\n Running mutex1 function");

if (SEM_count(&sem) == 0) {

LOG_printf(&trace, "Sem blocked in mutex1");

}

SEM_pend(&sem, SYS_FOREVER);

tempvar = maincount;

time = CLK_getltime();

while (CLK_getltime() <= (time + 1)) {

;

}

tsk1count++;

maincount = ++tempvar;

#ifdef _28_

LOG_printf(&trace, "mutex1: loop 0x%04x%04x;", (Arg)(tsk1count >> 16), (Arg)(tsk1count & 0xffff));

LOG_printf(&trace, " total count = 0x%04x%04x", (Arg)(maincount >> 16), (Arg)(maincount & 0xffff));

#else

LOG_printf(&trace, "mutex1: loop 0x%04x%04x;", (Int)(tsk1count >> 16), (Int)(tsk1count & 0xffff));

LOG_printf(&trace, " total count = 0x%04x%04x", (Int)(maincount >> 16), (Int)(maincount & 0xffff));

#endif

SEM_post(&sem);

TSK_sleep(1);

}

}

Void mutex2()

{

LgUns tempvar;

for (;;) {

LOG_printf(&trace, "\n Running mutex2 function");

if (SEM_count(&sem) == 0) {

LOG_printf(&trace, "Sem blocked in mutex2");

}

SEM_pend(&sem, SYS_FOREVER);

tempvar = maincount;

tsk2count++;

maincount = ++tempvar;

#ifdef _28_

LOG_printf(&trace, "mutex2: loop 0x%04x%04x;", (Arg)(tsk2count >> 16), (Arg)(tsk2count & 0xffff));

LOG_printf(&trace, " total count = 0x%04x%04x", (Arg)(maincount >> 16), (Arg)(maincount & 0xffff));

#else

LOG_printf(&trace, "mutex2: loop 0x%04x%04x;", (Int)(tsk2count >> 16), (Int)(tsk2count & 0xffff));

LOG_printf(&trace, " total count = 0x%04x%04x", (Int)(maincount >> 16), (Int)(maincount & 0xffff));

#endif

SEM_post(&sem);

TSK_sleep(1);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: