A lot of work has been done in MPLAB C30 rev 3.02 to perfect the management of interrupts and it affects the examples presented in the book in a number of ways.
A) Let’s start with the simplest change, the processor interrupt level (represented by 3 bits in the status register) and defined as a bit-field in the “p24fj128ga010.h” include file, has changed name, it is now spelled “_IPL” rather than just “_IP”. I am not sure where, but they tell me it was causing a possible name conflict. The fix is quick and does not require further explanation.
B) More worrisome, but not as critical as you might think, is a new warning that is generated now for every new interrupt service routine defined in the code examples:
Interrupts.c: xx: warning: PSV model not specified for ‘_xxInterrupt’;
This is due to some changes implemented in the compiler to facilitate the implementation of the CodeGuard(tm) technology. Nothing special, really, all that happens is that the compiler does NOT assume that the “PSV window” (unfortunately this is a feature we learn about only in the next Chapter 6) is under his control. It actually assumes the opposite now (that our application is managing it ), and therefore it takes preventive actions to make sure it is not corrupted during the ISR execution (saving the PSV value on the stack before the ISR and restoring its value after it). And it tells us about it:
assuming ‘auto_psv’ this may affect latency
as it warns us that this “precautionary” push and pop require a few extra instructions, that affect the overall interrupt latency.
The fact is that none of the examples in the book makes any attempt at modifying the PSV and the default value (assigned by the compiler) is used throughout.
Unfortunately there is no global switch (compiler option) that can change the compiler assumptions and we have to either accept the (redundant) warning and the increased latency (just a couple of cycles) or remember to add an attribute to each and every interrupt routine we define:
Did I ever mention before how I don’t care for the quadruple underscore and double parenthesis required by all GNU compilers to extend the C syntax?
void _ISR __attribute__((no_auto_psv)) _T1Interrupt( void)
A less distracting option would be to define a new macro:
#define _NOPSV __attribute__((no_auto_psv))
and use it as in the following example:
void _ISR _NOPSV _T1Interrupt( void)
We could be tempted to modify directly the definition of the _ISR macro to include the additional no_auto_psv attribute. But the _ISR macro is defined inside the device “p24fj128ga010.h” include file, and it is not considered a safe practice to modify standard include files, actually that is a VERY bad idea…
For now, since this is the first chapter were we learn to declare and use interrupt service routines, I will propose we use the _NOPSV macro explicitly.
Here are the source codes used alternatively in the interrupt.mcp project: