程序清单 L6.11是OSSemPost()函数的源代码。它首先检查参数指针pevent指向的任务控制块是否是OSSemCreate()函数建立的[L6.11(1)],接着检查是否有任务在等待该信号量[L6.11(2)]。如果该任务控制块中的.OSEventGrp域不是0,说明有任务正在等待该信号量。这时,就要调用函数OSEventTaskRdy()[见6.02节,使一个任务进入就绪状态,OSEventTaskRdy()],把其中的最高优先级任务从等待任务列表中删除[L6.11(3)]并使它进入就绪状态。然后,调用OSSched()任务调度函数检查该任务是否是系统中的最高优先级的就绪任务[L6.11(4)]。如果是,这时就要进行任务切换[当OSSemPost()函数是在任务中调用的],准备执行该就绪任务。如果不是,OSSched()直接返回,调用OSSemPost()的任务得以继续执行。如果这时没有任务在等待该信号量,该信号量的计数值就简单地加1[L6.11(5)]。
上面是由任务调用OSSemPost()时的情况。当中断服务子程序调用该函数时,不会发生上面的任务切换。如果需要,任务切换要等到中断嵌套的最外层中断服务子程序调用OSIntExit()函数后才能进行(见3.09节,µC/OS-II中的中断)。
程序清单 L6.11 发出一个信号量 |
INT8U OSSemPost (OS_EVENT *pevent) |
{ |
OS_ENTER_CRITICAL(); |
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { (1) |
OS_EXIT_CRITICAL(); |
return (OS_ERR_EVENT_TYPE); |
} |
if (pevent->OSEventGrp) { (2) |
OSEventTaskRdy(pevent, (void *)0, OS_STAT_SEM); (3) |
OS_EXIT_CRITICAL(); |
OSSched(); (4) |
return (OS_NO_ERR); |
} else { |
if (pevent->OSEventCnt < 65535) { |
pevent->OSEventCnt++; (5) |
OS_EXIT_CRITICAL(); |
return (OS_NO_ERR); |
} else { |
OS_EXIT_CRITICAL(); |
return (OS_SEM_OVF); |
} |
} |
} |