逐字逐句解析ucos ii 源代码-》OS_SEM.C

//BY 简单的元清    
  
//部分内容引用了其他博主的文章,对这些博主表示感谢,时间关系就不一一指出了。    
  
//如有转载,请说明,谢谢    
/*
*********************************************************************************************************
*                                                uC/OS-II
*                                          The Real-Time Kernel
*                                          SEMAPHORE MANAGEMENT
*
*                        (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
*                                           All Rights Reserved
*
*                                                  V2.00
*
* File : OS_SEM.C
* By   : Jean J. Labrosse
*********************************************************************************************************
*/

#ifndef  OS_MASTER_FILE
#include "software\includes.h"
#endif

#if OS_SEM_EN
/*
*********************************************************************************************************
*                                           ACCEPT SEMAPHORE
*
* Description: This function checks the semaphore to see if a resource is available or, if an event
*              occurred.  Unlike OSSemPend(), OSSemAccept() does not suspend the calling task if the
*              resource is not available or the event did not occur.
*
* Arguments  : pevent     is a pointer to the event control block
*
* Returns    : >  0       if the resource is available or the event did not occur the semaphore is
*                         decremented to obtain the resource.
*              == 0       if the resource is not available or the event did not occur or,
*                         you didn't pass a pointer to a semaphore
*********************************************************************************************************
*/
#if OS_SEM_ACCEPT_EN > 0
//无等待地请求一个信号量
INT16U OSSemAccept (OS_EVENT *pevent) reentrant
{
    INT16U cnt;


    OS_ENTER_CRITICAL();
	//进入临界区
    if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {   /* Validate event block type                     */
        OS_EXIT_CRITICAL();
        return (0);
		//如果类型不是信号量,退出临界区返回错误码
    }
    cnt = pevent->OSEventCnt;
	//读取信号量
    if (cnt > 0) {                                    /* See if resource is available                  */
        pevent->OSEventCnt--;                         /* Yes, decrement semaphore and notify caller    */
		//如果信号量不是0,计数器减一
    }
    OS_EXIT_CRITICAL();
	//退出临界区
    return (cnt);   
	//返回信号量
//	/* Return semaphore count                        */
}
#endif  
/*$PAGE*/
/*
*********************************************************************************************************
*                                           CREATE A SEMAPHORE
*
* Description: This function creates a semaphore.
*
* Arguments  : cnt           is the initial value for the semaphore.  If the value is 0, no resource is
*                            available (or no event has occurred).  You initialize the semaphore to a 
*                            non-zero value to specify how many resources are available (e.g. if you have
*                            10 resources, you would initialize the semaphore to 10).
*
* Returns    : != (void *)0  is a pointer to the event control clock (OS_EVENT) associated with the
*                            created semaphore
*              == (void *)0  if no event control blocks were available
*********************************************************************************************************
*/
//创建一个信号量
OS_EVENT *OSSemCreate (INT16U cnt) reentrant
{
    OS_EVENT *pevent;


    OS_ENTER_CRITICAL();
	//进入临界区
    pevent = OSEventFreeList;                              /* Get next free event control block        */
	//从空的列表中取出一块
    if (OSEventFreeList != (OS_EVENT *)0) {                /* See if pool of free ECB pool was empty   */
        OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
    //判断ECB块是不是空
    }
    OS_EXIT_CRITICAL();
	//退出临界区
    if (pevent != (OS_EVENT *)0) {                         /* Get an event control block               */
        pevent->OSEventType = OS_EVENT_TYPE_SEM;
        pevent->OSEventCnt  = cnt;   
//如果有事件发生,把类型设置为SEM,赋值		/* Set semaphore value                      */
        OSEventWaitListInit(pevent);
		 //添加进等待列表
    }
    return (pevent);
}

