18.2.5.1 Data-initialization Template

In order to clear or initialize all the data and RAM function sections, the linker creates a data-initialization template, which is loaded into an output section named .dinit and allocated space in program memory. The code in the C/C++ start-up module contained in libpic32c.a interprets this template, which indicates how the appropriate sections must be initialized.

The sections initialized by this template includes those holding intialized objects (such as the .data section) as well as sections containing ramfunc attributed functions, all of which must have values copied from the template in program to data memory where the objects and functions will be accessed at runtime. Other data sections holding unititialized objects (such as the .bss section) are cleared by the template before the main() function is called. The persistent data section (.pbss) is not considered by the runtime startup code. When the application’s main program takes control, all objects and RAM functions in data memory will have been initialized.

The data initialization template contains one record for each output section that needs initializing. Each record has one of several formats, represented by a format code within the record. The record formats specify how the data values are stored in the record itself and how they should be used to initialize the corresponding section. The --dinit-compression linker option (see 5.7.10.1 Dinit-compression Option) controls which of these records can be utilized by the template. The numerical format codes and the type of initialization they represent are as follows:
#0
Fill the RAM defined by the corresponding output section with zeros. No data bytes are stored in the record. Used by bss sections.
#1
Copy each byte of data from the record's array to the RAM associated with the output section. Used by data sections, and sections associated with ramfunc functions.
#2
Copy the same 16-bit value into the RAM associated with the output section multiples times. Used by data sections whose initial values are a repeating sequence.
#3
Copy the same 32-bit value into the RAM associated with the output section multiple times. Used by data sections whose initial values are a repeating sequence.
#4
Copy and decompress a simplified version of PackBits encoded data_record. Used by data sections, and sections associated with ramfunc functions which contain large numbers of consecutive zero bytes.

The data contained in each record type can be represented by the equivalent C structures that are presented below. The first element of the record is a pointer to the section in data memory. The second element is the section length or repeat count. The third element is the format code, which indicates the type of the record (listed above) and hence how the corresponding section should be initialized. The forth element is used for either alignment padding or an initial value. A fifth element, if present, is an array of data bytes.The template is terminated by two null instruction words.

/* For format values of 0 */
struct data_record_bss {
    uint32_t *dst;     /* destination address */
    uint32_t len;      /* length in bytes */
    uint16_t format;   /* format code */
    uint16_t padding;  /* padding for alignment */
};

/* For format values of 1 and 3 (also identical to format value 4) */
struct data_record_standard {
    uint32_t *dst;     /* destination address */
    uint32_t len;      /* length in bytes */
    uint16_t format;   /* format code */
    uint16_t padding;  /* padding for alignment or a 16-bit initialization value */
    uint32_t dat[0];   /* object-length data - holding initialization data */
};

/* For format values of 2 - objects are initialised with the same 16-bit value */
struct data_record_short_standard {
    uint32_t *dst;     /* destination address */
    uint32_t count;    /* count in bytes */
    uint16_t format;   /* format code */
    uint16_t dat       /* 16-bit repeated value data */
};

/* For format values of 4 - A simplified PackBits data compression is applied, where
each run of zeros is replaced by two 8-bit characters in the compressed array:
zero followed by the number of zeros in the original run. */
struct data_record_compressed {
    uint32_t *dst;               /* destination address */
    uint32_t count;              /* count in bytes */
    uint16_t format;             /* format code */
    uint16_t padding;            /* 16-bit repeated value data */
    uint32_t compressed_data[0]; /* compressed intialized data */
};