在实际任务间的通信中,一个或多个任务发送一个信号量或者消息给另一个任务是比常见的,而一个任务给多个任务发送信号量和消息相对比较少。前面所讲的信号量和消息队列均是单独的内核对象,是独立于任务存在的。这两章要讲述的任务信号量和任务消息队列是
任务特有的属性,紧紧依赖于一个特定任务。

  任务信号量和任务消息队列分别与多值信号量和消息队列非常相似,不同之处是,前者仅发布给一个特定任务,而后者可以发布给多个任务。因此,前者的操作相对比较简单,而且省时。如果任务信号量和任务消息队列可以满足设计需求,那么尽量不要使用普通多值信号量和消息队列

  任务信号量伴随任务存在,只要创建了任务,其任务信号量就是该任务的一个数据成员,任务信号量的数据成员被包含在任务控制块里。
OSTaskSemPost ()
  OSTaskSemPost () 函数用于给一个任务发布任务信号量。OSTaskSemPost () 函数的信息如下表所示。

任务信号量

  OSTaskSemPost () 函数的定义也位于“os_task.c”:

S_SEM_CTR  OSTaskSemPost (OS_TCB  *p_tcb,   //目标任务
                           OS_OPT   opt,     //选项
                           OS_ERR  *p_err)   //返回错误类型
{
    OS_SEM_CTR  ctr;
    CPU_TS      ts;



#ifdef OS_SAFETY_CRITICAL               //如果使能(默认禁用)了安全检测
    if (p_err == (OS_ERR *)0) {         //如果 p_err 为空
        OS_SAFETY_CRITICAL_EXCEPTION(); //执行安全检测异常函数
        return ((OS_SEM_CTR)0);         //返回0(有错误),停止执行
    }
#endif

#if OS_CFG_ARG_CHK_EN > 0u                  //如果使能(默认使能)了参数检测功能
    switch (opt) {                          //根据选项分类处理
        case OS_OPT_POST_NONE:              //如果选项在预期之内
        case OS_OPT_POST_NO_SCHED:
             break;                         //跳出

        default:                            //如果选项超出预期
            *p_err =  OS_ERR_OPT_INVALID;   //错误类型为“选项非法”
             return ((OS_SEM_CTR)0u);       //返回0(有错误),停止执行
    }
#endif

    ts = OS_TS_GET();                                      //获取时间戳

#if OS_CFG_ISR_POST_DEFERRED_EN > 0u                       //如果使能了中断延迟发布
    if (OSIntNestingCtr > (OS_NESTING_CTR)0) {             //如果该函数是在中断中被调用
        OS_IntQPost((OS_OBJ_TYPE)OS_OBJ_TYPE_TASK_SIGNAL,  //将该信号量发布到中断消息队列
                    (void      *)p_tcb,
                    (void      *)0,
                    (OS_MSG_SIZE)0,
                    (OS_FLAGS   )0,
                    (OS_OPT     )0,
                    (CPU_TS     )ts,
                    (OS_ERR    *)p_err);
        return ((OS_SEM_CTR)0);                           //返回0(尚未发布)   
    }
#endif

    ctr = OS_TaskSemPost(p_tcb,                          //将信号量按照普通方式处理
                         opt,
                         ts,
                         p_err);

    return (ctr);                                       //返回信号的当前计数值
}
OSTaskSemPost()

相关文章: