Esempio n. 1
0
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
    }
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}