/*$PAGE*/
/*
*********************************************************************************************************
*                                           PEND ON SEMAPHORE
*
* Description: This function waits for a semaphore.
*
* Arguments  : pevent        is a pointer to the event control block associated with the desired 
*                            semaphore.
*
*              timeout       is an optional timeout period (in clock ticks).  If non-zero, your task will
*                            wait for the resource up to the amount of time specified by this argument.  
*                            If you specify 0, however, your task will wait forever at the specified 
*                            semaphore or, until the resource becomes available (or the event occurs).
*
*              err           is a pointer to where an error message will be deposited.  Possible error
*                            messages are:
*
*                            OS_NO_ERR          The call was successful and your task owns the resource 
*                                               or, the event you are waiting for occurred.
*                            OS_TIMEOUT         The semaphore was not received within the specified 
*                                               timeout.
*                            OS_ERR_EVENT_TYPE  If you didn't pass a pointer to a semaphore.
*                            OS_ERR_PEND_ISR    If you called this function from an ISR and the result
*                                               would lead to a suspension.
*
* Returns    : none
*********************************************************************************************************
*/
//等待一个信号量 
void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) reentrant
{
    OS_ENTER_CRITICAL();
	//进入临界区
    if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {   /* Validate event block type                     */
        OS_EXIT_CRITICAL();
        *err = OS_ERR_EVENT_TYPE;
		//如果事件的类型不是信号量,退出临界区然后返回错误码
    }
    if (pevent->OSEventCnt > 0) {                     /* If sem. is positive, resource available ...   */
	//如果有信号发生
        pevent->OSEventCnt--;                         /* ... decrement semaphore only if positive.     */
		//数目减一
        OS_EXIT_CRITICAL();
		//退出临界区
        *err = OS_NO_ERR;
		//返回错误码
		
    } else if (OSIntNesting > 0) {                    /* See if called from ISR ...                    */
	//如果有中断发生
        OS_EXIT_CRITICAL();                           /* ... can't PEND from an ISR                    */
		//退出临界区
        *err = OS_ERR_PEND_ISR;
		//返回错误码
    } else {                                          /* Otherwise, must wait until event occurs       */
        OSTCBCur->OSTCBStat    |= OS_STAT_SEM;        /* Resource not available, pend on semaphore     */
        OSTCBCur->OSTCBDly      = timeout;            /* Store pend timeout in TCB                     */
        OSEventTaskWait(pevent);                      /* Suspend task until event or timeout occurs    */
		//赋值信号量参数给给OSTCBCur并加入等待列表
        OS_EXIT_CRITICAL();
		//退出临界区
        OSSched();                                    /* Find next highest priority task ready         */
		//退出临界区
        OS_ENTER_CRITICAL();
		//进入临界区
        if (OSTCBCur->OSTCBStat & OS_STAT_SEM) {      /* Must have timed out if still waiting for event*/
		//如果超时并存在等待任务
            OSEventTO(pevent);
			//直接运行不再等待
            OS_EXIT_CRITICAL();
			//退出临界区
            *err = OS_TIMEOUT;                        /* Indicate that didn't get event within TO      */
			//返回错误码
        } else {
            OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
			//OSTCBCur->OSTCBEventPtr指向空指针
            OS_EXIT_CRITICAL();
			
            *err = OS_NO_ERR;
			//退出临界区然后返回错误码
        }
    }
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                         POST TO A SEMAPHORE
*
* Description: This function signals a semaphore
*
* Arguments  : pevent        is a pointer to the event control block associated with the desired 
*                            semaphore.
*
* Returns    : OS_NO_ERR          The call was successful and the semaphore was signaled.
*              OS_SEM_OVF         If the semaphore count exceeded its limit.  In other words, you have 
*                                 signalled the semaphore more often than you waited on it with either
*                                 OSSemAccept() or OSSemPend().
*              OS_ERR_EVENT_TYPE  If you didn't pass a pointer to a semaphore
*********************************************************************************************************
*/
//发送信号量
INT8U OSSemPost (OS_EVENT *pevent) reentrant
{
    OS_ENTER_CRITICAL();
	//进入临界区
    if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {        /* Validate event block type                */
	
        OS_EXIT_CRITICAL();
        return (OS_ERR_EVENT_TYPE);
		//如果事件的类型不是信号量,退出临界区然后返回错误码
    }
    if (pevent->OSEventGrp) {                              /* See if any task waiting for semaphore    */
	//如果有事件发生
        OSEventTaskRdy(pevent, (void *)0, OS_STAT_SEM);    /* Ready highest prio task waiting on event */
		//把任务就绪
        OS_EXIT_CRITICAL();
		//退出临界区
        OSSched();                                    /* Find highest priority task ready to run       */
		//进行调度
        return (OS_NO_ERR);
		//返回错误码
    } else {
        if (pevent->OSEventCnt < 65535) {             /* Make sure semaphore will not overflow         */
		
            pevent->OSEventCnt++;                     /* Increment semaphore count to register event   */
			//如果信号量满足小于65535,pevent->OSEventCnt加加
            OS_EXIT_CRITICAL();
			
            return (OS_NO_ERR);
			//退出临界区然后返回错误码
        } else {                                      /* Semaphore value has reached its maximum       */
            OS_EXIT_CRITICAL();
			//退出临界区
            return (OS_SEM_OVF);
        }
    }
}
/*
*********************************************************************************************************
*                                          QUERY A SEMAPHORE
*
* Description: This function obtains information about a semaphore
*
* Arguments  : pevent        is a pointer to the event control block associated with the desired 
*                            semaphore
*
*              pdata         is a pointer to a structure that will contain information about the 
*                            semaphore.
*
* Returns    : OS_NO_ERR          The call was successful and the message was sent
*              OS_ERR_EVENT_TYPE  If you are attempting to obtain data from a non semaphore.
*********************************************************************************************************
*/
#if OS_SEM_QUERY_EN > 0
INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *ppdata) reentrant
{
    INT8U  i;
    INT8U *psrc;
    INT8U *pdest;
    
    
    OS_ENTER_CRITICAL();
	//进入临界区
    if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {        /* Validate event block type                */
        OS_EXIT_CRITICAL();
		
        return (OS_ERR_EVENT_TYPE);
	//如果事件的类型不是信号量,退出临界区然后返回错误码
    }
    ppdata->OSEventGrp = pevent->OSEventGrp;                /* Copy message mailbox wait list           */

    psrc              = &pevent->OSEventTbl[0];
    pdest             = &ppdata->OSEventTbl[0];
    for (i = 0; i < OS_EVENT_TBL_SIZE; i++) {
        *pdest++ = *psrc++;   
    }
    ppdata->OSCnt      = pevent->OSEventCnt;                /* Get semaphore count                      */
	//复制信号量的参数给ppdata
    OS_EXIT_CRITICAL();
	//退出临界区
    return (OS_NO_ERR);
	//返回错误码
}
#endif

