Microchip Technology SW006022-1N Data Sheet

Page of 338
MPLAB
®
 XC16 C Compiler User’s Guide
DS52071B-page 184
 2012 Microchip Technology Inc.
EXAMPLE 11-3: 
BIT FIELDS
A third cause for concern are bit fields. C allows memory to be allocated at the bit level, 
but does not define any bit operations. In the purest sense, any operation on a bit will 
be treated as an operation on the underlying type of the bit field and will usually require 
some operations to extract the field from bar and baz or to insert the field into foo. 
The important consideration to note is that (again depending upon instruction architec-
ture, optimization levels and memory settings) an interrupted routine that writes to any 
portion of the bit field where foo resides may be corruptible. This is particularly appar-
ent in the case where one of the operands is also the destination.
The dsPIC DSC instruction set can operate on 1 bit atomically. The compiler may select 
these instructions depending upon optimization level, memory settings and resource 
availability.
EXAMPLE 11-4: 
CACHED MEMORY VALUES IN REGISTERS
Finally, the compiler may choose to cache memory values in registers. These are often 
referred to as register variables and are particularly prone to interrupt corruption, even 
when an operation involving the variable is not being interrupted. Ensure that memory 
resources shared between an ISR and an interruptible function are designated as 
volatile
. This will inform the compiler that the memory location may be updated 
out-of-line from the serial code sequence. This will not protect against the effect of 
non-atomic operations, but is never-the-less important.
11.8.1.2
DEVELOPMENT SOLUTIONS
Here are some strategies to remove potential hazards:
• Design the software system such that the conflicting event cannot occur. Do not 
share memory between ISRs and other functions. Make ISRs as simple as 
possible and move the real work to main code.
• Use care when sharing memory and, if possible, avoid sharing bit fields which 
contain multiple bits.
• Protect non-atomic updates of shared memory from interrupts as you would 
protect critical sections of code. The following macro can be used for this purpose:
     #define INTERRUPT_PROTECT(x) {              \
        char saved_ipl;                          \
                                                 \
        SET_AND_SAVE_CPU_IPL(saved_ipl,7);       \
        x;                                       \
        RESTORE_CPU_IPL(saved_ipl); } (void) 0;
This macro disables interrupts by increasing the current priority level to 7, 
performing the desired statement and then restoring the previous priority level.