A problem of chSchGoSleepS()
Posted: Tue Jan 07, 2014 6:57 am
Hi,
I'm using STM32F4 Discovery, ChibiOS 2.6.1, all compile-time debugging options are enabled. An external interrupt is used to notify some data is ready. I have one thread waiting, and use the interrupt ISR to wakeup the thread. I use EXT driver for the external interrupt. Following is the code:
Here is my problem. Once waiter_thread call into chSchGoSleepS(), it never come back. And in debugger if I set breakpoint in ext_callback(), it never get triggered. It look as if the external interrupt was always disabled after calling chSchGoSleepS().
However, if I replace chSchGoSleepS() with chSchGoSleepTimeoutS(), external interrupt is working. But the waiter_thread always wakeup by time-out not by ISR. And debugger shows ext_callback() never has chance to call chSchReadyI() (because waiter == NULL all the time). Again it looks like the interrupt was disabled before the chSchGoSleepTimeoutS() returns.
I'm wondering what went wrong? I wrote this code according to how SPI implementation in ChibiOS. What am I missing? Thanks a lot!
I'm using STM32F4 Discovery, ChibiOS 2.6.1, all compile-time debugging options are enabled. An external interrupt is used to notify some data is ready. I have one thread waiting, and use the interrupt ISR to wakeup the thread. I use EXT driver for the external interrupt. Following is the code:
Code: Select all
static int pending = 0;
static Thread *waiter = NULL;
static void ext_callback(EXTDriver *extp, expchannel_t channel)
{
chSysLockFromIsr();
pending++;
if (waiter != NULL) {
Thread *th = waiter;
th->p_u.rdymsg = RDY_OK;
waiter = NULL;
chSchReadyI(th);
}
chSysUnlockFromIsr();
}
static msg_t waiter_thread(void *p)
{
while (1) {
chSysLock();
if (pending == 0) {
waiter = chThdSelf();
chSchGoSleepS(THD_STATE_SUSPENDED);
}
pending = 0;
chSysUnlock();
fetch_data();
}
}
Here is my problem. Once waiter_thread call into chSchGoSleepS(), it never come back. And in debugger if I set breakpoint in ext_callback(), it never get triggered. It look as if the external interrupt was always disabled after calling chSchGoSleepS().
However, if I replace chSchGoSleepS() with chSchGoSleepTimeoutS(), external interrupt is working. But the waiter_thread always wakeup by time-out not by ISR. And debugger shows ext_callback() never has chance to call chSchReadyI() (because waiter == NULL all the time). Again it looks like the interrupt was disabled before the chSchGoSleepTimeoutS() returns.
I'm wondering what went wrong? I wrote this code according to how SPI implementation in ChibiOS. What am I missing? Thanks a lot!