Ucos 信号量

可以把信号量当成一个全局变量来看 
一:信号创建
OS_EVENT *OSSemCreate(INT16U value);   //信号创建

创建了一个信号量 系统会分配一个时间控制块给用户
就是这个信号量控制块
OS_EVENT
typedef struct os_event {
    INT8U    OSEventType;                   /* Type of event control block (see OS_EVENT_TYPE_xxxx)    */
    void    *OSEventPtr;                    /* Pointer to message or queue structure                   */
    INT16U   OSEventCnt;                    /* Semaphore Count (not used if other EVENT type)          */
    OS_PRIO  OSEventGrp;                    /* Group corresponding to tasks waiting for event to occur */
    OS_PRIO  OSEventTbl[OS_EVENT_TBL_SIZE]; /* List of tasks waiting for event to occur                */

#if OS_EVENT_NAME_EN > 0u
    INT8U   *OSEventName;              //允许给控制块命名  新加的特性
#endif
} OS_EVENT;
这个结构体里面有 事件类型 事件控制块指针 事件/消息计数器  后面两个暂时不了解

Value
value就是信号量初始值  每接收一次信号量 Value就会减1


二 : 信号接收
信号的接收有两个函数  分别是:
INT16U OSSemAccept(OS_EVENT *pevent);
void OSSemPend (OS_EVENT *pevent, INT32U timeout, INT8U *perr);

同样的 任意一个接收函数 每接收到一个信号量 Value都会自减1 但是返回的信号量的值是减1之前的值 

第一个函数使用比较简单 参数是一个事件控制块的指针  返回值是一个 INT16U 类型的变量 也就是Value没有减1前的值
如果信号量已经变为零 那每次返回的都是零 不会再做减法运算
这个函数的性质有点像  if判断语句 如果信号量获取不成功就会直接去执行下面的语句
INT16U  OSSemAccept (OS_EVENT *pevent)
{
    INT16U     cnt;
#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */
    OS_CPU_SR  cpu_sr = 0u;
#endif



#if OS_ARG_CHK_EN > 0u
    if (pevent == (OS_EVENT *)0) {                    /* Validate 'pevent'                             */
        return (0u);
    }
#endif
    if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {   /* Validate event block type                     */
        return (0u);
    }
    OS_ENTER_CRITICAL();
    cnt = pevent->OSEventCnt;
    if (cnt > 0u) {                                   /* See if resource is available                  */
        pevent->OSEventCnt--;                         /* Yes, decrement semaphore and notify caller    */
    }
    OS_EXIT_CRITICAL();
    return (cnt);                                     /* Return semaphore count                        */
}
关于使用   pevent->OSEventCnt  和 使用  cnt  的区别
如果使用的是第一个 那么在信号接收函数之后使用 得到的是已经执行减法操作的数
如果使用的是第二个 那么在信号接收函数之后使用 得到的是没有执行减法操作的数

第二个函数 传入事件控制块的指针 
                   timeout:  等待的时间  参数0是无限等待    单位是毫秒    
                   perr: 指向错误代码变量的指针     
OS_ERR_NONE 信号量不为 0。
OS_ERR_TIMEOUT 信号量未在指定的超时周期内置起。
OS_ERR_PEND_ABORT
等待中止。 是由于另一个任务或 ISR 通过调用 OSSemPendAbort ()。
OS_ERR_EVENT_TYPE
pevent 不是指向一个信号量。
OS_ERR_PEND_LOCKED
在调用本函数时,调度器被锁定。
OS_ERR_PEND_ISR
尝试从一个 ISR 调用 OSSemPend (), 不允
n许。
OS_ERR_PEVENT_NULL
pevent 传入的是一个空指针。
这个函数的性质有点类似 while()语句 在设定的等待时间范围内
如果等不到信号量 就会一直停在这里 后面的语句也不能执行 这个函数不可以用在中断函数里 如果使用在中断函数里 系统会返回一个错误代码
最好不要把等待时间设置为0 不然信号量减到零的时候 就会一直卡在那里

三:信号发送
INT8U OSSemPost(OS_EVENT *pevent);
返回值是错误类型的枚举
函数参数是事件指针 就是哪个事件的指针
执行一次信号量就加1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值