BOOLEAN OSTmrStop (OS_TMR *ptmr, INT8U opt, void *callback_arg, INT8U *perr) { OS_TMR_CALLBACK pfnct; #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return (OS_FALSE); } #endif #if OS_ARG_CHK_EN > 0u if (ptmr == (OS_TMR *)0) { *perr = OS_ERR_TMR_INVALID; return (OS_FALSE); } #endif if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ *perr = OS_ERR_TMR_INVALID_TYPE; return (OS_FALSE); } if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return (OS_FALSE); } OSSchedLock(); switch (ptmr->OSTmrState) { case OS_TMR_STATE_RUNNING: OSTmr_Unlink(ptmr); /* Remove from current wheel spoke */ *perr = OS_ERR_NONE; switch (opt) { case OS_TMR_OPT_CALLBACK: pfnct = ptmr->OSTmrCallback; /* Execute callback function if available ... */ if (pfnct != (OS_TMR_CALLBACK)0) { (*pfnct)((void *)ptmr, ptmr->OSTmrCallbackArg); /* Use callback arg when timer was created */ } else { *perr = OS_ERR_TMR_NO_CALLBACK; } break; case OS_TMR_OPT_CALLBACK_ARG: pfnct = ptmr->OSTmrCallback; /* Execute callback function if available ... */ if (pfnct != (OS_TMR_CALLBACK)0) { (*pfnct)((void *)ptmr, callback_arg); /* ... using the 'callback_arg' provided in call */ } else { *perr = OS_ERR_TMR_NO_CALLBACK; } break; case OS_TMR_OPT_NONE: break; default: *perr = OS_ERR_TMR_INVALID_OPT; break; } OSSchedUnlock(); return (OS_TRUE); case OS_TMR_STATE_COMPLETED: /* Timer has already completed the ONE-SHOT or ... */ case OS_TMR_STATE_STOPPED: /* ... timer has not started yet. */ OSSchedUnlock(); *perr = OS_ERR_TMR_STOPPED; return (OS_TRUE); case OS_TMR_STATE_UNUSED: /* Timer was not created */ OSSchedUnlock(); *perr = OS_ERR_TMR_INACTIVE; return (OS_FALSE); default: OSSchedUnlock(); *perr = OS_ERR_TMR_INVALID_STATE; return (OS_FALSE); } }
void OSMutexPend (OS_MUTEX *p_mutex, OS_TICK timeout, OS_OPT opt, CPU_TS *p_ts, OS_ERR *p_err) { OS_PEND_DATA pend_data; OS_TCB *p_tcb; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_PEND_ISR; return; } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_mutex == (OS_MUTEX *)0) { /* Validate arguments */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_OBJ_PTR_NULL; return; } switch (opt) { /* Validate 'opt' */ case OS_OPT_PEND_BLOCKING: case OS_OPT_PEND_NON_BLOCKING: break; default: #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_OPT_INVALID; return; } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_mutex->Type != OS_OBJ_TYPE_MUTEX) { /* Make sure mutex was created */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_OBJ_TYPE; return; } #endif if (p_ts != (CPU_TS *)0) { *p_ts = (CPU_TS )0; /* Initialize the returned timestamp */ } CPU_CRITICAL_ENTER(); if (p_mutex->OwnerNestingCtr == (OS_NESTING_CTR)0) { /* Resource available? */ p_mutex->OwnerTCBPtr = OSTCBCurPtr; /* Yes, caller may proceed */ p_mutex->OwnerOriginalPrio = OSTCBCurPtr->Prio; p_mutex->OwnerNestingCtr = (OS_NESTING_CTR)1; if (p_ts != (CPU_TS *)0) { *p_ts = p_mutex->TS; } CPU_CRITICAL_EXIT(); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_NONE; return; } if (OSTCBCurPtr == p_mutex->OwnerTCBPtr) { /* See if current task is already the owner of the mutex */ p_mutex->OwnerNestingCtr++; if (p_ts != (CPU_TS *)0) { *p_ts = p_mutex->TS; } CPU_CRITICAL_EXIT(); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_MUTEX_OWNER; /* Indicate that current task already owns the mutex */ return; } if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) { /* Caller wants to block if not available? */ CPU_CRITICAL_EXIT(); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_PEND_WOULD_BLOCK; /* No */ return; } else { if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Can't pend when the scheduler is locked */ CPU_CRITICAL_EXIT(); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_SCHED_LOCKED; return; } } /* Lock the scheduler/re-enable interrupts */ OS_CRITICAL_ENTER_CPU_EXIT(); p_tcb = p_mutex->OwnerTCBPtr; /* Point to the TCB of the Mutex owner */ if (p_tcb->Prio > OSTCBCurPtr->Prio) { /* See if mutex owner has a lower priority than current */ switch (p_tcb->TaskState) { case OS_TASK_STATE_RDY: OS_RdyListRemove(p_tcb); /* Remove from ready list at current priority */ p_tcb->Prio = OSTCBCurPtr->Prio; /* Raise owner's priority */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_INHERIT(p_tcb, p_tcb->Prio); #endif OS_PrioInsert(p_tcb->Prio); OS_RdyListInsertHead(p_tcb); /* Insert in ready list at new priority */ break; case OS_TASK_STATE_DLY: case OS_TASK_STATE_DLY_SUSPENDED: case OS_TASK_STATE_SUSPENDED: p_tcb->Prio = OSTCBCurPtr->Prio; /* Only need to raise the owner's priority */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_INHERIT(p_tcb, p_tcb->Prio); #endif break; case OS_TASK_STATE_PEND: /* Change the position of the task in the wait list */ case OS_TASK_STATE_PEND_TIMEOUT: case OS_TASK_STATE_PEND_SUSPENDED: case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED: OS_PendListChangePrio(p_tcb, OSTCBCurPtr->Prio); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_INHERIT(p_tcb, p_tcb->Prio); #endif break; default: OS_CRITICAL_EXIT(); *p_err = OS_ERR_STATE_INVALID; return; } } OS_Pend(&pend_data, /* Block task pending on Mutex */ (OS_PEND_OBJ *)((void *)p_mutex), OS_TASK_PEND_ON_MUTEX, timeout); OS_CRITICAL_EXIT_NO_SCHED(); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_BLOCK(p_mutex); /* Record the event. */ #endif OSSched(); /* Find the next highest priority task ready to run */ CPU_CRITICAL_ENTER(); switch (OSTCBCurPtr->PendStatus) { case OS_STATUS_PEND_OK: /* We got the mutex */ if (p_ts != (CPU_TS *)0) { *p_ts = OSTCBCurPtr->TS; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_NONE; break; case OS_STATUS_PEND_ABORT: /* Indicate that we aborted */ if (p_ts != (CPU_TS *)0) { *p_ts = OSTCBCurPtr->TS; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_PEND_ABORT; break; case OS_STATUS_PEND_TIMEOUT: /* Indicate that we didn't get mutex within timeout */ if (p_ts != (CPU_TS *)0) { *p_ts = (CPU_TS )0; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_TIMEOUT; break; case OS_STATUS_PEND_DEL: /* Indicate that object pended on has been deleted */ if (p_ts != (CPU_TS *)0) { *p_ts = OSTCBCurPtr->TS; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_OBJ_DEL; break; default: #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_PEND_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_STATUS_INVALID; break; } CPU_CRITICAL_EXIT(); }
INT32U OSTmrRemainGet (OS_TMR *ptmr, INT8U *perr) { INT32U remain; #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return (0u); } #endif #if OS_ARG_CHK_EN > 0u if (ptmr == (OS_TMR *)0) { *perr = OS_ERR_TMR_INVALID; return (0u); } #endif if (ptmr->OSTmrType != OS_TMR_TYPE) { /* Validate timer structure */ *perr = OS_ERR_TMR_INVALID_TYPE; return (0u); } if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return (0u); } OSSchedLock(); switch (ptmr->OSTmrState) { case OS_TMR_STATE_RUNNING: remain = ptmr->OSTmrMatch - OSTmrTime; /* Determine how much time is left to timeout */ OSSchedUnlock(); *perr = OS_ERR_NONE; return (remain); case OS_TMR_STATE_STOPPED: /* It's assumed that the timer has not started yet */ switch (ptmr->OSTmrOpt) { case OS_TMR_OPT_PERIODIC: if (ptmr->OSTmrDly == 0u) { remain = ptmr->OSTmrPeriod; } else { remain = ptmr->OSTmrDly; } OSSchedUnlock(); *perr = OS_ERR_NONE; break; case OS_TMR_OPT_ONE_SHOT: default: remain = ptmr->OSTmrDly; OSSchedUnlock(); *perr = OS_ERR_NONE; break; } return (remain); case OS_TMR_STATE_COMPLETED: /* Only ONE-SHOT that timed out can be in this state */ OSSchedUnlock(); *perr = OS_ERR_NONE; return (0u); case OS_TMR_STATE_UNUSED: OSSchedUnlock(); *perr = OS_ERR_TMR_INACTIVE; return (0u); default: OSSchedUnlock(); *perr = OS_ERR_TMR_INVALID_STATE; return (0u); } }
void *OSQPend (OS_Q *p_q, OS_TICK timeout, OS_OPT opt, OS_MSG_SIZE *p_msg_size, CPU_TS *p_ts, OS_ERR *p_err) { OS_PEND_DATA pend_data; void *p_void; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return ((void *)0); } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */ *p_err = OS_ERR_PEND_ISR; return ((void *)0); } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_q == (OS_Q *)0) { /* Validate arguments */ *p_err = OS_ERR_OBJ_PTR_NULL; return ((void *)0); } if (p_msg_size == (OS_MSG_SIZE *)0) { *p_err = OS_ERR_PTR_INVALID; return ((void *)0); } switch (opt) { case OS_OPT_PEND_BLOCKING: case OS_OPT_PEND_NON_BLOCKING: break; default: *p_err = OS_ERR_OPT_INVALID; return ((void *)0); } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_q->Type != OS_OBJ_TYPE_Q) { /* Make sure message queue was created */ *p_err = OS_ERR_OBJ_TYPE; return ((void *)0); } #endif if (p_ts != (CPU_TS *)0) { *p_ts = (CPU_TS )0; /* Initialize the returned timestamp */ } CPU_CRITICAL_ENTER(); p_void = OS_MsgQGet(&p_q->MsgQ, /* Any message waiting in the message queue? */ p_msg_size, p_ts, p_err); if (*p_err == OS_ERR_NONE) { CPU_CRITICAL_EXIT(); return (p_void); /* Yes, Return message received */ } if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) { /* Caller wants to block if not available? */ CPU_CRITICAL_EXIT(); *p_err = OS_ERR_PEND_WOULD_BLOCK; /* No */ return ((void *)0); } else { if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Can't pend when the scheduler is locked */ CPU_CRITICAL_EXIT(); *p_err = OS_ERR_SCHED_LOCKED; return ((void *)0); } } /* Lock the scheduler/re-enable interrupts */ OS_CRITICAL_ENTER_CPU_EXIT(); OS_Pend(&pend_data, /* Block task pending on Message Queue */ (OS_PEND_OBJ *)((void *)p_q), OS_TASK_PEND_ON_Q, timeout); OS_CRITICAL_EXIT_NO_SCHED(); OSSched(); /* Find the next highest priority task ready to run */ CPU_CRITICAL_ENTER(); switch (OSTCBCurPtr->PendStatus) { case OS_STATUS_PEND_OK: /* Extract message from TCB (Put there by Post) */ p_void = OSTCBCurPtr->MsgPtr; *p_msg_size = OSTCBCurPtr->MsgSize; if (p_ts != (CPU_TS *)0) { *p_ts = OSTCBCurPtr->TS; } *p_err = OS_ERR_NONE; break; case OS_STATUS_PEND_ABORT: /* Indicate that we aborted */ p_void = (void *)0; *p_msg_size = (OS_MSG_SIZE)0; if (p_ts != (CPU_TS *)0) { *p_ts = OSTCBCurPtr->TS; } *p_err = OS_ERR_PEND_ABORT; break; case OS_STATUS_PEND_TIMEOUT: /* Indicate that we didn't get event within TO */ p_void = (void *)0; *p_msg_size = (OS_MSG_SIZE)0; if (p_ts != (CPU_TS *)0) { *p_ts = (CPU_TS )0; } *p_err = OS_ERR_TIMEOUT; break; case OS_STATUS_PEND_DEL: /* Indicate that object pended on has been deleted */ p_void = (void *)0; *p_msg_size = (OS_MSG_SIZE)0; if (p_ts != (CPU_TS *)0) { *p_ts = OSTCBCurPtr->TS; } *p_err = OS_ERR_OBJ_DEL; break; default: p_void = (void *)0; *p_msg_size = (OS_MSG_SIZE)0; *p_err = OS_ERR_STATUS_INVALID; break; } CPU_CRITICAL_EXIT(); return (p_void); }
void OSQPost (OS_Q *p_q, void *p_void, OS_MSG_SIZE msg_size, OS_OPT opt, OS_ERR *p_err) { CPU_TS ts; #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_q == (OS_Q *)0) { /* Validate 'p_q' */ *p_err = OS_ERR_OBJ_PTR_NULL; return; } switch (opt) { /* Validate 'opt' */ case OS_OPT_POST_FIFO: case OS_OPT_POST_LIFO: case OS_OPT_POST_FIFO | OS_OPT_POST_ALL: case OS_OPT_POST_LIFO | OS_OPT_POST_ALL: case OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED: case OS_OPT_POST_LIFO | OS_OPT_POST_NO_SCHED: case OS_OPT_POST_FIFO | OS_OPT_POST_ALL | OS_OPT_POST_NO_SCHED: case OS_OPT_POST_LIFO | OS_OPT_POST_ALL | OS_OPT_POST_NO_SCHED: break; default: *p_err = OS_ERR_OPT_INVALID; return; } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_q->Type != OS_OBJ_TYPE_Q) { /* Make sure message queue was created */ *p_err = OS_ERR_OBJ_TYPE; return; } #endif ts = OS_TS_GET(); /* Get timestamp */ #if OS_CFG_ISR_POST_DEFERRED_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { OS_IntQPost((OS_OBJ_TYPE)OS_OBJ_TYPE_Q, /* Post to ISR queue */ (void *)p_q, (void *)p_void, (OS_MSG_SIZE)msg_size, (OS_FLAGS )0, (OS_OPT )opt, (CPU_TS )ts, (OS_ERR *)p_err); return; } #endif OS_QPost(p_q, p_void, msg_size, opt, ts, p_err); }
void OSTimeDly (OS_TICK dly, OS_OPT opt, OS_ERR *p_err) { CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to call from an ISR */ *p_err = OS_ERR_TIME_DLY_ISR; return; } #endif if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0u) { /* Can't delay when the scheduler is locked */ *p_err = OS_ERR_SCHED_LOCKED; return; } switch (opt) { case OS_OPT_TIME_DLY: case OS_OPT_TIME_TIMEOUT: case OS_OPT_TIME_PERIODIC: if (dly == (OS_TICK)0u) { /* 0 means no delay! */ *p_err = OS_ERR_TIME_ZERO_DLY; return; } break; case OS_OPT_TIME_MATCH: break; default: *p_err = OS_ERR_OPT_INVALID; return; } OS_CRITICAL_ENTER(); OS_TickListInsertDly(OSTCBCurPtr, dly, opt, p_err); if (*p_err != OS_ERR_NONE) { OS_CRITICAL_EXIT_NO_SCHED(); return; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_TASK_DLY(dly); /* Record the event. */ #endif OS_RdyListRemove(OSTCBCurPtr); /* Remove current task from ready list */ OS_CRITICAL_EXIT_NO_SCHED(); OSSched(); /* Find next task to run! */ *p_err = OS_ERR_NONE; }
/*$PAGE*/ void *OSMboxPend (OS_EVENT *pevent, INT32U timeout, INT8U *perr) { void *pmsg; #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(); } #endif #if OS_ARG_CHK_EN > 0u if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *perr = OS_ERR_PEVENT_NULL; return ((void *)0); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ *perr = OS_ERR_EVENT_TYPE; return ((void *)0); } if (OSIntNesting > 0u) { /* See if called from ISR ... */ *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ return ((void *)0); } if (OSLockNesting > 0u) { /* See if called with scheduler locked ... */ *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ return ((void *)0); } OS_ENTER_CRITICAL(); pmsg = pevent->OSEventPtr; if (pmsg != (void *)0) { /* See if there is already a message */ pevent->OSEventPtr = (void *)0; /* Clear the mailbox */ OS_EXIT_CRITICAL(); *perr = OS_ERR_NONE; return (pmsg); /* Return the message received (or NULL) */ } OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /* Message not available, task will pend */ OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; 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(); switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */ case OS_STAT_PEND_OK: pmsg = OSTCBCur->OSTCBMsg; *perr = OS_ERR_NONE; break; case OS_STAT_PEND_ABORT: pmsg = (void *)0; *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ break; case OS_STAT_PEND_TO: default: OS_EventTaskRemove(OSTCBCur, pevent); pmsg = (void *)0; *perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */ break; } OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */ OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */ #if (OS_EVENT_MULTI_EN > 0u) OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0; #endif OSTCBCur->OSTCBMsg = (void *)0; /* Clear received message */ OS_EXIT_CRITICAL(); return (pmsg); /* Return received message */ }
OS_OBJ_QTY OSMonDel (OS_MON *p_mon, OS_OPT opt, OS_ERR *p_err) { OS_OBJ_QTY nbr_tasks; OS_PEND_LIST *p_pend_list; OS_TCB *p_tcb; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == DEF_NULL) { OS_SAFETY_CRITICAL_EXCEPTION(); return (0u); } #endif #ifdef OS_SAFETY_CRITICAL_IEC61508 if (OSSafetyCriticalStartFlag == DEF_TRUE) { *p_err = OS_ERR_ILLEGAL_DEL_RUN_TIME; return (0u); } #endif #if (OS_CFG_CALLED_FROM_ISR_CHK_EN == DEF_ENABLED) if (OSIntNestingCtr > 0u) { /* Not allowed to delete a monitor from an ISR */ *p_err = OS_ERR_DEL_ISR; return (0u); } #endif #if (OS_CFG_INVALID_OS_CALLS_CHK_EN == DEF_ENABLED) /* Is the kernel running? */ if (OSRunning != OS_STATE_OS_RUNNING) { *p_err = OS_ERR_OS_NOT_RUNNING; return (0u); } #endif #if (OS_CFG_ARG_CHK_EN == DEF_ENABLED) if (p_mon == DEF_NULL) { /* Validate 'p_mon' */ *p_err = OS_ERR_OBJ_PTR_NULL; return (0u); } #endif #if (OS_CFG_OBJ_TYPE_CHK_EN == DEF_ENABLED) if (p_mon->Type != OS_OBJ_TYPE_MON) { /* Make sure monitor was created */ *p_err = OS_ERR_OBJ_TYPE; return (0u); } #endif CPU_CRITICAL_ENTER(); p_pend_list = &p_mon->PendList; nbr_tasks = 0u; switch (opt) { case OS_OPT_DEL_NO_PEND: /* Delete monitor only if no task waiting */ if (p_pend_list->HeadPtr == DEF_NULL) { #if (OS_CFG_DBG_EN == DEF_ENABLED) OS_MonDbgListRemove(p_mon); OSMonQty--; #endif OS_MonClr(p_mon); CPU_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; } else { CPU_CRITICAL_EXIT(); *p_err = OS_ERR_TASK_WAITING; } break; case OS_OPT_DEL_ALWAYS: /* Always delete the monitor */ while (p_pend_list->HeadPtr != DEF_NULL) { /* Remove all tasks on the pend list */ p_tcb = p_pend_list->HeadPtr; OS_PendAbort(p_tcb, 0, OS_STATUS_PEND_DEL); nbr_tasks++; } #if (OS_CFG_DBG_EN == DEF_ENABLED) OS_MonDbgListRemove(p_mon); OSMonQty--; #endif OS_MonClr(p_mon); CPU_CRITICAL_EXIT(); OSSched(); /* Find highest priority task ready to run */ *p_err = OS_ERR_NONE; break; default: CPU_CRITICAL_EXIT(); *p_err = OS_ERR_OPT_INVALID; break; } return (nbr_tasks); }
void OSMonOp (OS_MON *p_mon, OS_TICK timeout, void *p_arg, OS_MON_ON_ENTER_PTR p_on_enter, OS_MON_ON_EVAL_PTR p_on_eval, OS_OPT opt, OS_ERR *p_err) { CPU_INT32U op_res; CPU_INT32U mon_res; OS_PEND_LIST *p_pend_list; OS_TCB *p_tcb; OS_TCB *p_tcb_next; void *p_eval_data; CPU_BOOLEAN sched; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == DEF_NULL) { OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #if (OS_CFG_INVALID_OS_CALLS_CHK_EN == DEF_ENABLED) /* Is the kernel running? */ if (OSRunning != OS_STATE_OS_RUNNING) { *p_err = OS_ERR_OS_NOT_RUNNING; return; } #endif #if (OS_CFG_ARG_CHK_EN == DEF_ENABLED) if (p_mon == DEF_NULL) { /* Validate 'p_mon' */ *p_err = OS_ERR_OBJ_PTR_NULL; return; } #endif sched = DEF_NO; CPU_CRITICAL_ENTER(); if (p_on_enter != DEF_NULL) { op_res = (*p_on_enter)(p_mon, p_arg); } else { op_res = OS_MON_RES_BLOCK | OS_MON_RES_STOP_EVAL; } if (DEF_BIT_IS_SET(op_res, OS_MON_RES_BLOCK) == DEF_YES) { OS_Pend((OS_PEND_OBJ *)(p_mon), /* Block task pending on Condition Variable */ OS_TASK_PEND_ON_COND_VAR, timeout); sched = DEF_YES; } OSTCBCurPtr->MonData.p_eval_data = p_arg; OSTCBCurPtr->MonData.p_on_eval = p_on_eval; if (DEF_BIT_IS_CLR(op_res, OS_MON_RES_STOP_EVAL) == DEF_YES) { p_pend_list = &p_mon->PendList; if (p_pend_list->HeadPtr != DEF_NULL) { p_tcb = p_pend_list->HeadPtr; while (p_tcb != DEF_NULL) { p_tcb_next = p_tcb->PendNextPtr; p_on_eval = p_tcb->MonData.p_on_eval; p_eval_data = p_tcb->MonData.p_eval_data; if (p_on_eval != DEF_NULL) { mon_res = (*p_on_eval)(p_mon, p_eval_data, p_arg); } else { mon_res = OS_MON_RES_STOP_EVAL; } if (DEF_BIT_IS_CLR(mon_res, OS_MON_RES_BLOCK) == DEF_YES) { OS_Post((OS_PEND_OBJ *)(p_mon), p_tcb, DEF_NULL, 0u, 0u); if (DEF_BIT_IS_CLR(opt, OS_OPT_POST_NO_SCHED) == DEF_YES) { sched = DEF_YES; } } if (DEF_BIT_IS_SET(mon_res, OS_MON_RES_STOP_EVAL) == DEF_YES) { break; } p_tcb = p_tcb_next; } } } CPU_CRITICAL_EXIT(); if (sched == DEF_YES) { OSSched(); /* Find the next highest priority task ready to run */ } if (DEF_BIT_IS_SET(op_res, OS_MON_RES_BLOCK) == DEF_YES) { CPU_CRITICAL_ENTER(); switch (OSTCBCurPtr->PendStatus) { case OS_STATUS_PEND_OK: /* We got the monitor */ *p_err = OS_ERR_NONE; break; case OS_STATUS_PEND_ABORT: /* Indicate that we aborted */ *p_err = OS_ERR_PEND_ABORT; break; case OS_STATUS_PEND_TIMEOUT: /* Indicate that we didn't get monitor within timeout */ *p_err = OS_ERR_TIMEOUT; break; case OS_STATUS_PEND_DEL: /* Indicate that object pended on has been deleted */ *p_err = OS_ERR_OBJ_DEL; break; default: *p_err = OS_ERR_STATUS_INVALID; } CPU_CRITICAL_EXIT(); } else { *p_err = OS_ERR_NONE; } }
void OSStatTaskCPUUsageInit (OS_ERR *p_err) { OS_ERR err; OS_TICK dly; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #if ((OS_CFG_TMR_EN > 0u) && (OS_CFG_TASK_SUSPEND_EN > 0u)) OSTaskSuspend(&OSTmrTaskTCB, &err); if (err != OS_ERR_NONE) { *p_err = err; return; } #endif OSTimeDly((OS_TICK )2, /* Synchronize with clock tick */ (OS_OPT )OS_OPT_TIME_DLY, (OS_ERR *)&err); if (err != OS_ERR_NONE) { *p_err = err; return; } CPU_CRITICAL_ENTER(); OSStatTaskCtr = (OS_TICK)0; /* Clear idle counter */ CPU_CRITICAL_EXIT(); dly = (OS_TICK)0; if (OSCfg_TickRate_Hz > OSCfg_StatTaskRate_Hz) { dly = (OS_TICK)(OSCfg_TickRate_Hz / OSCfg_StatTaskRate_Hz); } if (dly == (OS_TICK)0) { dly = (OS_TICK)(OSCfg_TickRate_Hz / (OS_RATE_HZ)10); } OSTimeDly(dly, /* Determine MAX. idle counter value */ OS_OPT_TIME_DLY, &err); #if ((OS_CFG_TMR_EN > 0u) && (OS_CFG_TASK_SUSPEND_EN > 0u)) OSTaskResume(&OSTmrTaskTCB, &err); if (err != OS_ERR_NONE) { *p_err = err; return; } #endif CPU_CRITICAL_ENTER(); OSStatTaskTimeMax = (CPU_TS)0; OSStatTaskCtrMax = OSStatTaskCtr; /* Store maximum idle counter count */ OSStatTaskRdy = OS_STATE_RDY; CPU_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; }
void OSStatReset (OS_ERR *p_err) { #if (OS_CFG_DBG_EN > 0u) OS_TCB *p_tcb; #if (OS_MSG_EN > 0u) OS_MSG_Q *p_msg_q; #endif #if (OS_CFG_Q_EN > 0u) OS_Q *p_q; #endif #endif CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif CPU_CRITICAL_ENTER(); #if OS_CFG_ISR_POST_DEFERRED_EN > 0u OSIntQTaskTimeMax = (CPU_TS )0; /* Reset the task execution times */ OSIntQNbrEntriesMax = (OS_OBJ_QTY)0; /* Reset the queue maximum number of entries */ #endif #if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageMax = 0u; OSStatTaskTimeMax = (CPU_TS)0; #endif OSTickTaskTimeMax = (CPU_TS)0; #if OS_CFG_TMR_EN > 0u OSTmrTaskTimeMax = (CPU_TS)0; #endif #ifdef CPU_CFG_INT_DIS_MEAS_EN OSIntDisTimeMax = (CPU_TS)0; /* Reset the maximum interrupt disable time */ #endif #if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u OSSchedLockTimeMax = (CPU_TS)0; /* Reset the maximum scheduler lock time */ #endif #if ((OS_MSG_EN > 0u) && (OS_CFG_DBG_EN > 0u)) OSMsgPool.NbrUsedMax = 0u; #endif CPU_CRITICAL_EXIT(); #if OS_CFG_DBG_EN > 0u CPU_CRITICAL_ENTER(); p_tcb = OSTaskDbgListPtr; CPU_CRITICAL_EXIT(); while (p_tcb != (OS_TCB *)0) { /* Reset per-Task statistics */ CPU_CRITICAL_ENTER(); #ifdef CPU_CFG_INT_DIS_MEAS_EN p_tcb->IntDisTimeMax = (CPU_TS )0; #endif #if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u p_tcb->SchedLockTimeMax = (CPU_TS )0; #endif #if OS_CFG_TASK_PROFILE_EN > 0u #if OS_CFG_TASK_Q_EN > 0u p_tcb->MsgQPendTimeMax = (CPU_TS )0; #endif p_tcb->SemPendTimeMax = (CPU_TS )0; p_tcb->CtxSwCtr = (OS_CTR )0; p_tcb->CPUUsage = (OS_CPU_USAGE)0; p_tcb->CPUUsageMax = (OS_CPU_USAGE)0; p_tcb->CyclesTotal = (OS_CYCLES )0; p_tcb->CyclesTotalPrev = (OS_CYCLES )0; p_tcb->CyclesStart = OS_TS_GET(); #endif #if OS_CFG_TASK_Q_EN > 0u p_msg_q = &p_tcb->MsgQ; p_msg_q->NbrEntriesMax = (OS_MSG_QTY )0; #endif p_tcb = p_tcb->DbgNextPtr; CPU_CRITICAL_EXIT(); } #endif #if (OS_CFG_Q_EN > 0u) && (OS_CFG_DBG_EN > 0u) CPU_CRITICAL_ENTER(); p_q = OSQDbgListPtr; CPU_CRITICAL_EXIT(); while (p_q != (OS_Q *)0) { /* Reset message queues statistics */ CPU_CRITICAL_ENTER(); p_msg_q = &p_q->MsgQ; p_msg_q->NbrEntriesMax = (OS_MSG_QTY)0; p_q = p_q->DbgNextPtr; CPU_CRITICAL_EXIT(); } #endif OS_TickListResetPeak(); /* Reset tick wheel statistics */ #if OS_CFG_TMR_EN > 0u OS_TmrResetPeak(); #endif *p_err = OS_ERR_NONE; }
/*$PAGE*/ void OSSemPend (OS_EVENT *pevent, INT32U timeout, INT8U *perr) { #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; } #endif #if OS_ARG_CHK_EN > 0u if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *perr = OS_ERR_PEVENT_NULL; return; } #endif if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ *perr = OS_ERR_EVENT_TYPE; return; } if (OSIntNesting > 0u) { /* See if called from ISR ... */ *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ return; } if (OSLockNesting > 0u) { /* See if called with scheduler locked ... */ *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ return; } OS_ENTER_CRITICAL(); if (pevent->OSEventCnt > 0u) { /* If sem. is positive, resource available ... */ pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */ OS_EXIT_CRITICAL(); *perr = OS_ERR_NONE; return; } /* Otherwise, must wait until event occurs */ OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */ OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; 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(); switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */ case OS_STAT_PEND_OK: *perr = OS_ERR_NONE; break; case OS_STAT_PEND_ABORT: *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ break; case OS_STAT_PEND_TO: default: OS_EventTaskRemove(OSTCBCur, pevent); *perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */ break; } OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */ OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */ #if (OS_EVENT_MULTI_EN > 0u) OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0; #endif OS_EXIT_CRITICAL(); }
void OSMutexPost (OS_MUTEX *p_mutex, OS_OPT opt, OS_ERR *p_err) { OS_PEND_LIST *p_pend_list; OS_TCB *p_tcb; CPU_TS ts; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_POST_FAILED(p_mutex); /* Record the event. */ #endif OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_POST_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_POST_ISR; return; } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_mutex == (OS_MUTEX *)0) { /* Validate 'p_mutex' */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_POST_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_OBJ_PTR_NULL; return; } switch (opt) { /* Validate 'opt' */ case OS_OPT_POST_NONE: case OS_OPT_POST_NO_SCHED: break; default: #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_POST_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_OPT_INVALID; return; } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_mutex->Type != OS_OBJ_TYPE_MUTEX) { /* Make sure mutex was created */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_POST_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_OBJ_TYPE; return; } #endif CPU_CRITICAL_ENTER(); if (OSTCBCurPtr != p_mutex->OwnerTCBPtr) { /* Make sure the mutex owner is releasing the mutex */ CPU_CRITICAL_EXIT(); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_POST_FAILED(p_mutex); /* Record the event. */ #endif *p_err = OS_ERR_MUTEX_NOT_OWNER; return; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_POST(p_mutex); /* Record the event. */ #endif OS_CRITICAL_ENTER_CPU_EXIT(); ts = OS_TS_GET(); /* Get timestamp */ p_mutex->TS = ts; p_mutex->OwnerNestingCtr--; /* Decrement owner's nesting counter */ if (p_mutex->OwnerNestingCtr > (OS_NESTING_CTR)0) { /* Are we done with all nestings? */ OS_CRITICAL_EXIT(); /* No */ *p_err = OS_ERR_MUTEX_NESTING; return; } p_pend_list = &p_mutex->PendList; if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0) { /* Any task waiting on mutex? */ p_mutex->OwnerTCBPtr = (OS_TCB *)0; /* No */ p_mutex->OwnerNestingCtr = (OS_NESTING_CTR)0; OS_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; return; } /* Yes */ if (OSTCBCurPtr->Prio != p_mutex->OwnerOriginalPrio) { OS_RdyListRemove(OSTCBCurPtr); OSTCBCurPtr->Prio = p_mutex->OwnerOriginalPrio; /* Lower owner's priority back to its original one */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_DISINHERIT(OSTCBCurPtr, OSTCBCurPtr->Prio); #endif OS_PrioInsert(OSTCBCurPtr->Prio); OS_RdyListInsertTail(OSTCBCurPtr); /* Insert owner in ready list at new priority */ OSPrioCur = OSTCBCurPtr->Prio; } /* Get TCB from head of pend list */ p_tcb = p_pend_list->HeadPtr->TCBPtr; p_mutex->OwnerTCBPtr = p_tcb; /* Give mutex to new owner */ p_mutex->OwnerOriginalPrio = p_tcb->Prio; p_mutex->OwnerNestingCtr = (OS_NESTING_CTR)1; /* Post to mutex */ OS_Post((OS_PEND_OBJ *)((void *)p_mutex), (OS_TCB *)p_tcb, (void *)0, (OS_MSG_SIZE )0, (CPU_TS )ts); OS_CRITICAL_EXIT_NO_SCHED(); if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0) { OSSched(); /* Run the scheduler */ } *p_err = OS_ERR_NONE; }
void OSMutexCreate (OS_MUTEX *p_mutex, CPU_CHAR *p_name, OS_ERR *p_err) { CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #ifdef OS_SAFETY_CRITICAL_IEC61508 if (OSSafetyCriticalStartFlag == DEF_TRUE) { *p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME; return; } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to be called from an ISR */ *p_err = OS_ERR_CREATE_ISR; return; } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_mutex == (OS_MUTEX *)0) { /* Validate 'p_mutex' */ *p_err = OS_ERR_OBJ_PTR_NULL; return; } #endif OS_CRITICAL_ENTER(); #if OS_OBJ_TYPE_REQ > 0u p_mutex->Type = OS_OBJ_TYPE_MUTEX; /* Mark the data structure as a mutex */ #endif #if OS_CFG_DBG_EN > 0u p_mutex->NamePtr = p_name; #else (void)&p_name; #endif p_mutex->OwnerTCBPtr = (OS_TCB *)0; p_mutex->OwnerNestingCtr = (OS_NESTING_CTR)0; /* Mutex is available */ p_mutex->TS = (CPU_TS )0; p_mutex->OwnerOriginalPrio = OS_CFG_PRIO_MAX; OS_PendListInit(&p_mutex->PendList); /* Initialize the waiting list */ #if OS_CFG_DBG_EN > 0u OS_MutexDbgListAdd(p_mutex); #endif OSMutexQty++; #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_CREATE(p_mutex, p_name); /* Record the event. */ #endif OS_CRITICAL_EXIT_NO_SCHED(); *p_err = OS_ERR_NONE; }
/*$PAGE*/ OS_OBJ_QTY OSPendMulti (OS_PEND_DATA *p_pend_data_tbl, OS_OBJ_QTY tbl_size, OS_TICK timeout, OS_OPT opt, OS_ERR *p_err) { CPU_BOOLEAN valid; OS_OBJ_QTY nbr_obj_rdy; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_OBJ_QTY)0); } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Can't pend from an ISR */ *p_err = OS_ERR_PEND_ISR; return ((OS_OBJ_QTY)0); } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_pend_data_tbl == (OS_PEND_DATA *)0) { /* Validate 'p_pend_data_tbl' */ *p_err = OS_ERR_PTR_INVALID; return ((OS_OBJ_QTY)0); } if (tbl_size == (OS_OBJ_QTY)0) { /* Array size must be > 0 */ *p_err = OS_ERR_PTR_INVALID; return ((OS_OBJ_QTY)0); } switch (opt) { case OS_OPT_PEND_BLOCKING: case OS_OPT_PEND_NON_BLOCKING: break; default: *p_err = OS_ERR_OPT_INVALID; return ((OS_OBJ_QTY)0); } #endif valid = OS_PendMultiValidate(p_pend_data_tbl, /* -------- Validate objects to be OS_SEM or OS_Q ------- */ tbl_size); if (valid == DEF_FALSE) { *p_err = OS_ERR_OBJ_TYPE; /* Invalid, not OS_SEM or OS_Q */ return ((OS_OBJ_QTY)0); } /*$PAGE*/ CPU_CRITICAL_ENTER(); nbr_obj_rdy = OS_PendMultiGetRdy(p_pend_data_tbl, /* --------- SEE IF OBJECT(s) HAVE BEEN POSTED ---------- */ tbl_size); if (nbr_obj_rdy > (OS_OBJ_QTY)0) { CPU_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; return ((OS_OBJ_QTY)nbr_obj_rdy); } if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) { /* Caller wants to block if not available? */ CPU_CRITICAL_EXIT(); *p_err = OS_ERR_PEND_WOULD_BLOCK; /* No */ return ((OS_OBJ_QTY)0); } else { if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Can't pend when the scheduler is locked */ CPU_CRITICAL_EXIT(); *p_err = OS_ERR_SCHED_LOCKED; return ((OS_OBJ_QTY)0); } } /* Lock the scheduler/re-enable interrupts */ OS_CRITICAL_ENTER_CPU_EXIT(); /* ------ NO OBJECT READY, PEND ON MULTIPLE OBJECTS ----- */ OS_PendMultiWait(p_pend_data_tbl, /* Suspend task until object posted or timeout occurs */ tbl_size, timeout); OS_CRITICAL_EXIT_NO_SCHED(); OSSched(); /* Find next highest priority task ready */ CPU_CRITICAL_ENTER(); switch (OSTCBCurPtr->PendStatus) { case OS_STATUS_PEND_OK: /* We got one of the objects posted to */ *p_err = OS_ERR_NONE; break; case OS_STATUS_PEND_ABORT: /* Indicate that the multi-pend was aborted */ *p_err = OS_ERR_PEND_ABORT; break; case OS_STATUS_PEND_TIMEOUT: /* Indicate that we didn't get semaphore within timeout */ *p_err = OS_ERR_TIMEOUT; break; case OS_STATUS_PEND_DEL: /* Indicate that an object pended on has been deleted */ *p_err = OS_ERR_OBJ_DEL; break; default: *p_err = OS_ERR_STATUS_INVALID; break; } OSTCBCurPtr->PendStatus = OS_STATUS_PEND_OK; CPU_CRITICAL_EXIT(); return ((OS_OBJ_QTY)1); }
void OSMonCreate (OS_MON *p_mon, CPU_CHAR *p_name, void *p_mon_data, OS_ERR *p_err) { CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == DEF_NULL) { OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #ifdef OS_SAFETY_CRITICAL_IEC61508 if (OSSafetyCriticalStartFlag == DEF_TRUE) { *p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME; return; } #endif #if (OS_CFG_CALLED_FROM_ISR_CHK_EN == DEF_ENABLED) if (OSIntNestingCtr > 0u) { /* Not allowed to be called from an ISR */ *p_err = OS_ERR_CREATE_ISR; return; } #endif #if (OS_CFG_ARG_CHK_EN == DEF_ENABLED) if (p_mon == DEF_NULL) { /* Validate 'p_mon' */ *p_err = OS_ERR_OBJ_PTR_NULL; return; } #endif CPU_CRITICAL_ENTER(); #if (OS_OBJ_TYPE_REQ == DEF_ENABLED) p_mon->Type = OS_OBJ_TYPE_MON; /* Mark the data structure as a monitor */ #endif #if (OS_CFG_DBG_EN == DEF_ENABLED) p_mon->NamePtr = p_name; /* Save the name of the monitor */ #else (void)p_name; #endif OS_PendListInit(&p_mon->PendList); #if (OS_CFG_DBG_EN == DEF_ENABLED) OS_MonDbgListAdd(p_mon); OSMonQty++; #endif if (p_mon_data != DEF_NULL) { p_mon->MonDataPtr = p_mon_data; } CPU_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; }
void OSTimeDlyResume (OS_TCB *p_tcb, OS_ERR *p_err) { CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to call from an ISR */ *p_err = OS_ERR_TIME_DLY_RESUME_ISR; return; } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_tcb == (OS_TCB *)0) { /* Not possible for the running task to be delayed! */ *p_err = OS_ERR_TASK_NOT_DLY; return; } #endif CPU_CRITICAL_ENTER(); if (p_tcb == OSTCBCurPtr) { /* Not possible for the running task to be delayed! */ *p_err = OS_ERR_TASK_NOT_DLY; CPU_CRITICAL_EXIT(); return; } switch (p_tcb->TaskState) { case OS_TASK_STATE_RDY: /* Cannot Abort delay if task is ready */ CPU_CRITICAL_EXIT(); *p_err = OS_ERR_TASK_NOT_DLY; break; case OS_TASK_STATE_DLY: OS_CRITICAL_ENTER_CPU_EXIT(); p_tcb->TaskState = OS_TASK_STATE_RDY; OS_TickListRemove(p_tcb); /* Remove task from tick list */ OS_RdyListInsert(p_tcb); /* Add to ready list */ OS_CRITICAL_EXIT_NO_SCHED(); *p_err = OS_ERR_NONE; break; case OS_TASK_STATE_PEND: CPU_CRITICAL_EXIT(); *p_err = OS_ERR_TASK_NOT_DLY; break; case OS_TASK_STATE_PEND_TIMEOUT: CPU_CRITICAL_EXIT(); *p_err = OS_ERR_TASK_NOT_DLY; break; case OS_TASK_STATE_SUSPENDED: CPU_CRITICAL_EXIT(); *p_err = OS_ERR_TASK_NOT_DLY; break; case OS_TASK_STATE_DLY_SUSPENDED: OS_CRITICAL_ENTER_CPU_EXIT(); p_tcb->TaskState = OS_TASK_STATE_SUSPENDED; OS_TickListRemove(p_tcb); /* Remove task from tick list */ OS_CRITICAL_EXIT_NO_SCHED(); *p_err = OS_ERR_TASK_SUSPENDED; break; case OS_TASK_STATE_PEND_SUSPENDED: CPU_CRITICAL_EXIT(); *p_err = OS_ERR_TASK_NOT_DLY; break; case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED: CPU_CRITICAL_EXIT(); *p_err = OS_ERR_TASK_NOT_DLY; break; default: CPU_CRITICAL_EXIT(); *p_err = OS_ERR_STATE_INVALID; break; } OSSched(); }
OS_SEM_CTR OSSemPend (OS_SEM *p_sem, OS_TICK timeout, OS_OPT opt, CPU_TS *p_ts, OS_ERR *p_err) { OS_SEM_CTR ctr; OS_PEND_DATA pend_data; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_PEND_FAILED(p_sem); /* Record the event. */ #endif OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_SEM_CTR)0); } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_PEND_FAILED(p_sem); /* Record the event. */ #endif *p_err = OS_ERR_PEND_ISR; return ((OS_SEM_CTR)0); } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_sem == (OS_SEM *)0) { /* Validate 'p_sem' */ *p_err = OS_ERR_OBJ_PTR_NULL; return ((OS_SEM_CTR)0); } switch (opt) { /* Validate 'opt' */ case OS_OPT_PEND_BLOCKING: case OS_OPT_PEND_NON_BLOCKING: break; default: #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_PEND_FAILED(p_sem); /* Record the event. */ #endif *p_err = OS_ERR_OPT_INVALID; return ((OS_SEM_CTR)0); } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_sem->Type != OS_OBJ_TYPE_SEM) { /* Make sure semaphore was created */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_PEND_FAILED(p_sem); /* Record the event. */ #endif *p_err = OS_ERR_OBJ_TYPE; return ((OS_SEM_CTR)0); } #endif if (p_ts != (CPU_TS *)0) { *p_ts = (CPU_TS)0; /* Initialize the returned timestamp */ } CPU_CRITICAL_ENTER(); if (p_sem->Ctr > (OS_SEM_CTR)0) { /* Resource available? */ p_sem->Ctr--; /* Yes, caller may proceed */ if (p_ts != (CPU_TS *)0) { *p_ts = p_sem->TS; /* get timestamp of last post */ } ctr = p_sem->Ctr; CPU_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_PEND(p_sem); /* Record the event. */ #endif return (ctr); } if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) { /* Caller wants to block if not available? */ ctr = p_sem->Ctr; /* No */ CPU_CRITICAL_EXIT(); *p_err = OS_ERR_PEND_WOULD_BLOCK; #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_PEND_FAILED(p_sem); /* Record the event. */ #endif return (ctr); } else { /* Yes */ if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Can't pend when the scheduler is locked */ CPU_CRITICAL_EXIT(); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_PEND_FAILED(p_sem); /* Record the event. */ #endif *p_err = OS_ERR_SCHED_LOCKED; return ((OS_SEM_CTR)0); } } /* Lock the scheduler/re-enable interrupts */ OS_CRITICAL_ENTER_CPU_EXIT(); OS_Pend(&pend_data, /* Block task pending on Semaphore */ (OS_PEND_OBJ *)((void *)p_sem), OS_TASK_PEND_ON_SEM, timeout); OS_CRITICAL_EXIT_NO_SCHED(); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_PEND_BLOCK(p_sem); /* Record the event. */ #endif OSSched(); /* Find the next highest priority task ready to run */ CPU_CRITICAL_ENTER(); switch (OSTCBCurPtr->PendStatus) { case OS_STATUS_PEND_OK: /* We got the semaphore */ if (p_ts != (CPU_TS *)0) { *p_ts = OSTCBCurPtr->TS; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_PEND(p_sem); /* Record the event. */ #endif *p_err = OS_ERR_NONE; break; case OS_STATUS_PEND_ABORT: /* Indicate that we aborted */ if (p_ts != (CPU_TS *)0) { *p_ts = OSTCBCurPtr->TS; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_PEND_FAILED(p_sem); /* Record the event. */ #endif *p_err = OS_ERR_PEND_ABORT; break; case OS_STATUS_PEND_TIMEOUT: /* Indicate that we didn't get semaphore within timeout */ if (p_ts != (CPU_TS *)0) { *p_ts = (CPU_TS )0; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_PEND_FAILED(p_sem); /* Record the event. */ #endif *p_err = OS_ERR_TIMEOUT; break; case OS_STATUS_PEND_DEL: /* Indicate that object pended on has been deleted */ if (p_ts != (CPU_TS *)0) { *p_ts = OSTCBCurPtr->TS; } #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_PEND_FAILED(p_sem); /* Record the event. */ #endif *p_err = OS_ERR_OBJ_DEL; break; default: #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_PEND_FAILED(p_sem); /* Record the event. */ #endif *p_err = OS_ERR_STATUS_INVALID; CPU_CRITICAL_EXIT(); return ((OS_SEM_CTR)0); } ctr = p_sem->Ctr; CPU_CRITICAL_EXIT(); return (ctr); }
OS_EVENT *OSMboxDel (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(); } #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_MBOX) { /* 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 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_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; /* Mailbox has been deleted */ } else { OS_EXIT_CRITICAL(); *perr = OS_ERR_TASK_WAITING; pevent_return = pevent; } break; case OS_DEL_ALWAYS: /* Always delete the mailbox */ while (pevent->OSEventGrp != 0u) { /* Ready ALL tasks waiting for mailbox */ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, 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; /* Mailbox has been deleted */ break; default: OS_EXIT_CRITICAL(); *perr = OS_ERR_INVALID_OPT; pevent_return = pevent; break; } return (pevent_return); }
OS_SEM_CTR OSSemPost (OS_SEM *p_sem, OS_OPT opt, OS_ERR *p_err) { OS_SEM_CTR ctr; CPU_TS ts; #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_POST_FAILED(p_sem); /* Record the event. */ #endif OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_SEM_CTR)0); } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_sem == (OS_SEM *)0) { /* Validate 'p_sem' */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_POST_FAILED(p_sem); /* Record the event. */ #endif *p_err = OS_ERR_OBJ_PTR_NULL; return ((OS_SEM_CTR)0); } switch (opt) { /* Validate 'opt' */ case OS_OPT_POST_1: case OS_OPT_POST_ALL: case OS_OPT_POST_1 | OS_OPT_POST_NO_SCHED: case OS_OPT_POST_ALL | OS_OPT_POST_NO_SCHED: break; default: #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_POST_FAILED(p_sem); /* Record the event. */ #endif *p_err = OS_ERR_OPT_INVALID; return ((OS_SEM_CTR)0u); } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_sem->Type != OS_OBJ_TYPE_SEM) { /* Make sure semaphore was created */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_POST_FAILED(p_sem); /* Record the event. */ #endif *p_err = OS_ERR_OBJ_TYPE; return ((OS_SEM_CTR)0); } #endif ts = OS_TS_GET(); /* Get timestamp */ #if OS_CFG_ISR_POST_DEFERRED_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if called from an ISR */ OS_IntQPost((OS_OBJ_TYPE)OS_OBJ_TYPE_SEM, /* Post to ISR queue */ (void *)p_sem, (void *)0, (OS_MSG_SIZE)0, (OS_FLAGS )0, (OS_OPT )opt, (CPU_TS )ts, (OS_ERR *)p_err); return ((OS_SEM_CTR)0); } #endif #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_POST(p_sem); /* Record the event. */ #endif ctr = OS_SemPost(p_sem, /* Post to semaphore */ opt, ts, p_err); return (ctr); }
OS_OBJ_QTY OSQDel (OS_Q *p_q, OS_OPT opt, OS_ERR *p_err) { OS_OBJ_QTY cnt; OS_OBJ_QTY nbr_tasks; OS_PEND_DATA *p_pend_data; OS_PEND_LIST *p_pend_list; OS_TCB *p_tcb; CPU_TS ts; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_OBJ_QTY)0); } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Can't delete a message queue from an ISR */ *p_err = OS_ERR_DEL_ISR; return ((OS_OBJ_QTY)0); } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_q == (OS_Q *)0) { /* Validate 'p_q' */ *p_err = OS_ERR_OBJ_PTR_NULL; return ((OS_OBJ_QTY)0u); } switch (opt) { /* Validate 'opt' */ case OS_OPT_DEL_NO_PEND: case OS_OPT_DEL_ALWAYS: break; default: *p_err = OS_ERR_OPT_INVALID; return ((OS_OBJ_QTY)0u); } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_q->Type != OS_OBJ_TYPE_Q) { /* Make sure message queue was created */ *p_err = OS_ERR_OBJ_TYPE; return ((OS_OBJ_QTY)0); } #endif CPU_CRITICAL_ENTER(); p_pend_list = &p_q->PendList; cnt = p_pend_list->NbrEntries; nbr_tasks = cnt; switch (opt) { case OS_OPT_DEL_NO_PEND: /* Delete message queue only if no task waiting */ if (nbr_tasks == (OS_OBJ_QTY)0) { #if OS_CFG_DBG_EN > 0u OS_QDbgListRemove(p_q); #endif OSQQty--; OS_QClr(p_q); CPU_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; } else { CPU_CRITICAL_EXIT(); *p_err = OS_ERR_TASK_WAITING; } break; case OS_OPT_DEL_ALWAYS: /* Always delete the message queue */ OS_CRITICAL_ENTER_CPU_EXIT(); ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */ while (cnt > 0u) { /* Remove all tasks from the pend list */ p_pend_data = p_pend_list->HeadPtr; p_tcb = p_pend_data->TCBPtr; OS_PendObjDel((OS_PEND_OBJ *)((void *)p_q), p_tcb, ts); cnt--; } #if OS_CFG_DBG_EN > 0u OS_QDbgListRemove(p_q); #endif OSQQty--; OS_QClr(p_q); OS_CRITICAL_EXIT_NO_SCHED(); OSSched(); /* Find highest priority task ready to run */ *p_err = OS_ERR_NONE; break; default: CPU_CRITICAL_EXIT(); *p_err = OS_ERR_OPT_INVALID; break; } return (nbr_tasks); }
void OSSemCreate (OS_SEM *p_sem, CPU_CHAR *p_name, OS_SEM_CTR cnt, OS_ERR *p_err) { CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #ifdef OS_SAFETY_CRITICAL_IEC61508 if (OSSafetyCriticalStartFlag == DEF_TRUE) { *p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME; return; } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to be called from an ISR */ *p_err = OS_ERR_CREATE_ISR; return; } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_sem == (OS_SEM *)0) { /* Validate 'p_sem' */ *p_err = OS_ERR_OBJ_PTR_NULL; return; } #endif OS_CRITICAL_ENTER(); #if OS_OBJ_TYPE_REQ > 0u p_sem->Type = OS_OBJ_TYPE_SEM; /* Mark the data structure as a semaphore */ #endif p_sem->Ctr = cnt; /* Set semaphore value */ p_sem->TS = (CPU_TS)0; #if OS_CFG_DBG_EN > 0u p_sem->NamePtr = p_name; /* Save the name of the semaphore */ #else (void)&p_name; #endif OS_PendListInit(&p_sem->PendList); /* Initialize the waiting list */ #if OS_CFG_DBG_EN > 0u OS_SemDbgListAdd(p_sem); #endif OSSemQty++; #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_SEM_CREATE(p_sem, p_name); /* Record the event. */ #endif OS_CRITICAL_EXIT_NO_SCHED(); *p_err = OS_ERR_NONE; }
OS_OBJ_QTY OSQPendAbort (OS_Q *p_q, OS_OPT opt, OS_ERR *p_err) { OS_PEND_LIST *p_pend_list; OS_TCB *p_tcb; CPU_TS ts; OS_OBJ_QTY nbr_tasks; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_OBJ_QTY)0u); } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to Pend Abort from an ISR */ *p_err = OS_ERR_PEND_ABORT_ISR; return ((OS_OBJ_QTY)0u); } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_q == (OS_Q *)0) { /* Validate 'p_q' */ *p_err = OS_ERR_OBJ_PTR_NULL; return ((OS_OBJ_QTY)0u); } switch (opt) { /* Validate 'opt' */ case OS_OPT_PEND_ABORT_1: case OS_OPT_PEND_ABORT_ALL: case OS_OPT_PEND_ABORT_1 | OS_OPT_POST_NO_SCHED: case OS_OPT_PEND_ABORT_ALL | OS_OPT_POST_NO_SCHED: break; default: *p_err = OS_ERR_OPT_INVALID; return ((OS_OBJ_QTY)0u); } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_q->Type != OS_OBJ_TYPE_Q) { /* Make sure queue was created */ *p_err = OS_ERR_OBJ_TYPE; return ((OS_OBJ_QTY)0u); } #endif CPU_CRITICAL_ENTER(); p_pend_list = &p_q->PendList; if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0u) { /* Any task waiting on queue? */ CPU_CRITICAL_EXIT(); /* No */ *p_err = OS_ERR_PEND_ABORT_NONE; return ((OS_OBJ_QTY)0u); } OS_CRITICAL_ENTER_CPU_EXIT(); nbr_tasks = 0u; ts = OS_TS_GET(); /* Get local time stamp so all tasks get the same time */ while (p_pend_list->NbrEntries > (OS_OBJ_QTY)0u) { p_tcb = p_pend_list->HeadPtr->TCBPtr; OS_PendAbort((OS_PEND_OBJ *)((void *)p_q), p_tcb, ts); nbr_tasks++; if (opt != OS_OPT_PEND_ABORT_ALL) { /* Pend abort all tasks waiting? */ break; /* No */ } } OS_CRITICAL_EXIT_NO_SCHED(); if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0u) { OSSched(); /* Run the scheduler */ } *p_err = OS_ERR_NONE; return (nbr_tasks); }
OS_TMR *OSTmrCreate (INT32U dly, INT32U period, INT8U opt, OS_TMR_CALLBACK callback, void *callback_arg, INT8U *pname, INT8U *perr) { OS_TMR *ptmr; #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_TMR *)0); } #endif #ifdef OS_SAFETY_CRITICAL_IEC61508 if (OSSafetyCriticalStartFlag == OS_TRUE) { OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_TMR *)0); } #endif #if OS_ARG_CHK_EN > 0u switch (opt) { /* Validate arguments */ case OS_TMR_OPT_PERIODIC: if (period == 0u) { *perr = OS_ERR_TMR_INVALID_PERIOD; return ((OS_TMR *)0); } break; case OS_TMR_OPT_ONE_SHOT: if (dly == 0u) { *perr = OS_ERR_TMR_INVALID_DLY; return ((OS_TMR *)0); } break; default: *perr = OS_ERR_TMR_INVALID_OPT; return ((OS_TMR *)0); } #endif if (OSIntNesting > 0u) { /* See if trying to call from an ISR */ *perr = OS_ERR_TMR_ISR; return ((OS_TMR *)0); } OSSchedLock(); ptmr = OSTmr_Alloc(); /* Obtain a timer from the free pool */ if (ptmr == (OS_TMR *)0) { OSSchedUnlock(); *perr = OS_ERR_TMR_NON_AVAIL; return ((OS_TMR *)0); } ptmr->OSTmrState = OS_TMR_STATE_STOPPED; /* Indicate that timer is not running yet */ ptmr->OSTmrDly = dly; ptmr->OSTmrPeriod = period; ptmr->OSTmrOpt = opt; ptmr->OSTmrCallback = callback; ptmr->OSTmrCallbackArg = callback_arg; #if OS_TMR_CFG_NAME_EN > 0u if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */ ptmr->OSTmrName = (INT8U *)(void *)"?"; } else { ptmr->OSTmrName = pname; } #endif OSSchedUnlock(); *perr = OS_ERR_NONE; return (ptmr); }
void OSTimeDlyHMSM (CPU_INT16U hours, CPU_INT16U minutes, CPU_INT16U seconds, CPU_INT32U milli, OS_OPT opt, OS_ERR *p_err) { #if OS_CFG_ARG_CHK_EN > 0u CPU_BOOLEAN opt_invalid; CPU_BOOLEAN opt_non_strict; #endif OS_OPT opt_time; OS_RATE_HZ tick_rate; OS_TICK ticks; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { /* Not allowed to call from an ISR */ *p_err = OS_ERR_TIME_DLY_ISR; return; } #endif if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0u) { /* Can't delay when the scheduler is locked */ *p_err = OS_ERR_SCHED_LOCKED; return; } opt_time = opt & OS_OPT_TIME_MASK; /* Retrieve time options only. */ switch (opt_time) { case OS_OPT_TIME_DLY: case OS_OPT_TIME_TIMEOUT: case OS_OPT_TIME_PERIODIC: if (milli == (CPU_INT32U)0u) { /* Make sure we didn't specify a 0 delay */ if (seconds == (CPU_INT16U)0u) { if (minutes == (CPU_INT16U)0u) { if (hours == (CPU_INT16U)0u) { *p_err = OS_ERR_TIME_ZERO_DLY; return; } } } } break; case OS_OPT_TIME_MATCH: break; default: *p_err = OS_ERR_OPT_INVALID; return; } #if OS_CFG_ARG_CHK_EN > 0u /* Validate arguments to be within range */ opt_invalid = DEF_BIT_IS_SET_ANY(opt, ~OS_OPT_TIME_OPTS_MASK); if (opt_invalid == DEF_YES) { *p_err = OS_ERR_OPT_INVALID; return; } opt_non_strict = DEF_BIT_IS_SET(opt, OS_OPT_TIME_HMSM_NON_STRICT); if (opt_non_strict != DEF_YES) { if (milli > (CPU_INT32U)999u) { *p_err = OS_ERR_TIME_INVALID_MILLISECONDS; return; } if (seconds > (CPU_INT16U)59u) { *p_err = OS_ERR_TIME_INVALID_SECONDS; return; } if (minutes > (CPU_INT16U)59u) { *p_err = OS_ERR_TIME_INVALID_MINUTES; return; } if (hours > (CPU_INT16U)99u) { *p_err = OS_ERR_TIME_INVALID_HOURS; return; } } else { if (minutes > (CPU_INT16U)9999u) { *p_err = OS_ERR_TIME_INVALID_MINUTES; return; } if (hours > (CPU_INT16U)999u) { *p_err = OS_ERR_TIME_INVALID_HOURS; return; } } #endif /* Compute the total number of clock ticks required.. */ /* .. (rounded to the nearest tick) */ tick_rate = OSCfg_TickRate_Hz; ticks = ((OS_TICK)hours * (OS_TICK)3600u + (OS_TICK)minutes * (OS_TICK)60u + (OS_TICK)seconds) * tick_rate + (tick_rate * ((OS_TICK)milli + (OS_TICK)500u / tick_rate)) / (OS_TICK)1000u; if (ticks > (OS_TICK)0u) { OS_CRITICAL_ENTER(); OSTCBCurPtr->TaskState = OS_TASK_STATE_DLY; OS_TickListInsert(OSTCBCurPtr, ticks, opt_time, p_err); if (*p_err != OS_ERR_NONE) { OS_CRITICAL_EXIT_NO_SCHED(); return; } OS_RdyListRemove(OSTCBCurPtr); /* Remove current task from ready list */ OS_CRITICAL_EXIT_NO_SCHED(); OSSched(); /* Find next task to run! */ *p_err = OS_ERR_NONE; } else { *p_err = OS_ERR_TIME_ZERO_DLY; } }
OS_OBJ_QTY OSMutexDel (OS_MUTEX *p_mutex, OS_OPT opt, OS_ERR *p_err) { OS_OBJ_QTY cnt; OS_OBJ_QTY nbr_tasks; OS_PEND_DATA *p_pend_data; OS_PEND_LIST *p_pend_list; OS_TCB *p_tcb; OS_TCB *p_tcb_owner; CPU_TS ts; CPU_SR_ALLOC(); #ifdef OS_SAFETY_CRITICAL if (p_err == (OS_ERR *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_OBJ_QTY)0); } #endif #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to delete a mutex from an ISR */ *p_err = OS_ERR_DEL_ISR; return ((OS_OBJ_QTY)0); } #endif #if OS_CFG_ARG_CHK_EN > 0u if (p_mutex == (OS_MUTEX *)0) { /* Validate 'p_mutex' */ *p_err = OS_ERR_OBJ_PTR_NULL; return ((OS_OBJ_QTY)0); } switch (opt) { /* Validate 'opt' */ case OS_OPT_DEL_NO_PEND: case OS_OPT_DEL_ALWAYS: break; default: *p_err = OS_ERR_OPT_INVALID; return ((OS_OBJ_QTY)0); } #endif #if OS_CFG_OBJ_TYPE_CHK_EN > 0u if (p_mutex->Type != OS_OBJ_TYPE_MUTEX) { /* Make sure mutex was created */ *p_err = OS_ERR_OBJ_TYPE; return ((OS_OBJ_QTY)0); } #endif OS_CRITICAL_ENTER(); p_pend_list = &p_mutex->PendList; cnt = p_pend_list->NbrEntries; nbr_tasks = cnt; switch (opt) { case OS_OPT_DEL_NO_PEND: /* Delete mutex only if no task waiting */ if (nbr_tasks == (OS_OBJ_QTY)0) { #if OS_CFG_DBG_EN > 0u OS_MutexDbgListRemove(p_mutex); #endif OSMutexQty--; #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_DEL(p_mutex); /* Record the event. */ #endif OS_MutexClr(p_mutex); OS_CRITICAL_EXIT(); *p_err = OS_ERR_NONE; } else { OS_CRITICAL_EXIT(); *p_err = OS_ERR_TASK_WAITING; } break; case OS_OPT_DEL_ALWAYS: /* Always delete the mutex */ p_tcb_owner = p_mutex->OwnerTCBPtr; /* Did we had to change the prio of owner? */ if ((p_tcb_owner != (OS_TCB *)0) && (p_tcb_owner->Prio != p_mutex->OwnerOriginalPrio)) { switch (p_tcb_owner->TaskState) { /* yes */ case OS_TASK_STATE_RDY: OS_RdyListRemove(p_tcb_owner); p_tcb_owner->Prio = p_mutex->OwnerOriginalPrio; /* Lower owner's prio back */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_DISINHERIT(p_tcb_owner, p_tcb_owner->Prio) #endif OS_PrioInsert(p_tcb_owner->Prio); OS_RdyListInsertTail(p_tcb_owner); /* Insert owner in ready list at new prio */ break; case OS_TASK_STATE_DLY: case OS_TASK_STATE_SUSPENDED: case OS_TASK_STATE_DLY_SUSPENDED: p_tcb_owner->Prio = p_mutex->OwnerOriginalPrio; /* Not in any pend list, change the prio */ #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_DISINHERIT(p_tcb_owner, p_tcb_owner->Prio) #endif break; case OS_TASK_STATE_PEND: case OS_TASK_STATE_PEND_TIMEOUT: case OS_TASK_STATE_PEND_SUSPENDED: case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED: OS_PendListChangePrio(p_tcb_owner, /* Owner is pending on another object */ p_mutex->OwnerOriginalPrio); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_DISINHERIT(p_tcb_owner, p_tcb_owner->Prio) #endif break; default: OS_CRITICAL_EXIT(); *p_err = OS_ERR_STATE_INVALID; return ((OS_OBJ_QTY)0); } } ts = OS_TS_GET(); /* Get timestamp */ while (cnt > 0u) { /* Remove all tasks from the pend list */ p_pend_data = p_pend_list->HeadPtr; p_tcb = p_pend_data->TCBPtr; OS_PendObjDel((OS_PEND_OBJ *)((void *)p_mutex), p_tcb, ts); cnt--; } #if OS_CFG_DBG_EN > 0u OS_MutexDbgListRemove(p_mutex); #endif OSMutexQty--; #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_DEL(p_mutex); /* Record the event. */ #endif OS_MutexClr(p_mutex); OS_CRITICAL_EXIT_NO_SCHED(); OSSched(); /* Find highest priority task ready to run */ *p_err = OS_ERR_NONE; break; default: OS_CRITICAL_EXIT(); *p_err = OS_ERR_OPT_INVALID; break; } return (nbr_tasks); }