
QDK™
M16C/Neutrino-NC30
www.state-machine.com/m16c
3.4 QP Idle Loop Customization in QF_onIdle()
The cooperative “vanilla” kernel can very easily detect the situation when no events are available,
in which case
QF_run()
calls the
QF_onIdle()
callback. You can use
QF_onIdle()
to suspended the
CPU to save power, if your CPU supports such a power-saving mode. Please note that
QF_onIdle()
is called repetitively from the event loop whenever the event loop has no more events to process,
in which case only an interrupt can provide new events. The
QF_onIdle()
callback is called with in-
terrupts locked, because the determination of the idle condition might change by any interrupt
posting an event.
M16C microcontrollers support several power-saving levels (consult the specific data sheet for de-
tails). The following piece of code shows the
QF_onIdle()
callback that puts M16C into the idle
power-saving mode. Please note that M16C architecture allows for very atomic setting the low-
power mode and enabling interrupts at the same time (see the article “Using Low-Power Modes in
Foreground/Background Systems” [Samek 07a]).
(1) void QF_onIdle(void) {
#ifdef Q_SPY
/* perform QS trace output via M16C UART... */
. . .
(2) #elif (defined NDEBUG) /* low-power mode interferes with debugging */
(3) /* stop all peripheral clocks that you can in your applicaiton ... */
(4) _asm("FSET I"); /* NOTE: the following WAIT instruction will */
(5) _asm("WAIT"); /* execute before entering any pending interrupt */
#else
(6) QF_INT_UNLOCK(); /* just unlock interrupts */
#endif
}
Listing 5
QF_onIdle()
for the non-preemptive (“vanilla”) QP port to M16C.
(1) The
QF_onIdle()
callback is always called with interrupts locked to prevent any race condition
between posting events from ISRs and transitioning to the sleep mode.
(2) The low-power mode is entered only in the Release (not DEBUG) configuration.
(3) The clock management
register
s are setup the desired sleep mode. Please note that the sleep
mode is not active until the SLEEP command.
(4) The interrupts are unlocked with the
FSET I
instruction.
(5) The sleep mode is activated with the
WAIT
instruction.
NOTE: As described in “M16C/60, M16C/20 Series Software Manual”, Section 5.2.1 “Interrupt
Enable Flag”, the instruction immediately following the
FSET I
instruction, will be executed be-
fore any pending interrupt. This guarantees atomic transition to the WAIT mode.
CAUTION: The instruction pair (
FSET I, WAIT
) should never be separated by any other instruc-
tion.
(6) In the DEBUG configuration the interrupts are simply unlocked.
NOTE: Every path through
QF_onIdle()
callback function must ultimately unlock interrupts.
Copyright © Quantum Leaps, LLC. All Rights Reserved.
13 of 25
Comentarios a estos manuales