os_sem.c

  定位到uCOS-II/Source/os_sem.c,该文件是信号量的相关操作函数。

  信号量适用于资源保护的场合,它和互斥型信号量Mutex一样,用于保护着某个共享资源,二者的差别是:Mutex是二值的(0/1),其初始值为1,某任务要操作共享资源,需要获取信号量,获取后信号量计数器为0,那么下一个任务来获取该Mutex将获取不到;而信号量Semaphore的初始值(信号量计数器)可以为大于1的数,假设为3,,那么任务A要使用该资源时,获取信号量后信号量值为2,同理,被任务B获取后信号量值为1,任务C获取后信号量值为0,那么再下一个任务来获取时就将获取不到信号量了。

1. 非阻塞的获取一个信号量函数OSSemAccept()

  OSSemAccept()用于检测信号量是否可用,若资源不可用,调用此函数不会使得所在任务被挂起。

#if OS_SEM_ACCEPT_EN > 0u               //定义OSSemAccept()函数使能宏
INT16U  OSSemAccept (OS_EVENT *pevent)  //pevent指向需要保护的共享资源的信号量
{
    INT16U     cnt;
#if OS_CRITICAL_METHOD == 3u            //信号量中的值
    OS_CPU_SR  cpu_sr = 0u;
#endif

#if OS_ARG_CHK_EN > 0u                  //参数检测使能宏
    if (pevent == (OS_EVENT *)0) { 
        return (0u);
    }
#endif
    if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { 
        return (0u);
    }
    OS_ENTER_CRITICAL();
    cnt = pevent->OSEventCnt;           //取出信号量的值
    if (cnt > 0u) {                     //大于0表示信号量还可以使用
        pevent->OSEventCnt--;           //自减表示使用了该信号量
    }
    OS_EXIT_CRITICAL();
    return (cnt);                       //返回值cnt大于0表示获取信号量成功,反之获取失败
}
#endif

2. 创建信号量函数OSSemCreate()

  OSSemCreate()用于创建并初始化一个信号量。

OS_EVENT  *OSSemCreate (INT16U cnt)     //cnt为信号量的初始值
{
    OS_EVENT  *pevent;
#if OS_CRITICAL_METHOD == 3u
    OS_CPU_SR  cpu_sr = 0u;
#endif

#ifdef OS_SAFETY_CRITICAL_IEC61508      //系统安全相关,不管
    if (OSSafetyCriticalStartFlag == OS_TRUE) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return ((OS_EVENT *)0);
    }
#endif

    if (OSIntNesting > 0u) { 
        return ((OS_EVENT *)0);
    }
    OS_ENTER_CRITICAL();
    pevent = OSEventFreeList;               //pevent指向空闲事件链表
    if (OSEventFreeList != (OS_EVENT *)0) { //如果有空余事件管理块 
        //空闲事件控制链表指向下一个空闲事件控制块  
        OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
    }
    OS_EXIT_CRITICAL();
    if (pevent != (OS_EVENT *)0) {  //解引用前先判断指针是否有效
        //初始化该event(信号量)的相关参数
        pevent->OSEventType    = OS_EVENT_TYPE_SEM;
        pevent->OSEventCnt     = cnt;
        pevent->OSEventPtr     = (void *)0; //OSEventPtr初始值为空,等到某任务获取该event后,OSEventPtr指向该任务的TCB
#if OS_EVENT_NAME_EN > 0u
        pevent->OSEventName    = (INT8U *)(void *)"?";
#endif
        OS_EventWaitListInit(pevent);       //定义在os_core.c中,实现清空该event的等待列表OSEventTbl和等待组OSEventGrp
    }
    re
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值