QDK PIC24/dsPIC-C30 - Quantum Leaps
QDK PIC24/dsPIC-C30 - Quantum Leaps
QDK PIC24/dsPIC-C30 - Quantum Leaps
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>QDK</strong><br />
<strong>PIC24</strong>/<strong>dsPIC</strong>-<strong>C30</strong><br />
www.state-machine.com/pic<br />
The solution used in this QK port is to use the __preprologue__ attribute of the compiler-generated ISR<br />
to check the stacked SR before the compiler pushes any registers to the stack and alters the stack<br />
pointer. The IPL extracted from the stacked SR is then stored in the global variable QK_intNest_, which<br />
in this case is not used as the interrupt nesting counter, but rather as a bitmask (a set) of preempted IPL<br />
levels. More precisely, the QK-specific ISR entry code added before any compiler-generated code checks<br />
the stacked IPL level in SR and sets the bit corresponding to the preempted IPL in the<br />
QK_intNest_ bitmask, as illustrated in Figure 7. In the QK-specific ISR exit code, the current IPL is<br />
extracted from the SR and the bit corresponding to the current IPL is cleared in the QK_intNest_<br />
bitmask.<br />
Figure 7: Storing the preempted IPLs in the QK_intNest_ bitmask<br />
Bit number<br />
7<br />
6<br />
5<br />
4<br />
3<br />
2<br />
1<br />
0<br />
0<br />
0<br />
1<br />
0<br />
0<br />
0<br />
1<br />
1<br />
QK_intNest_<br />
Unused level (IPL = 7)<br />
Preempted IPL = 5<br />
Preempted IPL = 1<br />
Preempted IPL = 0<br />
The QK-specific interrupt entry and exit sequence defined in the header file qk_port.h shown in Listing 7<br />
demonstrates one possible solution to this problem. The QK port header file for the <strong>PIC24</strong>/<strong>dsPIC</strong> port is<br />
located in \ports\pic24-dspic\qk\mplab-c30\qk_port.h. The upcoming Section “ISRs with the<br />
Preemptive QK Kernel” explains how to use the macros QK_ISR_ENTRY() / QK_ISR_EXIT() and how<br />
these macros work at the assembly level.<br />
Listing 7: qk_port.h header file for the preemptive QP port with QK<br />
/* QK interrupt entry and exit */<br />
(1) #define QK_ISR(psv_) \<br />
(2) void __attribute__((__interrupt__(__preprologue__( \<br />
"push RCOUNT \n" \<br />
"push.d w0 \n" \<br />
"mov.w [w15-8],w0 \n" \<br />
"lsr.w w0,#13,w1 \n" \<br />
"mov.w #1,w0 \n" \<br />
"sl w0,w1,w0 \n" \<br />
"ior.b _QK_intNest_\n" \<br />
"bra .+6 ")) \<br />
, psv_))<br />
(3) #define QK_ISR_EXIT() do { \<br />
register uint16_t this_sr; \<br />
__asm__ volatile ( \<br />
"mov.w SR,%0 \n" \<br />
"lsr %0,#5,w0 \n" \<br />
Copyright © <strong>Quantum</strong> <strong>Leaps</strong>, LLC. All Rights Reserved.<br />
18 of 35