nOS_Error nOS_TimerCreate (nOS_Timer *timer, nOS_TimerCallback callback, void *arg, nOS_TimerCounter reload, nOS_TimerMode mode) { nOS_Error err; #if (NOS_CONFIG_SAFE > 0) if (timer == NULL) { err = NOS_E_INV_OBJ; } else if (timer->state != NOS_TIMER_DELETED) { err = NOS_E_INV_OBJ; } else if ((mode != NOS_TIMER_FREE_RUNNING) && (mode != NOS_TIMER_ONE_SHOT)) { err = NOS_E_INV_VAL; } else #endif { timer->count = 0; timer->reload = reload; timer->state = (nOS_TimerState)(NOS_TIMER_CREATED | (nOS_TimerState)(mode & NOS_TIMER_MODE)); timer->callback = callback; timer->arg = arg; timer->node.payload = (void *)timer; nOS_EnterCritical(); nOS_AppendToList(&_timerList, &timer->node); nOS_LeaveCritical(); err = NOS_OK; } return err; }
static void _TickTimer (void *payload, void *arg) { nOS_Timer *timer = (nOS_Timer *)payload; bool call = false; NOS_UNUSED(arg); nOS_EnterCritical(); if ((timer->state & (NOS_TIMER_RUNNING | NOS_TIMER_PAUSED)) == NOS_TIMER_RUNNING) { if (timer->count > 0) { timer->count--; } if (timer->count == 0) { if (((nOS_TimerMode)timer->state & NOS_TIMER_MODE) == NOS_TIMER_FREE_RUNNING) { timer->count = timer->reload; /* One-shot timer */ } else { timer->state = (nOS_TimerState)(timer->state &~ NOS_TIMER_RUNNING); } /* Call callback function outside of critical section */ call = true; } } nOS_LeaveCritical(); if (call) { if (timer->callback != NULL) { timer->callback(timer, timer->arg); } } }
nOS_Error nOS_ThreadSuspendAll (void) { nOS_Error err; nOS_StatusReg sr; #if (NOS_CONFIG_SAFE > 0) #if (NOS_CONFIG_SCHED_LOCK_ENABLE > 0) /* Can't suspend all threads from any thread (except idle) when scheduler is locked */ if ((nOS_lockNestingCounter > 0) && (nOS_runningThread != &nOS_idleHandle)) { err = NOS_E_LOCKED; } else #endif #endif { nOS_EnterCritical(sr); nOS_WalkInList(&nOS_allThreadsList, _SuspendThread, NULL); if (nOS_runningThread != &nOS_idleHandle) { nOS_Schedule(); } nOS_LeaveCritical(sr); err = NOS_OK; } return err; }
nOS_Error nOS_SemDelete (nOS_Sem *sem) { nOS_Error err; #if (NOS_CONFIG_SAFE > 0) if (sem == NULL) { err = NOS_E_INV_OBJ; } else if (sem->e.type != NOS_EVENT_SEM) { err = NOS_E_INV_OBJ; } else #endif { nOS_EnterCritical(); sem->count = 0; sem->max = 0; #if (NOS_CONFIG_HIGHEST_THREAD_PRIO > 0) && (NOS_CONFIG_SCHED_PREEMPTIVE_ENABLE > 0) if (nOS_DeleteEvent((nOS_Event*)sem)) { nOS_Schedule(); } #else nOS_DeleteEvent((nOS_Event*)sem); #endif nOS_LeaveCritical(); err = NOS_OK; } return err; }
nOS_Error nOS_QueueDelete (nOS_Queue *queue) { nOS_Error err; nOS_StatusReg sr; #if (NOS_CONFIG_SAFE > 0) if (queue == NULL) { err = NOS_E_INV_OBJ; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (queue->e.type != NOS_EVENT_QUEUE) { err = NOS_E_INV_OBJ; } else #endif { _Flush(queue); queue->buffer = NULL; queue->bsize = 0; queue->bmax = 0; nOS_DeleteEvent((nOS_Event*)queue); err = NOS_OK; } nOS_LeaveCritical(sr); } return err; }
nOS_Error nOS_SignalDelete (nOS_Signal *signal) { nOS_Error err; nOS_StatusReg sr; #if (NOS_CONFIG_SAFE > 0) if (signal == NULL) { err = NOS_E_INV_OBJ; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (signal->state == NOS_SIGNAL_DELETED) { err = NOS_E_INV_OBJ; } else #endif { if (signal->state & NOS_SIGNAL_RAISED) { nOS_RemoveFromList(&_signalList, &signal->node); } signal->state = NOS_SIGNAL_DELETED; signal->callback = NULL; signal->node.payload = NULL; err = NOS_OK; } nOS_LeaveCritical(sr); } return err; }
bool nOS_LeaveIsr (void) { nOS_StatusReg sr; bool swctx = false; #if (NOS_CONFIG_SAFE > 0) if (nOS_running) #endif { nOS_EnterCritical(sr); nOS_isrNestingCounter--; #if (NOS_CONFIG_SCHED_PREEMPTIVE_ENABLE > 0) if (nOS_isrNestingCounter == 0) { #if (NOS_CONFIG_SCHED_LOCK_ENABLE > 0) if (nOS_lockNestingCounter == 0) #endif { nOS_highPrioThread = nOS_FindHighPrioThread(); if (nOS_runningThread != nOS_highPrioThread) { swctx = true; } } } #endif nOS_LeaveCritical(sr); } return swctx; }
nOS_Error nOS_SignalCreate (nOS_Signal *signal, nOS_SignalCallback callback) { nOS_Error err; nOS_StatusReg sr; #if (NOS_CONFIG_SAFE > 0) if (signal == NULL) { err = NOS_E_INV_OBJ; } else if (callback == NULL) { err = NOS_E_INV_VAL; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (signal->state != NOS_SIGNAL_DELETED) { err = NOS_E_INV_OBJ; } else #endif { signal->state = NOS_SIGNAL_CREATED; signal->callback = callback; signal->node.payload = (void *)signal; err = NOS_OK; } nOS_LeaveCritical(sr); } return err; }
void nOS_LeaveIsr (void) { nOS_StatusReg sr; #if (NOS_CONFIG_SAFE > 0) if (nOS_running) #endif { nOS_EnterCritical(sr); nOS_isrNestingCounter--; #if (NOS_CONFIG_SCHED_PREEMPTIVE_ENABLE > 0) || (NOS_CONFIG_SCHED_ROUND_ROBIN_ENABLE > 0) if (nOS_isrNestingCounter == 0) { #if (NOS_CONFIG_SCHED_LOCK_ENABLE > 0) if (nOS_lockNestingCounter == 0) #endif { #if (NOS_CONFIG_HIGHEST_THREAD_PRIO == 0) nOS_highPrioThread = nOS_GetHeadOfList(&nOS_readyThreadsList); #elif (NOS_CONFIG_SCHED_PREEMPTIVE_ENABLE > 0) nOS_highPrioThread = nOS_FindHighPrioThread(); #else nOS_highPrioThread = nOS_GetHeadOfList(&nOS_readyThreadsList[nOS_runningThread->prio]); #endif if (nOS_runningThread != nOS_highPrioThread) { *(volatile uint32_t *)0xE000ED04UL = 0x10000000UL; } } } #endif nOS_LeaveCritical(sr); } }
bool nOS_QueueIsFull (nOS_Queue *queue) { nOS_StatusReg sr; bool full; #if (NOS_CONFIG_SAFE > 0) if (queue == NULL) { full = false; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (queue->e.type != NOS_EVENT_QUEUE) { full = false; } else #endif { if (queue->buffer != NULL) { full = (queue->bcount == queue->bmax); } else { full = false; } } nOS_LeaveCritical(sr); } return full; }
void nOS_SignalProcess (void) { nOS_StatusReg sr; nOS_Signal *signal = NULL; nOS_SignalCallback callback = NULL; void *arg = NULL; nOS_EnterCritical(sr); if (nOS_SemTake (&_signalSem, #if (NOS_CONFIG_SIGNAL_THREAD_ENABLE > 0) NOS_WAIT_INFINITE #else NOS_NO_WAIT #endif ) == NOS_OK) { signal = (nOS_Signal *)nOS_GetHeadOfList(&_signalList); if (signal != NULL) { if (signal->state & NOS_SIGNAL_RAISED) { signal->state = (nOS_SignalState)(signal->state &~ NOS_SIGNAL_RAISED); nOS_RemoveFromList(&_signalList, &signal->node); callback = signal->callback; arg = signal->arg; } } } nOS_LeaveCritical(sr); if (callback != NULL) { callback(signal, arg); } }
nOS_Error nOS_QueuePeek (nOS_Queue *queue, void *block) { nOS_Error err; nOS_StatusReg sr; #if (NOS_CONFIG_SAFE > 0) if (queue == NULL) { err = NOS_E_INV_OBJ; } else if (block == NULL) { err = NOS_E_NULL; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (queue->e.type != NOS_EVENT_QUEUE) { err = NOS_E_INV_OBJ; } else #endif if (queue->bcount > 0) { memcpy(block, &queue->buffer[(size_t)queue->r * (size_t)queue->bsize], queue->bsize); err = NOS_OK; } else { err = NOS_E_EMPTY; } nOS_LeaveCritical(sr); } return err; }
nOS_Error nOS_FlagDelete (nOS_Flag *flag) { nOS_Error err; nOS_StatusReg sr; #if (NOS_CONFIG_SAFE > 0) if (flag == NULL) { err = NOS_E_INV_OBJ; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (flag->e.type != NOS_EVENT_FLAG) { err = NOS_E_INV_OBJ; } else #endif { flag->flags = NOS_FLAG_NONE; nOS_DeleteEvent((nOS_Event*)flag); err = NOS_OK; } nOS_LeaveCritical(sr); } return err; }
nOS_Stack* nOS_LeaveIsr (nOS_Stack *sp) { nOS_StatusReg sr; #if (NOS_CONFIG_SAFE > 0) if (nOS_running) #endif { nOS_EnterCritical(sr); nOS_isrNestingCounter--; if (nOS_isrNestingCounter == 0) { #if (NOS_CONFIG_SCHED_PREEMPTIVE_ENABLE > 0) #if (NOS_CONFIG_SCHED_LOCK_ENABLE > 0) if (nOS_lockNestingCounter == 0) #endif { nOS_highPrioThread = nOS_FindHighPrioThread(); nOS_runningThread = nOS_highPrioThread; } #endif sp = nOS_runningThread->stackPtr; } nOS_LeaveCritical(sr); } return sp; }
static void _Thread (void *arg) #endif { nOS_StatusReg sr; NOS_UNUSED(arg); while (true) { nOS_AlarmProcess(); nOS_EnterCritical(sr); if (nOS_GetHeadOfList(&_triggeredList) == NULL) { nOS_WaitForEvent(NULL, NOS_THREAD_ON_HOLD #if (NOS_CONFIG_WAITING_TIMEOUT_ENABLE > 0) || (NOS_CONFIG_SLEEP_ENABLE > 0) || (NOS_CONFIG_SLEEP_UNTIL_ENABLE > 0) ,NOS_WAIT_INFINITE #endif ); } nOS_LeaveCritical(sr); #if (NOS_CONFIG_THREAD_JOIN_ENABLE > 0) if (false) break; /* Remove "statement is unreachable" warning */ } return 0; #else }
nOS_Error nOS_FlagCreate (nOS_Flag *flag, nOS_FlagBits flags) { nOS_Error err; nOS_StatusReg sr; #if (NOS_CONFIG_SAFE > 0) if (flag == NULL) { err = NOS_E_INV_OBJ; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (flag->e.type != NOS_EVENT_INVALID) { err = NOS_E_INV_OBJ; } else #endif { nOS_CreateEvent((nOS_Event*)flag #if (NOS_CONFIG_SAFE > 0) ,NOS_EVENT_FLAG #endif ); flag->flags = flags; err = NOS_OK; } nOS_LeaveCritical(sr); } return err; }
nOS_QueueCounter nOS_QueueGetCount (nOS_Queue *queue) { nOS_StatusReg sr; nOS_QueueCounter bcount; #if (NOS_CONFIG_SAFE > 0) if (queue == NULL) { bcount = 0; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (queue->e.type != NOS_EVENT_QUEUE) { bcount = 0; } else #endif { bcount = queue->bcount; } nOS_LeaveCritical(sr); } return bcount; }
nOS_Error nOS_TimeWait (nOS_Time time) { nOS_Error err; if (nOS_isrNestingCounter > 0) { err = NOS_E_ISR; } #if (NOS_CONFIG_SCHED_LOCK_ENABLE > 0) else if (nOS_lockNestingCounter > 0) { /* Can't switch context when scheduler is locked */ err = NOS_E_LOCKED; } #endif else if (nOS_runningThread == &nOS_idleHandle) { err = NOS_E_IDLE; } else { nOS_EnterCritical(); if (_timeCounter < time) { err = NOS_E_ELAPSED; } else if (_timeCounter == time) { err = NOS_OK; } else { nOS_runningThread->ext = (void*)&time; err = nOS_WaitForEvent(&_timeEvent, NOS_THREAD_WAITING_TIME, NOS_WAIT_INFINITE); } nOS_LeaveCritical(); } return err; }
nOS_Error nOS_FlagDelete (nOS_Flag *flag) { nOS_Error err; nOS_StatusReg sr; #if (NOS_CONFIG_SAFE > 0) if (flag == NULL) { err = NOS_E_INV_OBJ; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (flag->e.type != NOS_EVENT_FLAG) { err = NOS_E_INV_OBJ; } else #endif { flag->flags = NOS_FLAG_NONE; #if (NOS_CONFIG_HIGHEST_THREAD_PRIO > 0) && (NOS_CONFIG_SCHED_PREEMPTIVE_ENABLE > 0) if (nOS_DeleteEvent((nOS_Event*)flag)) { nOS_Schedule(); } #else nOS_DeleteEvent((nOS_Event*)flag); #endif err = NOS_OK; } nOS_LeaveCritical(sr); } return err; }
nOS_Error nOS_SignalSetCallback (nOS_Signal *signal, nOS_SignalCallback callback) { nOS_Error err; nOS_StatusReg sr; #if (NOS_CONFIG_SAFE > 0) if (signal == NULL) { err = NOS_E_INV_OBJ; } else if (callback == NULL) { err = NOS_E_INV_VAL; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (signal->state == NOS_SIGNAL_DELETED) { err = NOS_E_INV_OBJ; } else #endif { signal->callback = callback; err = NOS_OK; } nOS_LeaveCritical(sr); } return err; }
nOS_Error nOS_SemCreate (nOS_Sem *sem, nOS_SemCounter count, nOS_SemCounter max) { nOS_Error err; #if (NOS_CONFIG_SAFE > 0) if (sem == NULL) { err = NOS_E_INV_OBJ; } else if (sem->e.type != NOS_EVENT_INVALID) { err = NOS_E_INV_OBJ; } else if (count > max) { err = NOS_E_INV_VAL; } else #endif { nOS_EnterCritical(); #if (NOS_CONFIG_SAFE > 0) nOS_CreateEvent((nOS_Event*)sem, NOS_EVENT_SEM); #else nOS_CreateEvent((nOS_Event*)sem); #endif sem->count = count; sem->max = max; nOS_LeaveCritical(); err = NOS_OK; } return err; }
bool nOS_SignalIsRaised (nOS_Signal *signal) { nOS_StatusReg sr; bool raised; #if (NOS_CONFIG_SAFE > 0) if (signal == NULL) { raised = false; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (signal->state == NOS_SIGNAL_DELETED) { raised = false; } else #endif { raised = (signal->state & NOS_SIGNAL_RAISED) == NOS_SIGNAL_RAISED; } nOS_LeaveCritical(sr); } return raised; }
bool nOS_QueueIsFull (nOS_Queue *queue) { nOS_StatusReg sr; bool full; #if (NOS_CONFIG_SAFE > 0) if (queue == NULL) { full = false; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (queue->e.type != NOS_EVENT_QUEUE) { full = false; } else #endif { full = queue->buffer != NULL ? queue->bcount == queue->bmax : nOS_GetHeadOfList(&queue->e.waitList) != NULL ? /* A thread can be ready to consume message */ false : true; } nOS_LeaveCritical(sr); } return full; }
bool nOS_QueueIsEmpty (nOS_Queue *queue) { nOS_StatusReg sr; bool empty; #if (NOS_CONFIG_SAFE > 0) if (queue == NULL) { empty = false; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (queue->e.type != NOS_EVENT_QUEUE) { empty = false; } else #endif { empty = queue->buffer != NULL ? queue->bcount == 0 : true; } nOS_LeaveCritical(sr); } return empty; }
bool nOS_SemIsAvailable (nOS_Sem *sem) { nOS_StatusReg sr; bool avail; #if (NOS_CONFIG_SAFE > 0) if (sem == NULL) { avail = false; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (sem->e.type != NOS_EVENT_SEM) { avail = false; } else #endif { avail = (sem->count > 0); } nOS_LeaveCritical(sr); } return avail; }
nOS_Error nOS_QueueRead (nOS_Queue *queue, void *block, nOS_TickCounter timeout) { nOS_Error err; nOS_StatusReg sr; nOS_Thread *thread; #if (NOS_CONFIG_SAFE > 0) if (queue == NULL) { err = NOS_E_INV_OBJ; } else if (block == NULL) { err = NOS_E_NULL; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (queue->e.type != NOS_EVENT_QUEUE) { err = NOS_E_INV_OBJ; } else #endif { /* No chance a thread waiting to read from queue if count is higher than 0 */ if (queue->bcount > 0) { _Read(queue, block); /* Check if thread waiting to write in queue */ thread = nOS_SendEvent((nOS_Event*)queue, NOS_OK); if (thread != NULL) { /* Write thread's block in queue */ _Write(queue, thread->ext); #if (NOS_CONFIG_HIGHEST_THREAD_PRIO > 0) && (NOS_CONFIG_SCHED_PREEMPTIVE_ENABLE > 0) if ((thread->state == NOS_THREAD_READY) && (thread->prio > nOS_runningThread->prio)) { nOS_Schedule(); } #endif } err = NOS_OK; } else if (timeout == NOS_NO_WAIT) { err = NOS_E_EMPTY; } else if (nOS_isrNestingCounter > 0) { err = NOS_E_ISR; } #if (NOS_CONFIG_SCHED_LOCK_ENABLE > 0) else if (nOS_lockNestingCounter > 0) { err = NOS_E_LOCKED; } #endif else if (nOS_runningThread == &nOS_idleHandle) { err = NOS_E_IDLE; } else { nOS_runningThread->ext = block; err = nOS_WaitForEvent((nOS_Event*)queue, NOS_THREAD_READING_QUEUE, timeout); } } nOS_LeaveCritical(sr); } return err; }
void nOS_EnterIsr (void) { nOS_StatusReg sr; nOS_EnterCritical(sr); nOS_isrNestingCounter++; nOS_LeaveCritical(sr); }
nOS_Error nOS_SemTake (nOS_Sem *sem, nOS_TickCounter timeout) { nOS_Error err; nOS_StatusReg sr; #if (NOS_CONFIG_SAFE > 0) if (sem == NULL) { err = NOS_E_INV_OBJ; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (sem->e.type != NOS_EVENT_SEM) { err = NOS_E_INV_OBJ; } else #endif { if (sem->count > 0) { /* Sem available. */ sem->count--; err = NOS_OK; } else if (timeout == NOS_NO_WAIT) { /* Calling thread can't wait. */ err = NOS_E_AGAIN; } else if (nOS_isrNestingCounter > 0) { /* Can't wait from ISR */ err = NOS_E_ISR; } #if (NOS_CONFIG_SCHED_LOCK_ENABLE > 0) else if (nOS_lockNestingCounter > 0) { /* Can't switch context when scheduler is locked */ err = NOS_E_LOCKED; } #endif else if (nOS_runningThread == &nOS_idleHandle) { /* Main thread can't wait */ err = NOS_E_IDLE; } else { /* Calling thread must wait on sem. */ err = nOS_WaitForEvent((nOS_Event*)sem, NOS_THREAD_TAKING_SEM #if (NOS_CONFIG_WAITING_TIMEOUT_ENABLE > 0) || (NOS_CONFIG_SLEEP_ENABLE > 0) || (NOS_CONFIG_SLEEP_UNTIL_ENABLE > 0) #if (NOS_CONFIG_WAITING_TIMEOUT_ENABLE > 0) ,timeout #else ,NOS_WAIT_INFINITE #endif #endif ); } } nOS_LeaveCritical(sr); } return err; }
nOS_Time nOS_TimeGet (void) { nOS_Time time; nOS_EnterCritical(); time = _timeCounter; nOS_LeaveCritical(); return time; }
nOS_Error nOS_QueueRead (nOS_Queue *queue, void *block, nOS_TickCounter timeout) { nOS_Error err; nOS_StatusReg sr; nOS_Thread *thread; #if (NOS_CONFIG_SAFE > 0) if (queue == NULL) { err = NOS_E_INV_OBJ; } else if (block == NULL) { err = NOS_E_NULL; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (queue->e.type != NOS_EVENT_QUEUE) { err = NOS_E_INV_OBJ; } else #endif /* No chance a thread waiting to read from queue if count is higher than 0 */ if (queue->bcount > 0) { _Read(queue, block); /* Check if thread waiting to write in queue */ thread = nOS_SendEvent((nOS_Event*)queue, NOS_OK); if (thread != NULL) { /* Write thread's block in queue */ _Write(queue, thread->ext); #if (NOS_CONFIG_SCHED_PREEMPTIVE_ENABLE > 0) /* Verify if a highest prio thread is ready to run */ nOS_Schedule(); #endif } err = NOS_OK; } else if (timeout == NOS_NO_WAIT) { err = NOS_E_EMPTY; } else { nOS_runningThread->ext = block; err = nOS_WaitForEvent((nOS_Event*)queue, NOS_THREAD_READING_QUEUE #if (NOS_CONFIG_WAITING_TIMEOUT_ENABLE > 0) ,timeout #elif (NOS_CONFIG_SLEEP_ENABLE > 0) || (NOS_CONFIG_SLEEP_UNTIL_ENABLE > 0) ,NOS_WAIT_INFINITE #endif ); } nOS_LeaveCritical(sr); } return err; }