23.3.4.8 .vectors Section
Some PIC32 families feature variable offsets for vector spacing. This feature allows the
interrupt vector spacing to be configured according to application needs. A specific
interrupt vector offset can be set for each vector using its associated
OFFxxx
register. For details on the interrupt vector-table variable
offset feature, refer to the “PIC32 -Family Reference Manual” (DS61108) and also
the data sheet for your specific PIC32 MCU.
The application source code is responsible for creating a .vector_n
input section for each interrupt vector. The C/C++ compiler creates this section when
either the -vector(n)
or the at_vector(n)
attribute is
applied to the interrupt service routine. In assembly code, use the
.section
directive to create a new named section.
The device-specific linker script creates a single output section named
.vectors
that groups all of the individual
.vector_n
input sections from the project. The start of the
interrupt-vector table is mapped to the address (_ebase_address +
0x200
). The default value of the _ebase_address
symbol is also
provided in the linker script.
For each vector, the linker script also creates a symbol named
__vector_offset_n
, whose value is the offset of the vector address
from the _ebase_address
address.
PROVIDE(_ebase_address = 0x9D000000);
SECTIONS {
/* Interrupt vector table with vector offsets */
.vectors _ebase_address + 0x200 :
{
/* Symbol __vector_offset_n points to .vector_n if it exists,
* otherwise points to the default handler. The
* vector_offset_init.o module then provides a .data section
* containing values used to initialize the vector-offset SFRs
* in the crt0 startup code.
*/
__vector_offset_0 = (DEFINED(__vector_dispatch_0) ? (. - _ebase_address) : __vector_offset_default); KEEP(*(.vector_0))
__vector_offset_1 = (DEFINED(__vector_dispatch_1) ? (. - _ebase_address) : __vector_offset_default); KEEP(*(.vector_1))
__vector_offset_2 = (DEFINED(__vector_dispatch_2) ? (. - _ebase_address) : __vector_offset_default); KEEP(*(.vector_2))
/* ... */
__vector_offset_190 = (DEFINED(__vector_dispatch_190) ? (. - _ebase_address) : __vector_offset_default); KEEP(*(.vector_190))
}
}
The vector-offset initialization module
(vector_offset_init.o
) uses the __vector_offset_n
symbols defined in the default linker script. The value of each symbol is the offset of
the vector’s address from the ebase register’s address. The vector-offset initialization
module, uses the symbol value to create a .data
section using the
address of the corresponding OFFxxx
special function register. This
means that the standard linker-generated data-initialization template contains the
values used to initialize the OFFxxx
registers.
With these .data
sections added to the project and the
linker-generated data-initialization template, the standard runtime startup code
initializes the OFFxxx
special function registers as regular
initialized data. No special code is required in the startup code to initialize the
OFFxxx
registers.