10.5.9. Configuring Error Correcting Code (ECC) with the Linker

Error Correcting Codes (ECC) can be generated and placed in separate sections through the linker command file. ECC uses extra bits to allow errors to be detected and/or corrected by a device. To enable ECC generation, you must include --ecc=on as a linker option on the command line. By default ECC generation is off, even if the ECC directive and ECC specifiers are used in the linker command file. This allows you to fully configure ECC in the linker command file while still being able to quickly turn the code generation on and off via the command line.

The ECC support provided by the linker is compatible with the ECC support in TI Flash memory on various TI devices. TI Flash memory uses a modified Hamming(72,64) code, which uses 8 parity bits for every 64 bits. Check the documentation for your Flash memory to see if ECC is supported. (ECC for read-write memory is handled completely in hardware at run time.)

You can control the details of ECC generation using the ECC specifier in the memory map (Using the ECC Specifier in the Memory Map) and the ECC directive (Using the ECC Directive).

See Error Correcting Code Testing (--ecc Options) for command-line options that introduce bit errors into code that has a corresponding ECC section or into the ECC parity bits themselves. Use these options to test ECC error handling code.

ECC can be generated during linking. The ECC data is included in the resulting object file, alongside code and data, as a data section located at the appropriate address. No extra ECC generation step is required after compilation, and the ECC can be uploaded to the device along with everything else.

10.5.9.1. Using the ECC Specifier in the Memory Map

To generate ECC, add a separate memory range to your memory map to hold ECC data and to indicate which memory range contains the Flash data that corresponds to this ECC data. If you have multiple memory ranges for Flash data, you should add a separate ECC memory range for each Flash data range.

The definition of an ECC memory range can also provide parameters for how to generate the ECC data.

The memory map for a device supporting Flash ECC may look something like this:

MEMORY {
    VECTORS  : origin=0x00000000 length=0x000020
    FLASH0   : origin=0x00000020 length=0x17FFE0
    FLASH1   : origin=0x00180000 length=0x180000
    STACKS   : origin=0x08000000 length=0x000500
    RAM      : origin=0x08000500 length=0x03FB00
    ECC_VEC  : origin=0xf0400000 length=0x000004 ECC={ input_range=VECTORS }
    ECC_FLA0 : origin=0xf0400004 length=0x02FFFC ECC={ input_range=FLASH0  }
    ECC_FLA1 : origin=0xf0430000 length=0x030000 ECC={ input_range=FLASH1  }
}

The specification syntax for ECC memory ranges is as follows:

MEMORY {
    <memory specifier1> : <memory attributes> [ vfill=<fill value> ]
    <memory specifier2> : <memory attributes> ECC = {
        input_range = <memory specifier1>
        [ algorithm   = <algorithm name> ]
        [ fill        = [ true, false ]  ]
    }
}

The “ECC” specifier attached to the ECC memory ranges indicates the data memory range that the ECC range covers. The ECC specifier supports the following parameters:

input_range = <range>

The data memory range covered by this ECC data range. Required.

algorithm = <ECC alg name>

The name of an ECC algorithm defined later in the command file using the ECC directive. Optional if only one algorithm is defined. (See Using the ECC Directive).

fill = true | false

Whether to generate ECC data for holes in the initialized data of the input range. The default is “true”. Using fill=false produces behavior similar to the nowECC tool. The input range can be filled normally or using a virtual fill (see Using the VFILL Specifier in the Memory Map).

10.5.9.2. Using the ECC Directive

In addition to specifying ECC memory ranges in the memory map, the linker command file must specify parameters for the algorithm that generates ECC data. You might need multiple ECC algorithm specifications if you have multiple Flash devices.

Each TI device supporting Flash ECC has exactly one set of valid values for these parameters. The linker command files provided with Code Composer Studio include the ECC parameters necessary for ECC support on the Flash memory accessible by the device. Documentation is provided here for completeness.

You specify algorithm parameters with the top-level ECC directive in the linker command file. The specification syntax is as follows:

ECC {
   <algorithm name> : parity_mask  = <8-bit integer>
                      mirroring    = [ F021, F035 ]
                      address_mask = <32-bit mask>
}

For example:

MEMORY {
    FLASH0 : origin=0x00000020 length=0x17FFE0
    ECC_FLA0 : origin=0xf0400004 length=0x02FFFC ECC={ input_range=FLASH0 algorithm=F021 }
}

ECC { F021 : parity_mask = 0xfc
             mirroring = F021 }

This ECC directive accepts the following attributes:

algorithm_name

Specify the name you would like to use for referencing the algorithm.

address_mask = <32-bit mask>

This mask determines which bits of the address of each 64-bit piece of memory are used in the calculation of the ECC byte for that memory. Default is 0xffffffff, so that all bits of the address are used. (Note that the ECC algorithm itself ignores the lowest bits, which are always zero for a correctly-aligned input block.)

parity_mask = <8-bit mask>

This mask determines which ECC bits encode even parity and which bits encode odd parity. Default is 0, meaning that all bits encode even parity.

mirroring = F021 | F035

This setting determines the order of the ECC bytes and their duplication pattern for redundancy. Default is F021.

10.5.9.3. Using the VFILL Specifier in the Memory Map

Normally, specifying a fill value for a MEMORY range creates initialized data sections to cover any previously uninitialized areas of memory. To generate ECC data for an entire memory range, the linker either needs to have initialized data in the entire range, or needs to know what value uninitialized memory areas will have at run time.

In cases where you want to generate ECC for an entire memory range, but do not want to initialize the entire range by specifying a fill value, you can use the “vfill” specifier instead of a “fill” specifier to virtually fill the range:

MEMORY {
    FLASH : origin=0x0000  length=0x4000  vfill=0xffffffff
}

The vfill specifier is functionally equivalent to omitting a fill specifier, except that it allows ECC data to be generated for areas of the input memory range that remain uninitialized. This has the benefit of reducing the size of the resulting object file.

The vfill specifier has no effect other than in ECC data generation. It cannot be specified along with a fill specifier, since that would introduce ambiguity.

If fill is specified in the ECC specifier, but vfill is not specified, vfill defaults to 0xff.