Program Space Visibility (PSV) maps selected blocks of flash program memory into the upper 32 KB of data memory space to provide quick access to literal constants and flash based data tables.
Two registers are used to enable PSV:
- CORCON - the Core Control Register
- PSVPAG - the PSV Page Register
When the PSV enable bit in CORCON (CORCON<2>) is set, the 32k Byte block of program memory specified by the value of PSVPAG will appear at data memory addresses 0x8000- 0xFFFF. (Only the lower 16-bit of each address word will appear in the PSV space).
MPLAB® XC16 C compiler considers the PSVPAG register a compiler managed resource. While it is possible for the application to manipulate the PSV registers, relying on the compiler to manage PSV access is the recommended approach.
MPLAB® XC16's default memory model, mconst-in-code, places all constants in program memory. When const is used to create a constant, the compiler will place the data in program memory and ensure it is formatted so it can be read from PSV. Constants can also be created and placed into the PSV window with the (space(psv)) attribute. (see the following example)
When constants are placed into PSV the compiler ensures that any application program accessing the constant will use the re-mapped PSV address.
The following are examples of creating constants with const and the (spave(psv)) attribute.
The preceding code will cause the constants example1, example2, and example3 to be placed into program memory. In this application the linker placed the constants at addresses 0x029E, 0x02A2, and 0x02A4. The 32-bit long constant example1 was placed in the lower 16-bits of adjacent program memory words so that it can be correctly read through PSV.
The following disassembly code demonstrates how the data elements located in program memory locations 0x029E, 0x02A2, and 0x02A4 (example1, example2, and example3) are accessed as if they were in data memory addresses 0x829E, 0x82A2, and 0x82A4.
Interrupt Service Routine Considerations.
PSV data accesses, especially those using using pointers, can take several instructions to complete. Were an interrupt to occur during a PSV access the value of PSVPAG could be changed by the ISR. This could result in the main program accessing the wrong constant value. To prevent such an occurrence the compiler automatically inserts code to save and restore PSVPAG into each ISR.
While it is prudent to preserve the contents of PSVPAG, in some cases saving PSV is NOT needed. For applications with only one managed PSV page, or for ISRs which do not access PSVPAG, the saving and restoring of PSVPAG offers no benefits. Applications needing to minimize interrupt latency may wish to eliminate the preservation of PSVPAG.
MPLAB® XC16 can be told to omit the PSV saving code with the interrupt attribute of no_auto_psv. ISRs defined with the no_auto_psv attribute will not have the code which saves and restores PSVPAG. If an ISR is defined the attribute auto_psv, or defined without an attribute, the PSVPAG preservation code will be included with the ISR.