INT8U OSQPendAbort (OS_EVENT *pevent, INT8U opt, INT8U *perr) { INT8U nbr_tasks; #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0u; #endif #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return (0u); } #endif #if OS_ARG_CHK_EN > 0u if (pevent == (OS_EVENT *)0) /* Validate 'pevent' */ { *perr = OS_ERR_PEVENT_NULL; return (0u); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_Q) /* Validate event block type */ { *perr = OS_ERR_EVENT_TYPE; return (0u); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0u) /* See if any task waiting on queue? */ { nbr_tasks = 0u; switch (opt) { case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */ while (pevent->OSEventGrp != 0u) /* Yes, ready ALL tasks waiting on queue */ { (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT); nbr_tasks++; } break; case OS_PEND_OPT_NONE: default: /* No, ready HPT waiting on queue */ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT); nbr_tasks++; break; } OS_EXIT_CRITICAL(); OS_Sched(); /* Find HPT ready to run */ *perr = OS_ERR_PEND_ABORT; return (nbr_tasks); } OS_EXIT_CRITICAL(); *perr = OS_ERR_NONE; return (0u); /* No tasks waiting on queue */ }
INT8U OSQPostOpt (OS_EVENT *pevent, void *pmsg, INT8U opt) { OS_Q *pq; #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 (OS_ERR_PEVENT_NULL); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ return (OS_ERR_EVENT_TYPE); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0x00u) { /* See if any task pending on queue */ if ((opt & OS_POST_OPT_BROADCAST) != 0x00u) { /* Do we need to post msg to ALL waiting tasks ? */ while (pevent->OSEventGrp != 0u) { /* Yes, Post to ALL tasks waiting on queue */ (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); } } else { /* No, Post to HPT waiting on queue */ (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); } OS_EXIT_CRITICAL(); if ((opt & OS_POST_OPT_NO_SCHED) == 0u) { /* See if scheduler needs to be invoked */ OS_Sched(); /* Find highest priority task ready to run */ } return (OS_ERR_NONE); } pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */ if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */ OS_EXIT_CRITICAL(); return (OS_ERR_Q_FULL); } if ((opt & OS_POST_OPT_FRONT) != 0x00u) { /* Do we post to the FRONT of the queue? */ if (pq->OSQOut == pq->OSQStart) { /* Yes, Post as LIFO, Wrap OUT pointer if we ... */ pq->OSQOut = pq->OSQEnd; /* ... are at the 1st queue entry */ } pq->OSQOut--; *pq->OSQOut = pmsg; /* Insert message into queue */ } else { /* No, Post as FIFO */ *pq->OSQIn++ = pmsg; /* Insert message into queue */ if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */ pq->OSQIn = pq->OSQStart; } } pq->OSQEntries++; /* Update the nbr of entries in the queue */ OS_EXIT_CRITICAL(); return (OS_ERR_NONE); }
INT8U OSMboxPendAbort (OS_EVENT *pevent, INT8U opt, INT8U *perr) { INT8U nbr_tasks; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if (perr == (INT8U *)0) { /* Validate 'perr' */ return (0); } if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *perr = OS_ERR_PEVENT_NULL; return (0); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ *perr = OS_ERR_EVENT_TYPE; return (0); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0) { /* See if any task waiting on mailbox? */ nbr_tasks = 0; switch (opt) { case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */ while (pevent->OSEventGrp != 0) { /* Yes, ready ALL tasks waiting on mailbox */ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_ABORT); nbr_tasks++; } break; case OS_PEND_OPT_NONE: /* No, ready HPT waiting on mailbox */ default: (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_ABORT); nbr_tasks++; break; } OS_EXIT_CRITICAL(); OS_Sched(); /* Find HPT ready to run */ *perr = OS_ERR_PEND_ABORT; return (nbr_tasks); } OS_EXIT_CRITICAL(); *perr = OS_ERR_NONE; return (0); /* No tasks waiting on mailbox */ }
INT8U OSSemPost (OS_EVENT *pevent) { #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 (OS_ERR_PEVENT_NULL); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ return (OS_ERR_EVENT_TYPE); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0u) { /* See if any task waiting for semaphore */ /* Ready HPT waiting on event */ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK); OS_EXIT_CRITICAL(); OS_Sched(); /* Find HPT ready to run */ return (OS_ERR_NONE); } if (pevent->OSEventCnt < 65535u) { /* Make sure semaphore will not overflow */ pevent->OSEventCnt++; /* Increment semaphore count to register event */ OS_EXIT_CRITICAL(); return (OS_ERR_NONE); } OS_EXIT_CRITICAL(); /* Semaphore value has reached its maximum */ return (OS_ERR_SEM_OVF); }
INT8U OSMboxPost (OS_EVENT *pevent, void *pmsg) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ return (OS_ERR_PEVENT_NULL); } if (pmsg == (void *)0) { /* Make sure we are not posting a NULL pointer */ return (OS_ERR_POST_NULL_PTR); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ return (OS_ERR_EVENT_TYPE); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0) { /* See if any task pending on mailbox */ /* Ready HPT waiting on event */ (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK); OS_EXIT_CRITICAL(); OS_Sched(); /* Find highest priority task ready to run */ return (OS_ERR_NONE); } if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesn't already have a msg */ OS_EXIT_CRITICAL(); return (OS_ERR_MBOX_FULL); } pevent->OSEventPtr = pmsg; /* Place message in mailbox */ OS_EXIT_CRITICAL(); return (OS_ERR_NONE); }
INT8U OSMboxPostOpt (OS_EVENT *pevent, void *msg, INT8U opt) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ return (OS_ERR_PEVENT_NULL); } if (msg == (void *)0) { /* Make sure we are not posting a NULL pointer */ return (OS_ERR_POST_NULL_PTR); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ return (OS_ERR_EVENT_TYPE); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0) { /* See if any task pending on mailbox */ if ((opt & OS_POST_OPT_BROADCAST) != 0x00) { /* Do we need to post msg to ALL waiting tasks ? */ while (pevent->OSEventGrp != 0) { /* Yes, Post to ALL tasks waiting on mailbox */ // 从等待列表中找出使最高优先级任务(Highest Priority Task – HPT),并将其置于就绪态。 (void)OS_EventTaskRdy(pevent, msg, OS_STAT_MBOX); } } else { // 从等待列表中找出使最高优先级任务(Highest Priority Task – HPT),并将其置于就绪态。 (void)OS_EventTaskRdy(pevent, msg, OS_STAT_MBOX); /* No, Post to HPT waiting on mbox */ } OS_EXIT_CRITICAL(); if ((opt & OS_POST_OPT_NO_SCHED) == 0) { OS_Sched(); /* Find HPT ready to run */ } return (OS_NO_ERR); } if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesn't already have a msg */ OS_EXIT_CRITICAL(); return (OS_MBOX_FULL); } pevent->OSEventPtr = msg; /* Place message in mailbox */ OS_EXIT_CRITICAL(); return (OS_NO_ERR); }
INT8U OSMboxPostOpt (OS_EVENT *pevent, void *pmsg, INT8U opt) { #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) { /*事件控制块指针是否有效 */ return (OS_ERR_PEVENT_NULL); } if (pmsg == (void *)0) { /* Make sure we are not posting a NULL pointer */ return (OS_ERR_POST_NULL_PTR); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* 事件控制块类型是否有效 */ return (OS_ERR_EVENT_TYPE); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0u) { /* See if any task pending on mailbox */ if ((opt & OS_POST_OPT_BROADCAST) != 0x00u) { /* Do we need to post msg to ALL waiting tasks ? */ while (pevent->OSEventGrp != 0u) { /* Yes, Post to ALL tasks waiting on mailbox */ (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK); } } else { /* No, Post to HPT waiting on mbox */ (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK); } OS_EXIT_CRITICAL(); if ((opt & OS_POST_OPT_NO_SCHED) == 0u) { /* See if scheduler needs to be invoked */ OS_Sched(); /* Find HPT ready to run */ } return (OS_ERR_NONE); } if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesn't already have a msg */ OS_EXIT_CRITICAL(); return (OS_ERR_MBOX_FULL); } pevent->OSEventPtr = pmsg; /* Place message in mailbox */ OS_EXIT_CRITICAL(); return (OS_ERR_NONE); }
INT8U OSMboxPost (OS_EVENT *pevent, void *msg) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if (pevent == (OS_EVENT *)0) /* Validate 'pevent' */ { return (OS_ERR_PEVENT_NULL); } if (msg == (void *)0) /* Make sure we are not posting a NULL pointer */ { return (OS_ERR_POST_NULL_PTR); } #endif // 事件类型是邮箱? if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) /* Validate event block type */ { return (OS_ERR_EVENT_TYPE); } OS_ENTER_CRITICAL(); // 有任务正在等待该邮箱? if (pevent->OSEventGrp != 0) /* See if any task pending on mailbox */ { // 使最高优先级任务进入就绪态。 (void)OS_EventTaskRdy(pevent, msg, OS_STAT_MBOX); /* Ready HPT waiting on event */ OS_EXIT_CRITICAL(); // 找出优先级最高的任务并进行任务切换 OS_Sched(); /* Find highest priority task ready to run */ return (OS_NO_ERR); } // 没有任务在等待信号量: // 邮箱不是空的? if (pevent->OSEventPtr != (void *)0) /* Make sure mailbox doesn't already have a msg */ { OS_EXIT_CRITICAL(); return (OS_MBOX_FULL); } // 将消息放进邮箱 pevent->OSEventPtr = msg; /* Place message in mailbox */ OS_EXIT_CRITICAL(); return (OS_NO_ERR); }
INT8U OSQPostFront (OS_EVENT *pevent, void *pmsg) { OS_Q *pq; #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 (OS_ERR_PEVENT_NULL); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_Q) /* Validate event block type */ { return (OS_ERR_EVENT_TYPE); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0u) /* See if any task pending on queue */ { /* Ready highest priority task waiting on event */ (void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK); OS_EXIT_CRITICAL(); OS_Sched(); /* Find highest priority task ready to run */ return (OS_ERR_NONE); } pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */ if (pq->OSQEntries >= pq->OSQSize) /* Make sure queue is not full */ { OS_EXIT_CRITICAL(); return (OS_ERR_Q_FULL); } if (pq->OSQOut == pq->OSQStart) /* Wrap OUT ptr if we are at the 1st queue entry */ { pq->OSQOut = pq->OSQEnd; } pq->OSQOut--; *pq->OSQOut = pmsg; /* Insert message into queue */ pq->OSQEntries++; /* Update the nbr of entries in the queue */ OS_EXIT_CRITICAL(); return (OS_ERR_NONE); }
// 释放信号量 INT8U OSSemPost (OS_EVENT *pevent) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if (pevent == (OS_EVENT *)0) /* Validate 'pevent' */ { return (OS_ERR_PEVENT_NULL); } #endif // 检查事件类型是信号量 if (pevent->OSEventType != OS_EVENT_TYPE_SEM) /* Validate event block type */ { return (OS_ERR_EVENT_TYPE); } OS_ENTER_CRITICAL(); // 有任务正在等待该信号量? if (pevent->OSEventGrp != 0) /* See if any task waiting for semaphore*/ { // 从等待列表中找出使最高优先级任务(Highest Priority Task – HPT),并将其置于就绪态。 (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); /* Ready HPT waiting on event */ OS_EXIT_CRITICAL(); // 找出优先级最高的任务并进行任务切换 OS_Sched(); /* Find HPT ready to run */ return (OS_NO_ERR); } // 没有任务在等待信号量 if (pevent->OSEventCnt < 65535u) /* Make sure semaphore will not overflow */ { // 计算器加一 pevent->OSEventCnt++; /* Increment semaphore count to register event */ OS_EXIT_CRITICAL(); return (OS_NO_ERR); } OS_EXIT_CRITICAL(); /* Semaphore value has reached its maximum */ return (OS_SEM_OVF); }
INT8U OSQPost (OS_EVENT *pevent, void *msg) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif OS_Q *pq; #if OS_ARG_CHK_EN > 0 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ return (OS_ERR_PEVENT_NULL); } if (msg == (void *)0) { /* Make sure we are not posting a NULL pointer */ return (OS_ERR_POST_NULL_PTR); } if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ return (OS_ERR_EVENT_TYPE); } #endif OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0x00) { /* See if any task pending on queue */ OS_EventTaskRdy(pevent, msg, OS_STAT_Q); /* Ready highest priority task waiting on event */ OS_EXIT_CRITICAL(); OS_Sched(); /* Find highest priority task ready to run */ return (OS_NO_ERR); } pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */ if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */ OS_EXIT_CRITICAL(); return (OS_Q_FULL); } *pq->OSQIn++ = msg; /* Insert message into queue */ pq->OSQEntries++; /* Update the nbr of entries in the queue */ if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */ pq->OSQIn = pq->OSQStart; } OS_EXIT_CRITICAL(); return (OS_NO_ERR); }
OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *perr) { BOOLEAN tasks_waiting; OS_EVENT *pevent_return; #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0u; #endif #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_EVENT *)0); } #endif #if OS_ARG_CHK_EN > 0u if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *perr = OS_ERR_PEVENT_NULL; return (pevent); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ *perr = OS_ERR_EVENT_TYPE; return (pevent); } if (OSIntNesting > 0u) { /* See if called from ISR ... */ *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ return (pevent); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0u) { /* See if any tasks waiting on semaphore */ tasks_waiting = OS_TRUE; /* Yes */ } else { tasks_waiting = OS_FALSE; /* No */ } switch (opt) { case OS_DEL_NO_PEND: /* Delete semaphore only if no task waiting */ if (tasks_waiting == OS_FALSE) { #if OS_EVENT_NAME_EN > 0u pevent->OSEventName = (INT8U *)(void *)"?"; #endif pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ pevent->OSEventCnt = 0u; OSEventFreeList = pevent; /* Get next free event control block */ OS_EXIT_CRITICAL(); *perr = OS_ERR_NONE; pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */ } else { OS_EXIT_CRITICAL(); *perr = OS_ERR_TASK_WAITING; pevent_return = pevent; } break; case OS_DEL_ALWAYS: /* Always delete the semaphore */ while (pevent->OSEventGrp != 0u) { /* Ready ALL tasks waiting for semaphore */ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK); } #if OS_EVENT_NAME_EN > 0u pevent->OSEventName = (INT8U *)(void *)"?"; #endif pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ pevent->OSEventCnt = 0u; OSEventFreeList = pevent; /* Get next free event control block */ OS_EXIT_CRITICAL(); if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ OS_Sched(); /* Find highest priority task ready to run */ } *perr = OS_ERR_NONE; pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */ break; default: OS_EXIT_CRITICAL(); *perr = OS_ERR_INVALID_OPT; pevent_return = pevent; break; } return (pevent_return); }
OS_EVENT *OSQDel (OS_EVENT *pevent, INT8U opt, INT8U *err) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif BOOLEAN tasks_waiting; OS_Q *pq; if (OSIntNesting > 0) { /* See if called from ISR ... */ *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ return ((OS_EVENT *)0); } #if OS_ARG_CHK_EN > 0 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *err = OS_ERR_PEVENT_NULL; return (pevent); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ *err = OS_ERR_EVENT_TYPE; return (pevent); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0x00) { /* See if any tasks waiting on queue */ tasks_waiting = TRUE; /* Yes */ } else { tasks_waiting = FALSE; /* No */ } switch (opt) { case OS_DEL_NO_PEND: /* Delete queue only if no task waiting */ if (tasks_waiting == FALSE) { #if OS_EVENT_NAME_SIZE > 0 (void)strcpy(pevent->OSEventName, "?"); /* Unknown name */ #endif pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */ pq->OSQPtr = OSQFreeList; OSQFreeList = pq; pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ pevent->OSEventCnt = 0; OSEventFreeList = pevent; /* Get next free event control block */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; return ((OS_EVENT *)0); /* Queue has been deleted */ } else { OS_EXIT_CRITICAL(); *err = OS_ERR_TASK_WAITING; return (pevent); } case OS_DEL_ALWAYS: /* Always delete the queue */ while (pevent->OSEventGrp != 0x00) { /* Ready ALL tasks waiting for queue */ OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q); } #if OS_EVENT_NAME_SIZE > 0 (void)strcpy(pevent->OSEventName, "?"); /* Unknown name */ #endif pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */ pq->OSQPtr = OSQFreeList; OSQFreeList = pq; pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ pevent->OSEventCnt = 0; OSEventFreeList = pevent; /* Get next free event control block */ OS_EXIT_CRITICAL(); if (tasks_waiting == TRUE) { /* Reschedule only if task(s) were waiting */ OS_Sched(); /* Find highest priority task ready to run */ } *err = OS_NO_ERR; return ((OS_EVENT *)0); /* Queue has been deleted */ default: OS_EXIT_CRITICAL(); *err = OS_ERR_INVALID_OPT; return (pevent); } }
OS_EVENT *OSMboxDel (OS_EVENT *pevent, INT8U opt, INT8U *err) { BOOLEAN tasks_waiting; OS_EVENT *pevent_return; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if (err == (INT8U *)0) { /* Validate 'err' */ return (pevent); } if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *err = OS_ERR_PEVENT_NULL; return (pevent); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ *err = OS_ERR_EVENT_TYPE; return (pevent); } if (OSIntNesting > 0) { /* See if called from ISR ... */ *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ return (pevent); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on mailbox */ tasks_waiting = OS_TRUE; /* Yes */ } else { tasks_waiting = OS_FALSE; /* No */ } switch (opt) { case OS_DEL_NO_PEND: /* Delete mailbox only if no task waiting */ if (tasks_waiting == OS_FALSE) { #if OS_EVENT_NAME_SIZE > 1 pevent->OSEventName[0] = '?'; /* Unknown name */ pevent->OSEventName[1] = OS_ASCII_NUL; #endif pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ pevent->OSEventCnt = 0; OSEventFreeList = pevent; /* Get next free event control block */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */ } else { OS_EXIT_CRITICAL(); *err = OS_ERR_TASK_WAITING; pevent_return = pevent; } break; case OS_DEL_ALWAYS: /* Always delete the mailbox */ while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for mailbox */ // 从等待列表中找出使最高优先级任务(Highest Priority Task – HPT),并将其置于就绪态。 (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX); } #if OS_EVENT_NAME_SIZE > 1 pevent->OSEventName[0] = '?'; /* Unknown name */ pevent->OSEventName[1] = OS_ASCII_NUL; #endif pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ pevent->OSEventCnt = 0; OSEventFreeList = pevent; /* Get next free event control block */ OS_EXIT_CRITICAL(); if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ OS_Sched(); /* Find highest priority task ready to run */ } *err = OS_NO_ERR; pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */ break; default: OS_EXIT_CRITICAL(); *err = OS_ERR_INVALID_OPT; pevent_return = pevent; break; } return (pevent_return); }