Here is my universal wake function which works both in I and not-I context, also works regardless if we are in locked context or not:
Code: Select all
// ChibiOS does not offer this function so that's a copy-paste of 'chSemSignal' without locking
void chSemSignalS(semaphore_t *sp) {
chDbgCheck(sp != NULL);
chDbgAssert(((sp->cnt >= (cnt_t)0) && queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && queue_notempty(&sp->queue)),
"inconsistent semaphore");
if (++sp->cnt <= (cnt_t)0) {
chSchWakeupS(queue_fifo_remove(&sp->queue), MSG_OK);
}
}
/**
* @details Wake up driver. Will cause output register update
*/
static int tle8888_wake_driver(struct tle8888_priv *chip)
{
int wasLocked = lockAnyContext();
if (isIsrContext()) {
// this is for normal runtime
chSemSignalI(&tle8888_wake);
} else {
// this is for start-up to not hang up
chSemSignalS(&tle8888_wake);
}
if (!wasLocked) {
unlockAnyContext();
}
return 0;
}