原创 ucos互斥信号

2010-7-6 10:03 1955 4 4 分类: MCU/ 嵌入式
uc/os互斥信号



 
使用互斥信号(Mutual Exclusion Semaphores)或者简单的互斥(mutexes)实现对资源的独占访问,互斥信号是本身是一种二进制信号,具有超出uCOS-II提供的一般信号机制的特性。本手册描述了C/OS-II V2.04增加的mutex一系列服务。
简介:
在应用程序中使用互斥信号是为了减少优先级翻转问题(priority inversion problem),如MicroC/OS-II, The Real-Time kernel (ISBN 0-87930-543-6), section 2.16, page 47中描述的。
当一个高优先级的任务需要的资源被一个低优先级的任务使用是,就会发生优先级翻转问题。为了减少优先级翻转问题,内核可以提高的优先级任务的优先级,先于高优先级的任务运行,释放占用的资源。
为了实现互斥,实时内核需要具有支持在同一优先级具有多个任务的能力。不幸的是,µC/OS-II不允许在相同的优先级有多个任务,必须只有一个任务。但是我们有另外的方*解决这个问题。可以把需要资源的高优先级任务上面的一个任务使用Mutex保留,允许提高的优先级任务的优先级。

字串3


举一个mutexes信号工作的例子,如listing1所示。
Listing 1中有三个任务可以使用共同的资源,为了访问这个资源,每个任务必须在互斥信号 ResourceMutex上等待(pend),任务#1有最高优先级10,任务#2优先级为15,任务#3优先级为20,一个没有使用的正好在最高优先级之上的优先级#9用来作为优先级继承优先级(Priority Inheritance Priority-PIP)。如main()所示,L1(1)进行µC/OS-II初始化,并通过调用OSMutexCreate() L1(2)创建了一个互斥信号。需要注意的是,OSMutexCreate()函数使用PIP最为参数。然后创建三个任务L1(3),启动µC/OS-II L1(4).
假设任务运行了一段时间,在某个时间点,任务#3最先访问了共同的资源,并得到了互斥信号,任务#3运行了一段时间后被任务#1抢占。任务#1需要使用这个资源,并通过调用OSMutexPend()企图获得互斥信号,这种情况下,OSMutexPend()会发现一个高优先级的任务需要这个资源,就会把任务#3的优先级提高到9,同时强迫进行上下文切换退回到任务#3执行。 任务#3可以继续执行然后释放占用的共同资源。任务#3通过调用OSMutexPost()释放占用的mutex信号,OSMutexPost()会发现mutex被一个优先级提升的低优先级的任务占有,就会把任务#3的优先级返回到20。把资源释放给任务#1使用,执行上下文切换到任务#1


字串6


-----------------------------------------------------------------
OS_EVENT *ResourceMutex;
OS_STK TaskPrio10Stk[1000];
OS_STK TaskPrio15Stk[1000];
OS_STK TaskPrio20Stk[1000];
void main (void)
{
INT8U err;
OSInit(); /* (1) */
/* ---------- 应用程序初始化 ---------- */
OSMutexCreate(9, &err); /* (2) */
OSTaskCreate(TaskPrio10, (void *)0, &TaskPrio10Stk[999], 10); /* (3) */
OSTaskCreate(TaskPrio15, (void *)0, &TaskPrio15Stk[999], 15);
OSTaskCreate(TaskPrio20, (void *)0, &TaskPrio20Stk[999], 20);
/* ---------- Application Initialization ---------- */
OSStart(); /* (4) */
}
void TaskPrio10 (void *pdata)
{
INT8U err;
pdata = pdata;
while (1) {
/* --------- 应用程序代码 ---------- */
OSMutexPend(ResourceMutex, 0, &err);
/* ------- 访问贡献资源 ------ */
OSMutexPost(ResourceMutex);
/* --------- 应用程序代码 ---------- */
}
}
void TaskPrio15 (void *pdata)
{
INT8U err;
pdata = pdata;
while (1) {
/* ---------应用程序代码 ---------- */
字串9


OSMutexPend(ResourceMutex, 0, &err);
/* ------- 访问共享资源 ------ */
OSMutexPost(ResourceMutex);
/* --------- 应用程序代码 ---------- */
}
}
void TaskPrio20 (void *pdata)
{
INT8U err;
pdata = pdata;
while (1) {
/* ---------应用程序代码---------- */
OSMutexPend(ResourceMutex, 0, &err);
/* -------访问共享资源------ */
OSMutexPost(ResourceMutex);
/* ---------应用程序代码---------- */
, 互斥信号使用示例
C/OS-II'互斥信号包含三个元素,一个flag表示当前mutex是否能够获得(0或1);一个priority表示使用这个mutex的任务,以防一个高优先级的任务需要访问mutex;还包括一个等待这个mutex的任务列表。
为了启动µC/OS-II’s mutex服务,应该在OS_CFG.H中设置OS_MUTEX_EN=1。在使用一个互斥信号之前应该首先创建它,创建一个mutex信号通过调用OSMutexCreate()完成,mutex的初始值总是设置为1,表示资源可以获得。
µC/OS-II提供了六种访问互斥信号量的操作 OSMutexCreate(), OSMutexDel(),
OSMutexPend(), OSMutexPost(), OSMutexAccept() and OSMutexQuery(). Figure 1 字串3
展示了任务和互斥信号量的关系。一个互斥信号量只能被任务访问。在途中使用钥匙符号表示互斥信号。钥匙符号表明互斥信号用来访问共享资源

文章评论0条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /2 下一条