INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif OS_STK *psp; INT8U err; #if OS_ARG_CHK_EN > 0 if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */ return (OS_PRIO_INVALID); } #endif psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0); /* Initialize the task's stack */ err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0); if (err == OS_NO_ERR) { OS_ENTER_CRITICAL(); OSTaskCtr++; /* Increment the #tasks counter */ OS_EXIT_CRITICAL(); if (OSRunning == TRUE) { /* Find highest priority task if multitasking has started */ OS_Sched(); } } return (err); }
void OSTimeDly (INT32U ticks) { INT8U y; #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0u; #endif if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ return; } if (OSLockNesting > 0u) { /* See if called with scheduler locked */ return; } if (ticks > 0u) { /* 0 means no delay! */ OS_ENTER_CRITICAL(); y = OSTCBCur->OSTCBY; /* Delay current task */ /* 清除任务就绪表中的就绪状态 */ OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX; /* 清除任务就绪分组中的就绪状态 */ if (OSRdyTbl[y] == 0u) { OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY; } /* 设置任务TCB中的延时 */ OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */ OS_EXIT_CRITICAL(); /* 当前任务进入等待状态,进行任务调度 */ OS_Sched(); /* Find next task to run! */ } }
INT8U OSTaskResume (INT8U prio) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif OS_TCB *ptcb; #if OS_ARG_CHK_EN > 0 if (prio >= OS_LOWEST_PRIO) { /* Make sure task priority is valid */ return (OS_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); ptcb = OSTCBPrioTbl[prio]; if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */ OS_EXIT_CRITICAL(); return (OS_TASK_RESUME_PRIO); } if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY) { /* Task must be suspended */ if (((ptcb->OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) && /* Remove suspension */ (ptcb->OSTCBDly == 0)) { /* Must not be delayed */ OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */ OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; OS_EXIT_CRITICAL(); OS_Sched(); } else { OS_EXIT_CRITICAL(); } return (OS_NO_ERR); } OS_EXIT_CRITICAL(); return (OS_TASK_NOT_SUSPENDED); }
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 OSTimeDlyResume (INT8U prio) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif OS_TCB *ptcb; if (prio >= OS_LOWEST_PRIO) { return (OS_PRIO_INVALID); } OS_ENTER_CRITICAL(); ptcb = (OS_TCB *)OSTCBPrioTbl[prio]; /* Make sure that task exist */ if (ptcb != (OS_TCB *)0) { if (ptcb->OSTCBDly != 0) { /* See if task is delayed */ ptcb->OSTCBDly = 0; /* Clear the time delay */ if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* See if task is ready to run */ OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */ OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; OS_EXIT_CRITICAL(); OS_Sched(); /* See if this is new highest priority */ } else { OS_EXIT_CRITICAL(); /* Task may be suspended */ } return (OS_NO_ERR); } else { OS_EXIT_CRITICAL(); return (OS_TIME_NOT_DLY); /* Indicate that task was not delayed */ } } OS_EXIT_CRITICAL(); return (OS_TASK_NOT_EXIST); /* The task does not exist */ }
INT8U OSTaskCreateExt (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT8U prio, INT16U id, OS_STK *pbos, INT32U stk_size, void *pext, INT16U opt) { OS_STK *psp; INT8U err; #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 (prio > OS_LOWEST_PRIO) /* Make sure priority is within allowable range */ { return (OS_ERR_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if (OSIntNesting > 0) /* Make sure we don't create the task from within an ISR */ { OS_EXIT_CRITICAL(); return (OS_ERR_TASK_CREATE_ISR); } if (OSTCBPrioTbl[prio] == (OS_TCB *)0) /* Make sure task doesn't already exist at this priority */ { OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ... */ /* ... the same thing until task is created. */ OS_EXIT_CRITICAL(); #if OS_TASK_STAT_STK_CHK_EN > 0 OS_TaskStkClr(pbos, stk_size, opt); /* Clear the task stack (if needed) */ #endif psp = OSTaskStkInit(task, p_arg, ptos, opt); /* Initialize the task's stack */ err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt); if (err == OS_ERR_NONE) { if (OSRunning == OS_TRUE) /* Find HPT if multitasking has started */ { OS_Sched(); } } else { OS_ENTER_CRITICAL(); OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Make this priority avail. to others */ OS_EXIT_CRITICAL(); } return (err); } OS_EXIT_CRITICAL(); return (OS_ERR_PRIO_EXIST); }
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 */ /* 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); }
// CODE_SECTION(OSTaskResume,".UserProgramCode") INT8U OSTaskResume( INT8U prio ) { OS_TCB *ptcb; #if OS_CRITICAL_METHOD == 3 /* Storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if ( prio >= OS_LOWEST_PRIO ) /* Make sure task priority is valid */ { return ( OS_ERR_PRIO_INVALID ); } #endif OS_ENTER_CRITICAL(); ptcb = OSTCBPrioTbl[prio]; if ( ptcb == ( OS_TCB * )0 ) /* Task to suspend must exist */ { OS_EXIT_CRITICAL(); return ( OS_ERR_TASK_RESUME_PRIO ); } if ( ptcb == OS_TCB_RESERVED ) /* See if assigned to Mutex */ { OS_EXIT_CRITICAL(); return ( OS_ERR_TASK_NOT_EXIST ); } if (( ptcb->OSTCBStat & OS_STAT_SUSPEND ) != OS_STAT_RDY ) /* Task must be suspended */ { ptcb->OSTCBStat &= ~( INT8U )OS_STAT_SUSPEND; /* Remove suspension */ if ( ptcb->OSTCBStat == OS_STAT_RDY ) /* See if task is now ready */ { if ( ptcb->OSTCBDly == 0 ) { OSRdyGrp |= ptcb->OSTCBBitY; /* Yes, Make task ready to run */ OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; OS_EXIT_CRITICAL(); if ( OSRunning == OS_TRUE ) { OS_Sched(); /* Find new highest priority task */ } } else { OS_EXIT_CRITICAL(); } } else /* Must be pending on event */ { OS_EXIT_CRITICAL(); } return ( OS_ERR_NONE ); } OS_EXIT_CRITICAL(); return ( OS_ERR_TASK_NOT_SUSPENDED ); }
INT8U OSTaskCreateExt (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio, INT16U id, OS_STK *pbos, INT32U stk_size, void *pext, INT16U opt) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif OS_STK *psp; INT8U err; #if OS_ARG_CHK_EN > 0 if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */ return (OS_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */ OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the priority to prevent others from doing ... */ /* ... the same thing until task is created. */ OS_EXIT_CRITICAL(); if (((opt & OS_TASK_OPT_STK_CHK) != 0x0000) || /* See if stack checking has been enabled */ ((opt & OS_TASK_OPT_STK_CLR) != 0x0000)) { /* See if stack needs to be cleared */ #if OS_STK_GROWTH == 1 (void)memset(pbos, 0, stk_size * sizeof(OS_STK)); #else (void)memset(ptos, 0, stk_size * sizeof(OS_STK)); #endif } psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, opt); /* Initialize the task's stack */ err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt); if (err == OS_NO_ERR) { OS_ENTER_CRITICAL(); OSTaskCtr++; /* Increment the #tasks counter */ OS_EXIT_CRITICAL(); if (OSRunning == TRUE) { /* Find HPT if multitasking has started */ OS_Sched(); } } else { OS_ENTER_CRITICAL(); OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Make this priority avail. to others */ OS_EXIT_CRITICAL(); } return (err); } OS_EXIT_CRITICAL(); return (OS_PRIO_EXIST); }
void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif void *msg; OS_Q *pq; if (OSIntNesting > 0) { /* See if called from ISR ... */ *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ return ((void *)0); } #if OS_ARG_CHK_EN > 0 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *err = OS_ERR_PEVENT_NULL; return ((void *)0); } if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */ *err = OS_ERR_EVENT_TYPE; return ((void *)0); } #endif OS_ENTER_CRITICAL(); pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */ if (pq->OSQEntries > 0) { /* See if any messages in the queue */ msg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */ pq->OSQEntries--; /* Update the number of entries in the queue */ if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */ pq->OSQOut = pq->OSQStart; } OS_EXIT_CRITICAL(); *err = OS_NO_ERR; return (msg); /* Return message received */ } OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for a message to be posted */ OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB */ OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ OS_EXIT_CRITICAL(); OS_Sched(); /* Find next highest priority task ready to run */ OS_ENTER_CRITICAL(); if (OSTCBCur->OSTCBStat & OS_STAT_Q) { /* Was task readied because of a timeout? */ OS_EventTO(pevent); /* Yes */ OS_EXIT_CRITICAL(); *err = OS_TIMEOUT; /* Indicate a timeout occured */ return ((void *)0); /* No message received */ } msg = OSTCBCur->OSTCBMsg;/* No, Extract message from TCB (Put there by QPost) */ OSTCBCur->OSTCBMsg = (void *)0; OSTCBCur->OSTCBStat = OS_STAT_RDY; OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; return (msg); /* Return message received */ }
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); }
void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) { 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 (err == (INT8U *)0) { /* Validate 'err' */ return ((void *)0); } if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *err = OS_ERR_PEVENT_NULL; return ((void *)0); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ *err = OS_ERR_EVENT_TYPE; return ((void *)0); } if (OSIntNesting > 0) { /* See if called from ISR ... */ *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ return ((void *)0); } OS_ENTER_CRITICAL(); msg = pevent->OSEventPtr; if (msg != (void *)0) { /* See if there is already a message */ pevent->OSEventPtr = (void *)0; /* Clear the mailbox */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; return (msg); /* Return the message received (or NULL) */ } OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /* Message not available, task will pend */ OSTCBCur->OSTCBPendTO = FALSE; OSTCBCur->OSTCBDly = timeout; /* Load timeout in TCB */ OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ OS_EXIT_CRITICAL(); OS_Sched(); /* Find next highest priority task ready to run */ OS_ENTER_CRITICAL(); if (OSTCBCur->OSTCBPendTO == TRUE) { /* See if we were given the message */ OS_EventTO(pevent); /* Timed out, Make task ready */ OS_EXIT_CRITICAL(); *err = OS_TIMEOUT; /* Indicate that a timeout occured */ return ((void *)0); /* Return a NULL message */ } msg = OSTCBCur->OSTCBMsg; OSTCBCur->OSTCBMsg = (void *)0; /* Yes, clear message received */ OSTCBCur->OSTCBStat = OS_STAT_RDY; OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; return (msg); /* Return the message received */ }
INT8U OSSemPendAbort (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_SEM) { /* Validate event block type */ *perr = OS_ERR_EVENT_TYPE; return (0u); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0u) { /* See if any task waiting on semaphore? */ 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 semaphore */ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_ABORT); nbr_tasks++; } break; case OS_PEND_OPT_NONE: default: /* No, ready HPT waiting on semaphore */ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, 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 semaphore */ }
// CODE_SECTION(OSTimeDlyResume,".UserProgramCode") INT8U OSTimeDlyResume( INT8U prio ) { OS_TCB *ptcb; #if OS_CRITICAL_METHOD == 3 /* Storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif if ( prio >= OS_LOWEST_PRIO ) { return ( OS_ERR_PRIO_INVALID ); } OS_ENTER_CRITICAL(); ptcb = OSTCBPrioTbl[prio]; /* Make sure that task exist */ if ( ptcb == ( OS_TCB * )0 ) { OS_EXIT_CRITICAL(); return ( OS_ERR_TASK_NOT_EXIST ); /* The task does not exist */ } if ( ptcb == OS_TCB_RESERVED ) { OS_EXIT_CRITICAL(); return ( OS_ERR_TASK_NOT_EXIST ); /* The task does not exist */ } if ( ptcb->OSTCBDly == 0 ) /* See if task is delayed */ { OS_EXIT_CRITICAL(); return ( OS_ERR_TIME_NOT_DLY ); /* Indicate that task was not delayed */ } ptcb->OSTCBDly = 0; /* Clear the time delay */ if (( ptcb->OSTCBStat & OS_STAT_PEND_ANY ) != OS_STAT_RDY ) { ptcb->OSTCBStat &= ~OS_STAT_PEND_ANY; /* Yes, Clear status flag */ ptcb->OSTCBStatPend = OS_STAT_PEND_TO; /* Indicate PEND timeout */ } else { ptcb->OSTCBStatPend = OS_STAT_PEND_OK; } if (( ptcb->OSTCBStat & OS_STAT_SUSPEND ) == OS_STAT_RDY ) /* Is task suspended? */ { OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make ready */ OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; OS_EXIT_CRITICAL(); OS_Sched(); /* See if this is new highest priority */ } else { OS_EXIT_CRITICAL(); /* Task may be suspended */ } return ( OS_ERR_NONE ); }
void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) { #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; } if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *err = OS_ERR_PEVENT_NULL; return; } #endif if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ *err = OS_ERR_EVENT_TYPE; return; } if (OSIntNesting > 0) { /* See if called from ISR ... */ *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ return; } if (OSLockNesting > 0) { /* See if called with scheduler locked ... */ *err = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ return; } OS_ENTER_CRITICAL(); if (pevent->OSEventCnt > 0) { /* If sem. is positive, resource available ... */ pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; return; } /* Otherwise, must wait until event occurs */ OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */ OSTCBCur->OSTCBPendTO = OS_FALSE; OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */ OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ OS_EXIT_CRITICAL(); OS_Sched(); /* Find next highest priority task ready */ OS_ENTER_CRITICAL(); if (OSTCBCur->OSTCBPendTO == OS_TRUE) { /* See if we timedout */ OS_EventTO(pevent); OS_EXIT_CRITICAL(); *err = OS_TIMEOUT; /* Indicate that didn't get event within TO */ return; } OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; OS_EXIT_CRITICAL(); *err = OS_NO_ERR; }
void OSTimeDly (UINT16 ticks) { if (ticks > 0) { /* 0 means no delay! */ OS_ENTER_CRITICAL(); if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) { /* Delay current task */ OSRdyGrp &= ~OSTCBCur->OSTCBBitY; } OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */ OS_EXIT_CRITICAL(); OS_Sched(); /* Find next task to run! */ } }
INT8U OSTaskSuspend (INT8U prio) { BOOLEAN self; OS_TCB *ptcb; INT8U y; #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 (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to suspend idle task */ return (OS_ERR_TASK_SUSPEND_IDLE); } if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */ if (prio != OS_PRIO_SELF) { return (OS_ERR_PRIO_INVALID); } } #endif OS_ENTER_CRITICAL(); if (prio == OS_PRIO_SELF) { /* See if suspend SELF */ prio = OSTCBCur->OSTCBPrio; self = OS_TRUE; } else if (prio == OSTCBCur->OSTCBPrio) { /* See if suspending self */ self = OS_TRUE; } else { self = OS_FALSE; /* No suspending another task */ } ptcb = OSTCBPrioTbl[prio]; if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */ OS_EXIT_CRITICAL(); return (OS_ERR_TASK_SUSPEND_PRIO); } if (ptcb == OS_TCB_RESERVED) { /* See if assigned to Mutex */ OS_EXIT_CRITICAL(); return (OS_ERR_TASK_NOT_EXIST); } y = ptcb->OSTCBY; OSRdyTbl[y] &= ~ptcb->OSTCBBitX; /* Make task not ready */ if (OSRdyTbl[y] == 0) { OSRdyGrp &= ~ptcb->OSTCBBitY; } ptcb->OSTCBStat |= OS_STAT_SUSPEND; /* Status of task is 'SUSPENDED' */ OS_EXIT_CRITICAL(); if (self == OS_TRUE) { /* Context switch only if SELF */ OS_Sched(); /* Find new highest priority task */ } return (OS_ERR_NONE); }
INT8U OSMboxPendAbort (OS_EVENT *pevent, INT8U opt, INT8U *err) { 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 (err == (INT8U *)0) { /* Validate 'err' */ return (0); } if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *err = OS_ERR_PEVENT_NULL; return (0); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ *err = 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 */ *err = OS_ERR_PEND_ABORT; return (nbr_tasks); } OS_EXIT_CRITICAL(); *err = OS_ERR_NONE; return (0); /* No tasks waiting on mailbox */ }
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 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); }
void OSTimeDly (INT16U ticks) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif if (ticks > 0) { /* 0 means no delay! */ OS_ENTER_CRITICAL(); if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) { /* Delay current task */ OSRdyGrp &= ~OSTCBCur->OSTCBBitY; } OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */ OS_EXIT_CRITICAL(); OS_Sched(); /* Find next task to run! */ } }
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 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); }
void OSTimeDly (INT32U ticks) { OS_CPU_SR cpu_sr = 0u; if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ return; } if (OSLockNesting > 0u) { /* See if called with scheduler locked */ return; } if (ticks > 0u) { /* 0 means no delay! */ OS_ENTER_CRITICAL(); OSTaskRdy&= ~(1<<OSTCBCur->OSTCBPrio); OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */ OS_EXIT_CRITICAL(); OS_Sched(); /* Find next task to run! */ } }
// 释放信号量 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 OSTaskResume (INT8U prio) { OS_TCB *ptcb; #if OS_CRITICAL_METHOD == 3 /* Storage for CPU status register */ OS_CPU_SR cpu_sr; cpu_sr = 0; /* Prevent compiler warning */ #endif #if OS_ARG_CHK_EN > 0 if (prio >= OS_LOWEST_PRIO) { /* Make sure task priority is valid */ return (OS_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); ptcb = OSTCBPrioTbl[prio]; if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */ OS_EXIT_CRITICAL(); return (OS_TASK_RESUME_PRIO); } if (ptcb == (OS_TCB *)1) { /* See if assigned to Mutex */ OS_EXIT_CRITICAL(); return (OS_TASK_NOT_EXIST); } if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY) { /* Task must be suspended */ ptcb->OSTCBStat &= ~OS_STAT_SUSPEND; /* Remove suspension */ if (ptcb->OSTCBStat == OS_STAT_RDY) { /* See if task is now ready */ if (ptcb->OSTCBDly == 0) { OSRdyGrp |= ptcb->OSTCBBitY; /* Yes, Make task ready to run */ OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; OS_EXIT_CRITICAL(); OS_Sched(); } else { OS_EXIT_CRITICAL(); } } else { /* Must be pending on event */ OS_EXIT_CRITICAL(); } return (OS_NO_ERR); } OS_EXIT_CRITICAL(); return (OS_TASK_NOT_SUSPENDED); }
INT8U OSTaskSuspend (INT8U prio) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif BOOLEAN self; OS_TCB *ptcb; #if OS_ARG_CHK_EN > 0 if (prio == OS_IDLE_PRIO) { /* Not allowed to suspend idle task */ return (OS_TASK_SUSPEND_IDLE); } if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) { /* Task priority valid ? */ return (OS_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if (prio == OS_PRIO_SELF) { /* See if suspend SELF */ prio = OSTCBCur->OSTCBPrio; self = TRUE; } else if (prio == OSTCBCur->OSTCBPrio) { /* See if suspending self */ self = TRUE; } else { self = FALSE; /* No suspending another task */ } ptcb = OSTCBPrioTbl[prio]; if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */ OS_EXIT_CRITICAL(); return (OS_TASK_SUSPEND_PRIO); } if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) { /* Make task not ready */ OSRdyGrp &= ~ptcb->OSTCBBitY; } ptcb->OSTCBStat |= OS_STAT_SUSPEND; /* Status of task is 'SUSPENDED' */ OS_EXIT_CRITICAL(); if (self == TRUE) { /* Context switch only if SELF */ OS_Sched(); } return (OS_NO_ERR); }
INT8U OSTaskCreate (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT8U prio) { OS_STK *psp; INT8U err; #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 (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */ return (OS_ERR_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if (OSIntNesting > 0) { /* Make sure we don't create the task from within an ISR */ OS_EXIT_CRITICAL(); return (OS_ERR_TASK_CREATE_ISR); } if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */ OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ... */ /* ... the same thing until task is created. */ OS_EXIT_CRITICAL(); psp = OSTaskStkInit(task, p_arg, ptos, 0); /* Initialize the task's stack */ err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0); if (err == OS_ERR_NONE) { if (OSRunning == OS_TRUE) { /* Find highest priority task if multitasking has started */ OS_Sched(); } } else { OS_ENTER_CRITICAL(); OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */ OS_EXIT_CRITICAL(); } return (err); } OS_EXIT_CRITICAL(); return (OS_ERR_PRIO_EXIST); }
void OSTimeDly (INT16U ticks) { INT8U y; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; cpu_sr = 0; /* Prevent compiler warning */ #endif if (ticks > 0) { /* 0 means no delay! */ OS_ENTER_CRITICAL(); y = OSTCBCur->OSTCBY; /* Delay current task */ OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX; if (OSRdyTbl[y] == 0) { OSRdyGrp &= ~OSTCBCur->OSTCBBitY; } OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */ OS_EXIT_CRITICAL(); OS_Sched(); /* Find next task to run! */ } }
void OSTimeDly (INT16U ticks) { INT8U y; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif if (OSIntNesting > 0) { /* See if trying to call from an ISR */ return; } if (ticks > 0) { /* 0 means no delay! */ OS_ENTER_CRITICAL(); y = OSTCBCur->OSTCBY; /* Delay current task */ OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX; if (OSRdyTbl[y] == 0) { OSRdyGrp &= ~OSTCBCur->OSTCBBitY; } OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */ OS_EXIT_CRITICAL(); OS_Sched(); /* Find next task to run! */ } }