一,信号量创建函数
OS_EVENT *OSSemCreate (INT16U cnt)
{
OS_EVENT *pevent;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
if (OSIntNesting > 0)
{
return ((OS_EVENT *)0);
}
OS_ENTER_CRITICAL();
pevent = OSEventFreeList;
if (OSEventFreeList != (OS_EVENT *)0) {
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
}
OS_EXIT_CRITICAL();
if (pevent != (OS_EVENT *)0) {
pevent->OSEventType = OS_EVENT_TYPE_SEM;
pevent->OSEventCnt = cnt;
pevent->OSEventPtr = (void *)0;
#if OS_EVENT_NAME_SIZE > 1
pevent->OSEventName[0] = '?';
pevent->OSEventName[1] = OS_ASCII_NUL;
#endif
OS_EventWaitListInit(pevent); //使所有的等待事件的任务都处于就绪状态
}
return (pevent);
}
主要实现的步骤是:
1, 判断是否有中断在执行
2, 判断在空的事件控制链表里面是不是还有任务控制块的存在。
3, 如果存在的话那么,就使OSEventList指向下一个任务控制块,然后对当前事件控制块进行赋值,并对事件控制块进行初始化,最后回赋值后的事件控制块指针
4, 如果不存在的话那么就返回(OSEvent *)0;
5, OS_EventWaitListInit(pevent) 清除等待任务列表
void OS_EventWaitListInit (OS_EVENT *pevent)
{
#if OS_LOWEST_PRIO <= 63
INT8U *ptbl;
#else
INT16U *ptbl;
#endif
INT8U i;
pevent->OSEventGrp = 0;
ptbl = &pevent->OSEventTbl[0];
for (i = 0; i < OS_EVENT_TBL_SIZE; i++) {
*ptbl++ = 0;
}
}
#endif
二,请求信号量
void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (err == (INT8U *)0) {
return;
}
if (pevent == (OS_EVENT *)0) {
*err = OS_ERR_PEVENT_NULL;
return;
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {
*err = OS_ERR_EVENT_TYPE;
return;
}
if (OSIntNesting > 0) {
*err = OS_ERR_PEND_ISR;
return;
}
OS_ENTER_CRITICAL();
if (pevent->OSEventCnt > 0) {
pevent->OSEventCnt--;
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return;
}
OSTCBCur->OSTCBStat |= OS_STAT_SEM;
//没有信号量任务处于等待状态
OSTCBCur->OSTCBPendTO = FALSE;
OSTCBCur->OSTCBDly = timeout;
OS_EventTaskWait(pevent);
//使需要这个事件的任务处于等待状态
OS_EXIT_CRITICAL();
OS_Sched();
//执行其他的任务
OS_ENTER_CRITICAL();
if (OSTCBCur->OSTCBPendTO == TRUE) {
OS_EventTO(pevent);
OS_EXIT_CRITICAL();
*err = OS_TIMEOUT;
return;
}
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
}
1, 就使判断相关的内容是不是合法的
2, 对OSEventCnt的判断,
如果是大于0那么就进行减一后在执行
如果等于0那么就将这个任务挂起
3、pevent->OSEventCnt > 0这是关键的一点如果有信号量那么可以执行相应的程序,如果没有信号量那么任务将被挂起,等待事件的所有任务都会被等待。
三,发送信号量
INT8U OSSemPost (OS_EVENT *pevent)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) {
return (OS_ERR_PEVENT_NULL);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {
return (OS_ERR_EVENT_TYPE);
}
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0) {
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM);
OS_EXIT_CRITICAL();
OS_Sched();
return (OS_NO_ERR);
}
if (pevent->OSEventCnt < 65535u) {
pevent->OSEventCnt++;
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
OS_EXIT_CRITICAL();
return (OS_SEM_OVF);
}
1, 首先要进行相关的判断;
2, 判断是否还有等待这个事件的任务。if (pevent->OSEventGrp != 0)
如果有那么就使相应的任务处于就绪的状态
如果没有那么就使OSEventCnt加1