在实际任务间的通信中,一个或多个任务发送一个信号量或者消息给另一个任务是比常见的,而一个任务给多个任务发送信号量和消息相对比较少。前面所讲的信号量和消息队列均是单独的内核对象,是独立于任务存在的。这两章要讲述的任务信号量和任务消息队列是
任务特有的属性,紧紧依赖于一个特定任务。
任务信号量和任务消息队列分别与多值信号量和消息队列非常相似,不同之处是,前者仅发布给一个特定任务,而后者可以发布给多个任务。因此,前者的操作相对比较简单,而且省时。如果任务信号量和任务消息队列可以满足设计需求,那么尽量不要使用普通多值信号量和消息队列
任务信号量伴随任务存在,只要创建了任务,其任务信号量就是该任务的一个数据成员,任务信号量的数据成员被包含在任务控制块里。
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); //返回信号的当前计数值 }