//*************************
#endif

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
\SOFTWARE The main directory from the root where all software-related files are placed. \SOFTWARE\BLOCKS The main directory where all ‘Building Blocks’ are located. With μC/OS-II, I included a ‘building block’ that handles DOS-type compatible functions that are used by the example code. \SOFTWARE\BLOCKS\TO This directory contains the files for the TO utility (see Appendix E, TO). The source file is TO.C and is found in the \SOFTWARE\TO\SOURCE directory. The DOS executable file (TO.EXE) is found in the \SOFTWARE\TO\EXE directory. Note that TO requires a file called TO.TBL which must reside on your root directory. An example of TO.TBL is also found in the \SOFTWARE\TO\EXE directory. You will need to move TO.TBL to the root directory if you are to use TO.EXE. \SOFTWARE\uCOS-II The main directory where all μC/OS-II files are located. \SOFTWARE\uCOS-II\EX1_x86L This directory contains the source code for EXAMPLE #1 (see section 1.07, Example #1) which is intended to run under DOS (or a DOS window under Windows 95). \SOFTWARE\uCOS-II\EX2_x86L This directory contains the source code for EXAMPLE #2 (see section 1.08, Example #2) which is intended to run under DOS (or a DOS window under Windows 95). \SOFTWARE\uCOS-II\EX3_x86L This directory contains the source code for EXAMPLE #3 (see section 1.09, Example #3) which is intended to run under DOS (or a DOS window under Windows 95). \SOFTWARE\uCOS-II\Ix86L This directory contains the source code for the processor dependent code (a.k.a. the port) of μC/OS-II for an 80x86 Real-Mode, Large Model processor. \SOFTWARE\uCOS-II\SOURCE This directory contains the source code for processor independent portion of μC/OS-II. This code is fully portable to other processor architectures.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值