I traced the hangup to the situation where the serial buffer is full, and the OS is going to do a thread switch to Sleep with timeout INFINITE.
The exception occurs (I think) because the current execution pointer ends up in unused memory.
Code: Select all
msg_t oqPutTimeout(output_queue_t *oqp, uint8_t b, systime_t time) {
osalSysLock();
while (oqIsFullI(oqp)) {
msg_t msg;
if ((msg = osalThreadEnqueueTimeoutS(&oqp->q_waiting, time)) < Q_OK) {
osalSysUnlock();
return msg;
}
}
osalThreadEnqueueTimeoutS does not return.
Tracing deeper I end up here:
Code: Select all
void chSchGoSleepS(tstate_t newstate) {
thread_t *otp;
chDbgCheckClassS();
(otp = currp)->p_state = newstate;
#if CH_CFG_TIME_QUANTUM > 0
/* The thread is renouncing its remaining time slices so it will have a new
time quantum when it will wakeup.*/
otp->p_preempt = CH_CFG_TIME_QUANTUM;
#endif
setcurrp(queue_fifo_remove(&ch.rlist.r_queue));
#if defined(CH_CFG_IDLE_ENTER_HOOK)
if (currp->p_prio == IDLEPRIO) {
CH_CFG_IDLE_ENTER_HOOK();
}
#endif
currp->p_state = CH_STATE_CURRENT;
chSysSwitch(currp, otp);
}
Where the last line "chSysSwitch(currp, otp);" cause the hangup. Tracing this further I do not enter this function, but end up in some inline ASM code.
SevenW