QDK PIC24/dsPIC-C30 - Quantum Leaps
QDK PIC24/dsPIC-C30 - Quantum Leaps
QDK PIC24/dsPIC-C30 - Quantum Leaps
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>QDK</strong><br />
<strong>PIC24</strong>/<strong>dsPIC</strong>-<strong>C30</strong><br />
www.state-machine.com/pic<br />
4 Preemptive Configuration with QK<br />
The QP port to <strong>PIC24</strong>/<strong>dsPIC</strong> with the preemptive kernel (QK) is similar to the “vanilla” port. In particular,<br />
the interrupt locking/unlocking policy is the same, and the BSP is almost identical, except for some extra<br />
considerations for the ISRs.<br />
4.1 QK-specific ISR Entry and Exit Macros (file qk_port.h)<br />
The preemptive QP port to <strong>PIC24</strong>/<strong>dsPIC</strong> also allows writing ISRs in C, so no explicit assembly<br />
programming is necessary. However, the preemptive QK kernel requires (as all preemptive kernels do)<br />
notifying the kernel about entering and exiting the ISR, so that the kernel can avoid context switching<br />
inside ISRs, but knows when to perform asynchronous preemptions when the last nested ISR returns to<br />
the task level.<br />
While working with the compiler-generated ISRs, the biggest problem for a preemptive kernel is to<br />
reliably detect that a given ISR is not nesting on top of another ISR, so that only the last interrupt<br />
returning to the task level performs context switch, if necessary.<br />
NOTE: Unlike most other processors, <strong>PIC24</strong>/<strong>dsPIC</strong> does not disable interrupts upon the entry to the<br />
interrupt service routine. <strong>PIC24</strong>/<strong>dsPIC</strong> merely raises the current IPL to the level of currently serviced<br />
interrupt. This means that the currently serviced interrupt can be preempted by a higher-level<br />
interrupt even at the very first instruction. Consequently, incrementing the interrupt nesting counter<br />
(QK_intNest_) is not a reliable way of accounting for interrupt nesting, because it can miss an<br />
interrupt nesting level no matter how early in the ISR it is performed.<br />
For <strong>PIC24</strong>/<strong>dsPIC</strong>, a reliable way of detecting nesting of interrupts is to check the preempted status<br />
register SR, which is saved on the interrupt stack as shown in Figure 6. Only if the preempted IPL<br />
(bits SR) is non-zero, the current interrupt preempts the task level and performing a context switch<br />
is allowed.<br />
Figure 6: Interrupt stack frame for <strong>PIC24</strong>/<strong>dsPIC</strong><br />
Low memory<br />
High memory<br />
15<br />
PC<br />
SR<br />
PC<br />
Register saved by the <strong>C30</strong> compiler<br />
Register saved by the <strong>C30</strong> compiler<br />
…<br />
Register saved by the <strong>C30</strong> compiler<br />
0<br />
IPL3 status bit<br />
(CORCON).<br />
Stack pointer<br />
(w15)<br />
While checking the stacked SR is quite easy in assembly, it is much trickier for the compiler-generated<br />
ISRs. The compiler generates different stack frames depending on the actually clobbered registers in the<br />
body of the ISR as well as the attributes of the ISR and even the optimization level used to compile the<br />
code. Consequently, it is difficult to know the offset of the stacked SR from the current stack pointer w15<br />
that is accessible inside the ISR, (again see Figure 6).<br />
Copyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.<br />
17 of 35