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_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_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; }
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_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; }
nOS_Error nOS_QueueWrite (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 /* If count equal 0, there are chances some threads can wait to read from queue */ if (queue->bcount == 0) { /* Check if thread waiting to read from queue */ thread = nOS_SendEvent((nOS_Event*)queue, NOS_OK); if (thread != NULL) { /* Direct copy between thread's buffers */ memcpy(thread->ext, block, queue->bsize); #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 (queue->buffer != NULL) { /* No thread waiting to read from queue, then store it */ _Write(queue, block); err = NOS_OK; } else { /* No thread waiting to consume message, inform producer */ err = NOS_E_NO_CONSUMER; } } else if (queue->bcount < queue->bmax) { /* No chance a thread waiting to read from queue if count is higher than 0 */ _Write(queue, block); err = NOS_OK; } else if (timeout == NOS_NO_WAIT) { err = NOS_E_FULL; } else { nOS_runningThread->ext = block; err = nOS_WaitForEvent((nOS_Event*)queue, NOS_THREAD_WRITING_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; }
nOS_Error nOS_FlagWait (nOS_Flag *flag, nOS_FlagBits flags, nOS_FlagBits *res, nOS_FlagOption opt, nOS_TickCounter timeout) { nOS_Error err; nOS_StatusReg sr; nOS_FlagContext ctx; nOS_FlagBits r; #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 { r = flag->flags & flags; /* If thread is waiting for ALL flags, then clear result if NOT ALL flags set. */ if (((opt & NOS_FLAG_WAIT) == NOS_FLAG_WAIT_ALL) && (r != flags)) { r = NOS_FLAG_NONE; } /* If result is not cleared, then condition is met for waiting thread. */ if (r != NOS_FLAG_NONE) { if (opt & NOS_FLAG_CLEAR_ON_EXIT) { /* Clear all flags that have awoken the waiting threads. */ flag->flags &=~ r; } err = NOS_OK; } else if (timeout == NOS_NO_WAIT) { /* Caller can't wait? Try again. */ err = NOS_E_AGAIN; } else { /* Calling thread must wait on flag. */ ctx.flags = flags; ctx.opt = opt; ctx.rflags = &r; nOS_runningThread->ext = &ctx; err = nOS_WaitForEvent((nOS_Event*)flag, NOS_THREAD_WAITING_FLAG #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 awoken flags if succeed to wait on flag object. */ if (err == NOS_OK && res != NULL) { *res = r; } } return err; }
nOS_Error nOS_FlagWait (nOS_Flag *flag, nOS_FlagBits flags, nOS_FlagBits *res, nOS_FlagOption opt, nOS_TickCounter tout) { nOS_Error err; nOS_StatusReg sr; nOS_FlagContext ctx; nOS_FlagBits r; #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 { r = flag->flags & flags; /* If thread is waiting for ALL flags, then clear result if NOT ALL flags set. */ if (((opt & NOS_FLAG_WAIT) == NOS_FLAG_WAIT_ALL) && (r != flags)) { r = NOS_FLAG_NONE; } /* If result is not cleared, then condition is met for waiting thread. */ if (r != NOS_FLAG_NONE) { if (opt & NOS_FLAG_CLEAR_ON_EXIT) { /* Clear all flags that have awoken the waiting threads. */ flag->flags &=~ r; } err = NOS_OK; } else if (tout == NOS_NO_WAIT) { /* Caller can't wait? Try again. */ 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 flag. */ ctx.flags = flags; ctx.opt = opt; ctx.rflags = &r; nOS_runningThread->ext = &ctx; err = nOS_WaitForEvent((nOS_Event*)flag, NOS_THREAD_WAITING_FLAG, tout); } } nOS_LeaveCritical(sr); /* Return awoken flags if succeed to wait on flag object. */ if (err == NOS_OK) { if (res != NULL) { *res = r; } } } return err; }
nOS_Error nOS_QueueWrite (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 { /* If count equal 0, there are chances some threads can wait to read from queue */ if (queue->bcount == 0) { /* Check if thread waiting to read from queue */ thread = nOS_SendEvent((nOS_Event*)queue, NOS_OK); if (thread != NULL) { /* Direct copy between thread's buffers */ memcpy(thread->ext, block, queue->bsize); #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 (queue->buffer != NULL) { /* No thread waiting to read from queue, then store it */ _Write(queue, block); err = NOS_OK; } else { /* No thread waiting to consume message, inform producer */ err = NOS_E_NO_CONSUMER; } } else if (queue->bcount < queue->bmax) { /* No chance a thread waiting to read from queue if count is higher than 0 */ _Write(queue, block); err = NOS_OK; } else if (timeout == NOS_NO_WAIT) { err = NOS_E_FULL; } 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) { /* Main threadv can't wait. */ err = NOS_E_IDLE; } else { nOS_runningThread->ext = block; err = nOS_WaitForEvent((nOS_Event*)queue, NOS_THREAD_WRITING_QUEUE, timeout); } } nOS_LeaveCritical(sr); } return err; }