30.12.2014 Views

QDK PIC24/dsPIC-C30 - Quantum Leaps

QDK PIC24/dsPIC-C30 - Quantum Leaps

QDK PIC24/dsPIC-C30 - Quantum Leaps

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!