git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6264 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2013-09-05 12:33:42 +00:00
parent 95d85de7d5
commit 986a9d1db1
2 changed files with 83 additions and 73 deletions

View File

@ -160,6 +160,13 @@
#define NIL_CFG_ENABLE_ASSERTS FALSE #define NIL_CFG_ENABLE_ASSERTS FALSE
#endif #endif
/**
* @brief Stack check.
*/
#if !defined(NIL_CFG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
#define NIL_CFG_ENABLE_STACK_CHECK FALSE
#endif
/** /**
* @brief Threads descriptor structure extension. * @brief Threads descriptor structure extension.
* @details User fields added to the end of the @p thread_t structure. * @details User fields added to the end of the @p thread_t structure.
@ -249,7 +256,7 @@ struct nil_thread {
intctx_t *ctxp; /**< @brief Pointer to internal context. */ intctx_t *ctxp; /**< @brief Pointer to internal context. */
tstate_t state; /**< @brief Thread state. */ tstate_t state; /**< @brief Thread state. */
/* Note, the following union contains a pointer while the thread is in a /* Note, the following union contains a pointer while the thread is in a
sleeping state (!CH_THD_IS_READY()) else contains the wake-up message.*/ sleeping state (!NIL_THD_IS_READY()) else contains the wake-up message.*/
union { union {
msg_t msg; /**< @brief Wake-up message. */ msg_t msg; /**< @brief Wake-up message. */
void *p; /**< @brief Generic pointer. */ void *p; /**< @brief Generic pointer. */
@ -277,13 +284,13 @@ typedef struct {
/** /**
* @brief Pointer to the running thread. * @brief Pointer to the running thread.
*/ */
thread_reference_t current; thread_t *current;
/** /**
* @brief Pointer to the next thread to be executed. * @brief Pointer to the next thread to be executed.
* @note This pointer must point at the same thread pointed by @p currp * @note This pointer must point at the same thread pointed by @p currp
* or to an higher priority thread if a switch is required. * or to an higher priority thread if a switch is required.
*/ */
thread_reference_t next; thread_t *next;
#if NIL_CFG_TIMEDELTA == 0 || defined(__DOXYGEN__) #if NIL_CFG_TIMEDELTA == 0 || defined(__DOXYGEN__)
/** /**
* @brief System time. * @brief System time.
@ -726,7 +733,7 @@ extern "C" {
void chSysTimerHandlerI(void); void chSysTimerHandlerI(void);
syssts_t chSysGetStatusAndLockX(void); syssts_t chSysGetStatusAndLockX(void);
void chSysRestoreStatusX(syssts_t sts); void chSysRestoreStatusX(syssts_t sts);
thread_reference_t chSchReadyI(thread_reference_t trp, msg_t msg); thread_t *chSchReadyI(thread_t *tp, msg_t msg);
void chSchRescheduleS(void); void chSchRescheduleS(void);
msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout); msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout);
msg_t chThdSuspendTimeoutS(thread_reference_t *trp, systime_t timeout); msg_t chThdSuspendTimeoutS(thread_reference_t *trp, systime_t timeout);

View File

@ -66,25 +66,28 @@ nil_system_t nil;
* @special * @special
*/ */
void chSysInit(void) { void chSysInit(void) {
thread_reference_t tr; thread_t *tp;
const thread_config_t *tcp; const thread_config_t *tcp;
/* Port layer initialization.*/ /* Port layer initialization.*/
port_init(); port_init();
/* Iterates through the list of defined threads.*/ /* Iterates through the list of defined threads.*/
for (tr = &nil.threads[0], tcp = nil_thd_configs; for (tp = &nil.threads[0], tcp = nil_thd_configs;
tr < &nil.threads[NIL_CFG_NUM_THREADS]; tp < &nil.threads[NIL_CFG_NUM_THREADS];
tr++, tcp++) { tp++, tcp++) {
tr->state = NIL_STATE_READY; tp->state = NIL_STATE_READY;
tr->timeout = 0; tp->timeout = 0;
#if NIL_CFG_USE_EVENTS
tp->epmask = 0;
#endif
/* Port dependent thread initialization.*/ /* Port dependent thread initialization.*/
PORT_SETUP_CONTEXT(tr, tcp->wap, tcp->size, tcp->funcp, tcp->arg); PORT_SETUP_CONTEXT(tp, tcp->wap, tcp->size, tcp->funcp, tcp->arg);
/* Initialization hook.*/ /* Initialization hook.*/
#if defined(NIL_CFG_THREAD_EXT_INIT_HOOK) #if defined(NIL_CFG_THREAD_EXT_INIT_HOOK)
NIL_CFG_THREAD_EXT_INIT_HOOK(tr); NIL_CFG_THREAD_EXT_INIT_HOOK(tp);
#endif #endif
} }
@ -136,65 +139,65 @@ void chSysHalt(const char *reason) {
void chSysTimerHandlerI(void) { void chSysTimerHandlerI(void) {
#if NIL_CFG_TIMEDELTA == 0 #if NIL_CFG_TIMEDELTA == 0
thread_reference_t tr = &nil.threads[0]; thread_t *tp = &nil.threads[0];
nil.systime++; nil.systime++;
do { do {
/* Is the thread in a wait state with timeout?.*/ /* Is the thread in a wait state with timeout?.*/
if (tr->timeout > 0) { if (tp->timeout > 0) {
chDbgAssert(!NIL_THD_IS_READY(tr), "is ready"); chDbgAssert(!NIL_THD_IS_READY(tp), "is ready");
/* Did the timer reach zero?*/ /* Did the timer reach zero?*/
if (--tr->timeout == 0) { if (--tp->timeout == 0) {
/* Timeout on semaphores requires a special handling because the /* Timeout on semaphores requires a special handling because the
semaphore counter must be incremented.*/ semaphore counter must be incremented.*/
if (NIL_THD_IS_WTSEM(tr)) if (NIL_THD_IS_WTSEM(tp))
tr->u1.semp->cnt++; tp->u1.semp->cnt++;
else if (NIL_THD_IS_SUSP(tr)) else if (NIL_THD_IS_SUSP(tp))
tr->u1.trp = NULL; tp->u1.trp = NULL;
chSchReadyI(tr, MSG_TIMEOUT); chSchReadyI(tp, MSG_TIMEOUT);
} }
} }
/* Lock released in order to give a preemption chance on those /* Lock released in order to give a preemption chance on those
architectures supporting IRQ preemption.*/ architectures supporting IRQ preemption.*/
chSysUnlockFromISR(); chSysUnlockFromISR();
tr++; tp++;
chSysLockFromISR(); chSysLockFromISR();
} while (tr < &nil.threads[NIL_CFG_NUM_THREADS]); } while (tp < &nil.threads[NIL_CFG_NUM_THREADS]);
#else #else
thread_reference_t tr = &nil.threads[0]; thread_t *tp = &nil.threads[0];
systime_t next = 0; systime_t next = 0;
chDbgAssert(nil.nexttime == port_timer_get_alarm(), "time mismatch"); chDbgAssert(nil.nexttime == port_timer_get_alarm(), "time mismatch");
do { do {
/* Is the thread in a wait state with timeout?.*/ /* Is the thread in a wait state with timeout?.*/
if (tr->timeout > 0) { if (tp->timeout > 0) {
chDbgAssert(!NIL_THD_IS_READY(tr), "is ready"); chDbgAssert(!NIL_THD_IS_READY(tp), "is ready");
chDbgAssert(tr->timeout >= nil.nexttime - nil.lasttime, "skipped one"); chDbgAssert(tp->timeout >= nil.nexttime - nil.lasttime, "skipped one");
tr->timeout -= nil.nexttime - nil.lasttime; tp->timeout -= nil.nexttime - nil.lasttime;
if (tr->timeout == 0) { if (tp->timeout == 0) {
/* Timeout on semaphores requires a special handling because the /* Timeout on semaphores requires a special handling because the
semaphore counter must be incremented.*/ semaphore counter must be incremented.*/
if (NIL_THD_IS_WTSEM(tr)) if (NIL_THD_IS_WTSEM(tp))
tr->u1.semp->cnt++; tp->u1.semp->cnt++;
else if (NIL_THD_IS_SUSP(tr)) else if (NIL_THD_IS_SUSP(tp))
tr->u1.trp = NULL; tp->u1.trp = NULL;
chSchReadyI(tr, MSG_TIMEOUT); chSchReadyI(tp, MSG_TIMEOUT);
} }
else { else {
if (tr->timeout <= next - 1) if (tp->timeout <= next - 1)
next = tr->timeout; next = tp->timeout;
} }
} }
/* Lock released in order to give a preemption chance on those /* Lock released in order to give a preemption chance on those
architectures supporting IRQ preemption.*/ architectures supporting IRQ preemption.*/
chSysUnlockFromISR(); chSysUnlockFromISR();
tr++; tp++;
chSysLockFromISR(); chSysLockFromISR();
} while (tr < &nil.threads[NIL_CFG_NUM_THREADS]); } while (tp < &nil.threads[NIL_CFG_NUM_THREADS]);
nil.lasttime = nil.nexttime; nil.lasttime = nil.nexttime;
if (next > 0) { if (next > 0) {
nil.nexttime += next; nil.nexttime += next;
@ -256,25 +259,25 @@ void chSysRestoreStatusX(syssts_t sts) {
/** /**
* @brief Makes the specified thread ready for execution. * @brief Makes the specified thread ready for execution.
* *
* @param[in] tr reference to the @p thread_t object * @param[in] tp pointer to the @p thread_t object
* @param[in] msg the wakeup message * @param[in] msg the wakeup message
* *
* @return The same reference passed as parameter. * @return The same reference passed as parameter.
*/ */
thread_reference_t chSchReadyI(thread_reference_t tr, msg_t msg) { thread_t *chSchReadyI(thread_t *tp, msg_t msg) {
chDbgAssert((tr >= nil.threads) && chDbgAssert((tp >= nil.threads) &&
(tr < &nil.threads[NIL_CFG_NUM_THREADS]), (tp < &nil.threads[NIL_CFG_NUM_THREADS]),
"pointer out of range"); "pointer out of range");
chDbgAssert(!NIL_THD_IS_READY(tr), "already ready"); chDbgAssert(!NIL_THD_IS_READY(tp), "already ready");
chDbgAssert(nil.next <= nil.current, "priority ordering"); chDbgAssert(nil.next <= nil.current, "priority ordering");
tr->u1.msg = msg; tp->u1.msg = msg;
tr->state = NIL_STATE_READY; tp->state = NIL_STATE_READY;
tr->timeout = 0; tp->timeout = 0;
if (tr < nil.next) if (tp < nil.next)
nil.next = tr; nil.next = tp;
return tr; return tp;
} }
/** /**
@ -285,15 +288,15 @@ thread_reference_t chSchReadyI(thread_reference_t tr, msg_t msg) {
void chSchRescheduleS(void) { void chSchRescheduleS(void) {
if (chSchIsRescRequiredI()) { if (chSchIsRescRequiredI()) {
thread_reference_t otr = nil.current; thread_t *otp = nil.current;
nil.current = nil.next; nil.current = nil.next;
#if defined(NIL_CFG_IDLE_LEAVE_HOOK) #if defined(NIL_CFG_IDLE_LEAVE_HOOK)
if (otr == &nil.threads[NIL_CFG_NUM_THREADS]) { if (otp == &nil.threads[NIL_CFG_NUM_THREADS]) {
NIL_CFG_IDLE_LEAVE_HOOK(); NIL_CFG_IDLE_LEAVE_HOOK();
} }
#endif #endif
port_switch(nil.next, otr); port_switch(nil.next, otp);
} }
} }
@ -315,13 +318,13 @@ void chSchRescheduleS(void) {
* @sclass * @sclass
*/ */
msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) {
thread_reference_t ntr, otr = nil.current; thread_t *ntp, *otp = nil.current;
chDbgAssert(otr != &nil.threads[NIL_CFG_NUM_THREADS], chDbgAssert(otp != &nil.threads[NIL_CFG_NUM_THREADS],
"idle cannot sleep"); "idle cannot sleep");
/* Storing the wait object for the current thread.*/ /* Storing the wait object for the current thread.*/
otr->state = newstate; otp->state = newstate;
#if NIL_CFG_TIMEDELTA > 0 #if NIL_CFG_TIMEDELTA > 0
if (timeout != TIME_INFINITE) { if (timeout != TIME_INFINITE) {
@ -347,33 +350,33 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) {
} }
/* Timeout settings.*/ /* Timeout settings.*/
otr->timeout = time - nil.lasttime; otp->timeout = time - nil.lasttime;
} }
#else #else
/* Timeout settings.*/ /* Timeout settings.*/
otr->timeout = timeout; otp->timeout = timeout;
#endif #endif
/* Scanning the whole threads array.*/ /* Scanning the whole threads array.*/
ntr = nil.threads; ntp = nil.threads;
while (true) { while (true) {
/* Is this thread ready to execute?*/ /* Is this thread ready to execute?*/
if (NIL_THD_IS_READY(ntr)) { if (NIL_THD_IS_READY(ntp)) {
nil.current = nil.next = ntr; nil.current = nil.next = ntp;
#if defined(NIL_CFG_IDLE_ENTER_HOOK) #if defined(NIL_CFG_IDLE_ENTER_HOOK)
if (ntr == &nil.threads[NIL_CFG_NUM_THREADS]) { if (ntp == &nil.threads[NIL_CFG_NUM_THREADS]) {
NIL_CFG_IDLE_ENTER_HOOK(); NIL_CFG_IDLE_ENTER_HOOK();
} }
#endif #endif
port_switch(ntr, otr); port_switch(ntp, otp);
return nil.current->u1.msg; return nil.current->u1.msg;
} }
/* Points to the next thread in lowering priority order.*/ /* Points to the next thread in lowering priority order.*/
ntr++; ntp++;
chDbgAssert(ntr <= &nil.threads[NIL_CFG_NUM_THREADS], chDbgAssert(ntp <= &nil.threads[NIL_CFG_NUM_THREADS],
"pointer out of range"); "pointer out of range");
} }
} }
@ -626,24 +629,24 @@ void chSemReset(semaphore_t *sp, cnt_t n) {
* @iclass * @iclass
*/ */
void chSemResetI(semaphore_t *sp, cnt_t n) { void chSemResetI(semaphore_t *sp, cnt_t n) {
thread_reference_t tr; thread_t *tp;
cnt_t cnt; cnt_t cnt;
cnt = sp->cnt; cnt = sp->cnt;
sp->cnt = n; sp->cnt = n;
tr = nil.threads; tp = nil.threads;
while (cnt < 0) { while (cnt < 0) {
/* Is this thread waiting on this semaphore?*/ /* Is this thread waiting on this semaphore?*/
if (tr->u1.semp == sp) { if (tp->u1.semp == sp) {
chDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting"); chDbgAssert(NIL_THD_IS_WTSEM(tp), "not waiting");
cnt++; cnt++;
chSchReadyI(tr, MSG_RESET); chSchReadyI(tp, MSG_RESET);
} }
tr++; tp++;
chDbgAssert(tr < &nil.threads[NIL_CFG_NUM_THREADS], chDbgAssert(tp < &nil.threads[NIL_CFG_NUM_THREADS],
"pointer out of range"); "pointer out of range");
} }
} }