[置顶] μCOS-II系统之事件(event)的使用规则及Semaphore实例

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

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

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

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

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

在实时多任务系统中,信号量被广泛用于:任务间对共享资源的互斥、任务和中断服务程序之间的同步、任务之间的同步。当任务调用OSSemPost()函数发送信号量时:


当信号量值大于0,任务调用OSSemPend()函数接收信号量时:

[置顶] μCOS-II系统之事件(event)的使用规则及Semaphore实例_第1张图片

当信号量值等于0,任务调用OSSemPend()函数接收信号量时:

[置顶] μCOS-II系统之事件(event)的使用规则及Semaphore实例_第2张图片

注意:μC/OS-II不允许在中断服务程序中等待信号量。

1):任务间同步
在实际的应用中, 常用信号量实现任务间的同步,OSSemPend()和OSSemPost()会出现在不同任务的不同函数中,但不一定成对出现。


注意:在实际的应用中,还有多对多、一对多信号量操作的情况,但很不常见,建议读者不要设计出这样的操作方式,因为这样会带来很多的麻烦。

2): 资源同步
在嵌入式系统中,经常使用信号量访问共享资源来实现资源同步。在使用时,注意发送信号量函数OSSemPost()与等待信号量函数OSSemPend()必须成对出现在同一个任务调用的函数中,才能实现资源同步。


二:Semaphore实例及代码


下面以示例来说明如何现实ISR与任务间同步。假设定时器1中断服务程序发送信号量,任务完成了信号量的创建并在接收到信号量后让蜂鸣器响一声。处理流程如下:

[置顶] μCOS-II系统之事件(event)的使用规则及Semaphore实例_第3张图片

中断服务程序ISR示例代码如下:

[置顶] μCOS-II系统之事件(event)的使用规则及Semaphore实例_第4张图片

下面以Nuvoton的NUC140为例说明Semaphore的使用:

[置顶] μCOS-II系统之事件(event)的使用规则及Semaphore实例_第5张图片

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

#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"

/* *************************************************************************************** */
/* 					 	         PUBLIC VARIABLE                               			   */
/* *************************************************************************************** */
#define	TASK1_PRIO 				1	 	// TASK1_PRIO < OS_LOWEST_PRIO
#define	TASK2_PRIO				2		// 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	*SemSync;;

/* *************************************************************************************** */
/* 					 	         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 );
}

//===========================================================================================
// Function		: MainTask1
// Purpose		: None
// Input		: None
// Rteurn		: None
// External		: None
// History		: EasyWave 2011-11-16 Create
//
// Modify		: None
//===========================================================================================
VOID MainTask1(VOID *pdata)
{
	SemSync = OSSemCreate(0);		//Create semaphore with Zero tokens

	while(TRUE)
	{
		OSTimeDly(50);
		TASK_DEBUG(DrvSIO_printf("Semaphore Release.\r\n"));
		OSSemPost(SemSync);		
	}
}

//===========================================================================================
// Function		: MainTask2
// Purpose		: None
// Input		: None
// Rteurn		: None
// External		: None
// History		: EasyWave 2011-11-16 Create
//
// Modify		: None
//===========================================================================================
VOID MainTask2(VOID *pdata)
{
	INT8U	err;
	
	while(TRUE)
	{
		TASK_DEBUG(DrvSIO_printf("Semaphore Get.\r\n"));
		OSTimeDly(50);
		OSSemPend(SemSync, INFINITE, &err);
	}
}



#endif	//_TASK_C

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

你可能感兴趣的:([置顶] μCOS-II系统之事件(event)的使用规则及Semaphore实例)