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

来源:互联网 发布:mac双系统修改启动顺序 编辑:程序博客网 时间:2024/04/27 15:48
 

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, &quot;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);
}
}

原创粉丝点击