首页 > 代码库 > μCOS-II系统之事件(event)的使用规则及MUTEX实例

μCOS-II系统之事件(event)的使用规则及MUTEX实例

***************************************************************************************************************************
作者:EasyWave                                                时间:2014.05.31

类别:μC/OS-II-操作系统                                  声明:转载,请保留链接

注意:如有错误,欢迎指正。这些是我学习的日志文章......

***************************************************************************************************************************

一:μC/OS-II系统事件简介

   好久没有弄μC/OS-II系统了,也很久没有更新这个板块的博文了,有工作的原因,也有时间的原因。今天就以Nuvoton的NUC140为例,简单介绍下uCOS-II系统中的事件(Event)的一般使用规则。事件管理函数是μC/OS-II中最多的系统函数, 在μC/OS-II中总共有34个,而且每种事件具有的管理函数数目不同。但是所有的事件都有类似的6个函数,它们是所有事件的基本功能,其函数名类似,使用方法也类似,详细函数见下表。


任何一个事件,必须先创建后使用。创建事件是通过调用函数OS???Create()实现的,其中???为事件的类型。创建事件可以在main()函数中,但更多的是在任务初始化部分。使用方法如下:


在嵌入式系统中,事件是静态使用的,即创建后永远不删除。但有时候需要动态使用,即根据需要创建和删除事件,此时创建事件就是在任务的事件执行代码中,使用方法如下:


要掌握事件函数在中断服务程序中的调用规则,我们必须清楚中断服务有哪些特点。


下面给出事件在中断服务程序中使用方法,假设Task0任务接收ISR发送的消息,任务代码如下:


注意:
1. 中断服务程序一般不会调用建立和删除事件函数,否则要么没有起到事件的作用,要么程序很复杂;
2. 中断服务程序不能调用等待事件的函数,否则可能造成程序崩溃,可以调用无等待获得事件函数获得信号,但事实上,在中断中调用无等待获得事件的情况都很少。

以互斥信号量为例,说明事件如何使用的,在日常生活中,出租车是一种常用的共享资源,当出租车载客时,从外面可以看到标识为载客;当空闲时,标识为空车。这样等车的人就可以根据标识知道出租车的当前状态,判断是否能够座上这辆车。这个标识牌就是一个二值信号量。由于这种二值信号量可以实现对共享资源的独占式处理,所以叫做互斥信号量。

使用互斥信号量有以下3点需要注意:



互斥信号量函数的6个基本函数如下:








二:MUTEX事件实例代码


为了实现资源同步, 我们需要保证OSMutexPost()与OSMutexPend()成对出现在同一个任务函数中。这点请注意哦,下面以Nuvoton的NUC140为例说明如下:


主函数里面只有做一些简单的初始化和OS环境建立。下面是MUTEX的实例代码:

#ifndef	_TASK_C
#define	_TASK_C

/*-----------------------------------------------------------------------------------------*/
/*                                                                                         */
/* Copyright (c) EasyWave. All rights reserved.                                            */
/*                                                                                         */
/*-----------------------------------------------------------------------------------------*/


//===========================================================================================
// 						INCLUDE FILES														 
//===========================================================================================
#include "SYS_Header.H"
#include "BSP_Header.H"
#include "DRV_Header.H"
#include "UOS_Header.H"
#include "Task.H"

/* *************************************************************************************** */
/* 					 	         LOCAL VARIABLE                    */
/* *************************************************************************************** */
#define	MUTEX_PRIO				1	 	// MUTEX_PRIO < OS_LOWEST_PRIO
#define	TASK1_PRIO 				2	 	// TASK1_PRIO < OS_LOWEST_PRIO
#define	TASK2_PRIO				3		// TASK2_PRIO < OS_LOWEST_PRIO

OS_STK	Task1Stack[OS_MAX_STACK];      	// for task1 stack size
OS_STK	Task2Stack[OS_MAX_STACK];      	// for task2 stack size
OS_EVENT	*Mutex;
UINT32	Critical1,Critical2;

/* *************************************************************************************** */
/* 					 	         DEBUG MARCO                	   */
/* *************************************************************************************** */
#ifdef ENABLE_DEBUG
    #define	TASK_DEBUG(x)	  x
#else
    #define	TASK_DEBUG(x)
#endif
/*-----------------------------------------------------------------------------------------*/
/*                      PUBLIC FUNCTION                                                    */
/*-----------------------------------------------------------------------------------------*/

//===========================================================================================
// Function		: OSTaskInitial
// Purpose		: None
// Input		: None
// Rteurn		: None
// External		: None
// History		: EasyWave 2011-11-16 Create
//
// Modify		: None
//===========================================================================================
VOID OSTaskInitial(VOID)
{
	OSTaskCreate( MainTask1, (void*)0, &Task1Stack[OS_MAX_STACK-1], TASK1_PRIO );
	OSTaskCreate( MainTask2, (void*)0, &Task2Stack[OS_MAX_STACK-1], TASK2_PRIO );

	Critical1 = 0x00;
	Critical2 = 0x00;
}

//===========================================================================================
// Function		: MainTask1
// Purpose		: None
// Input		: None
// Rteurn		: None
// External		: None
// History		: EasyWave 2011-11-16 Create
//
// Modify		: None
//===========================================================================================
VOID MainTask1(VOID *pdata)
{
	INT8U	err;

	(VOID)pdata; 

	Mutex = OSMutexCreate(MUTEX_PRIO,&err);

	if(err == OS_ERR_NONE)
	{
		TASK_DEBUG(DrvSIO_printf("OSMutexCreate Sucess.\r\n"));		
	}

	while(TRUE)
	{
		OSMutexPend(Mutex, INFINITE, &err);
 		TASK_DEBUG(DrvSIO_printf("%s is Running.\r\n",__FUNCTION__));
		Critical1 ++;
		OSTimeDly(100);
		Critical2 ++;
		OSMutexPost(Mutex);
	}
}

//===========================================================================================
// Function		: MainTask2
// Purpose		: None
// Input		: None
// Rteurn		: None
// External		: None
// History		: EasyWave 2011-11-16 Create
//
// Modify		: None
//===========================================================================================
VOID MainTask2(VOID *pdata)
{
	INT8U	err;
	
	(VOID)pdata; 

	while(TRUE)
	{
		TASK_DEBUG(DrvSIO_printf("%s is Running.\r\n",__FUNCTION__));

		OSMutexPend(Mutex, INFINITE, &err);
		if(Critical1 != Critical2)
		{
			TASK_DEBUG(DrvSIO_printf("Mutex error\n"));
			while(TRUE);
		}
		else
		{
			TASK_DEBUG(DrvSIO_printf("Mutex Works Well.\r\n"));
		}
		Critical1 ++;
		Critical2 ++;
		OSMutexPost(Mutex);
	} 

}



#endif	//_TASK_C
代码的意思,自行分析吧,这个博文已经分析的很清楚了。