This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linker Generated ECC differences to nowECC outupt

Other Parts Discussed in Thread: NOWECC, TMS570LS3137, RM48L952

I am new to using ti microcontroller and finding my feet... maybe someone in forum can point me in the right direction

Objective is to generate ECC and flash to TMS570LS3137 MCU - I'm using USB Dev Kit for target hardware, and I have not tried flashing ECC to hardware yet, but I found some differences between linker and nowECC generated ECC.

Used Linker Generated ECC (Code Composer Studio 5.5) to produce binary with following amendments to linker command file:

MEMORY
{
    FLASH_VECTORS        (RX) : origin=0x00000000 length=0x00000020
    FLASH_APP            (RX) : origin=0x00000020 length=0x002FFFE0
    EEPROM_SEC1          (R)  : origin=0xF0200000 length=0x00004000
    EEPROM_SEC2          (R)  : origin=0xF0204000 length=0x00004000
    EEPROM_SEC3          (R)  : origin=0xF0208000 length=0x00004000
    EEPROM_SEC4          (R)  : origin=0xF020C000 length=0x00004000
    ECC_VECTORS          (R)  : origin=0xF0400000 length=0x00000004 ECC={ input_range=FLASH_VECTORS, fill=false }
    ECC_APP              (R)  : origin=0xF0400004 length=0x0005FFFC ECC={ input_range=FLASH_APP, fill=false }
    .
    .

and update to sections:

SECTIONS
{
    .
    .
    .ecc0    : {} > ECC_VECTORS
    .ecc1    : {} > ECC_APP
}

There is some meta data that is appended to binary after build, and this meta data is located within FLASH VECTORS region so I was concerned that some ECC values would now be invalid. 

I did notice in the MAP file that the location for the meta data was identified as UNINITIALIZED, and read somewhere that ECC would not be generated for uninitialised memory locations. This gave me hope that I could use the linker method but thought I would cross-check by generating same ECC using nowECC (v2.22)

I have been unable to generate the same ECC data using the same ELF out file, whatever options I select, and I've re-read user guide several times. I had assumed the nowECC would generate data to flash at 0xF0400000 and this would be same as binary output from the linker commands, but I believe I must be mistaken.

The processors.wiki.ti.com/.../Linker_Generated_ECC mentions to specify fill=false to get same output as nowECC.

I have also looked at SPNA126–February 2011 ECC Handling in TMSx70-Based Microcontrollers

Q1) can output from linker generated ECC and nowECC be compared and be expected to be same?

Q2) if Q1 suggests can compare, what nowECC options would I need to choose to generate same output?

Any tips, or pointers to more information that can help me bottom out this ECC generation would be most welcome.

 

  • Andy,

    It looks like you're missing the vfill directives on your actual flash areas of the memory map.
    These need to be filled.

    You got to the right place w. the wiki article you reference - and you should be able to use
    the MEMORY directive that is listed under RM48L952 directly on the TMS570LS3137.

    i.e.

    MEMORY
    {
    /* Flash Memory */
    /* Bank 0 */
    VECTORS (X) : origin=0x00000000 length=0x00000020 fill=0xffffffff
    FLASH0 (RX) : origin=(end(VECTORS)) length=(0x00180000 - size(VECTORS)) vfill=0xffffffff
    /* Bank 1 */
    FLASH1 (RX) : origin=0x00180000 length=0x00180000 vfill=0xffffffff
    /* Bank 7 (FEE) */
    FLASH7 (R) : origin=0xF0200000 length=0x00010000 vfill=0xffffffff
    /* Bank 0 ECC */
    ECC_VEC (R) : origin=(0xf0400000 + (start(VECTORS) >> 3)) length=(size(VECTORS) >> 3) ECC={algorithm=algoR4F021, input_range=VECTORS}
    ECC_FLA0 (R) : origin=(0xf0400000 + (start(FLASH0) >> 3)) length=(size(FLASH0) >> 3) ECC={algorithm=algoR4F021, input_range=FLASH0 }
    /* Bank 1 ECC */
    ECC_FLA1 (R) : origin=(0xf0400000 + (start(FLASH1) >> 3)) length=(size(FLASH1) >> 3) ECC={algorithm=algoR4F021, input_range=FLASH1 }
    /* Bank 7 ECC */
    ECC_FLA7 (R) : origin=0xF0100000 length=(size(FLASH7) >> 3) ECC={algorithm=algoR4F021, input_range=FLASH7 }
    /* embedded SRAM */
    STACKS (RW) : origin=0x08000000 length=0x00001500
    RAM (RW) : origin=0x08001500 length=0x0003EB00
    }
  • Hi Andy,

    I think Anthony is right, you have to specify a fill (or vfill) for the complete Flash Memory to get the same output between the Linker and nowECC as the way they handle holes in the memory are different. I think the linker assumes a 0 fill if not specified and nowECC uses all ones to fill holes. To get the same output between the two you have to ensure that there are no holes and that both tools use the same data range to generate the ECC data. The easiest way to achieve this is to use a fill value for the complete flash memory, with this both conditions are meet. Please note, that binary output should be the same, but the ELF (.out) file will most likely be not the equal as it's then generated by two different tools.

    Best Regards,
    Christian
  • Anthony,

    OK I adapted to names of our sections for main flash (bank 01 & 1 dealt with together)

    MEMORY
    {
        FLASH_VECTORS        (RX) : origin=0x00000000 length=0x00000020 fill=0xFFFFFFFF
        FLASH_APP            (RX) : origin=(end(FLASH_VECTORS)) length=(0x00300000 - size(FLASH_VECTORS)) vfill=0xffffffff
        EEPROM_SEC1          (R)  : origin=0xF0200000 length=0x00004000
        EEPROM_SEC2          (R)  : origin=0xF0204000 length=0x00004000
        EEPROM_SEC3          (R)  : origin=0xF0208000 length=0x00004000
        EEPROM_SEC4          (R)  : origin=0xF020C000 length=0x00004000
        ECC_VECTORS          (R)  : origin=(0xf0400000 + (start(FLASH_VECTORS) >> 3)) length=(size(FLASH_VECTORS) >> 3) ECC={algorithm=algoR4F021, input_range=FLASH_VECTORS, fill=false}
        ECC_APP              (R)  : origin=(0xf0400000 + (start(FLASH_APP) >> 3)) length=(size(FLASH_APP) >> 3) ECC={algorithm=algoR4F021, input_range=FLASH_APP, fill=false }

    This produces ECC of 0x60D0 bytes (24784). Note: Omitting fill=false produces ECC the full 0x60000 long

    Using nowECC with the command line:

    nowECC -i C:\ADCM\CCWorkspace\SW111770\Build\Release\sw111770.out -f021 16M_NOADD -r4 -d

    I get no errors,

    This is nowECC Version 2.22
    Mapping: F021-16MB [ECC Without AddressBits]

    Ignoring Data located from 0xf0400000 to 0xf04060cf for ECC calculation
    ECC calculation from 0x00000000 to 0x0003592F
    *** Writing only ECC section to file -> C:\ADCM\CCWorkspace\SW111770\Build\Release\sw111770_ECC.out
    No Errors

    The output file it produces is longer and on further inspection is an ELF file rather than the binary to flash to MCU at 0xF0400000, so I'll need to use ARM to convert to binary before I compare... I'll follow this up on Monday when back in the office and report findings successful or otherwise.

    Andy

  • Thanks Christian,
    Yes I'm now aware that my presumption that nowECC was generating the binary rather than ELF was incorrect. Will generate binary from ELF and compare first thing next week, and report back.
    Also - I might be able to set fill value to 0x00 using nowECC and -f option (or would this generate all 0x60000 bytes of ECC from full 0x300000 flash?) I can experiment next week.
    Andy
  • Andy,

    One important thing to note is that the ECC for the flash memory also accounts for the address. This allows a double-bit error to be generated if there is any error in the address put out by the CPU (or fault on address lines between CPU and flash interface module). You need to change the "16M_NOADD" to "16M_ADD".

    Regards,
    Sunil
  • Hi Sunil,

    OK... but if I wanted to do this in linker generated ECC, where would I define this? or does it default to this?

    Don't see option in documentation for linker generated ECC

    Currently, in addition to MEMORY described earlier in this thread, there is also the algorithm

    ECC
    {
        algoR4F021 : address_mask = 0x003ffff8 /* Address Bits 21:3 */
                     hamming_mask = R4   /* Use R4 build in Mask */
                     parity_mask  = 0x0c /* Set which ECC bits are Even and Odd parity */
                     mirroring    = F021 /* RM4x are build in F021 */
    }

     Andy

  • Hi Andy,

    I think Sunil meant that you have to set this in NowECC rather than in the LCF.
    In the LCF this is set with address_mask = 0x003ffff8 /* Address Bits 21:3 */

    Best Regards,
    Christian
  • Thanks Christian. Yes, I meant that the option for nowECC needs to be changed to include "-f021 16M_ADD" instead of the "-f021 16M_NOADD".
  • OK,

    I have found I can generate ECC binary using nowECC or the linker generated ECC method. The additional binary ECC data (0x60D0 bytes) produced by the linker generated ECC method is identical to the first 0x60D0 bytes generated from nowECC method. However there are an additional 2646 (0xA56) bytes of binary data produced from the nowECC generated out file.

    Is there an explanation for what these additional bytes are?

            ------------------------------------------------------

    The following text describes what I did to produce the two binary files:

    I build the application producing ELF out file, and use that to generate binary which is 0x00035930 bytes long.

    I have generated the ECC from the ELF file output from build using the command:

    nowECC -i sw111770.out -f021 16M_ADD -r4 -d

    and this outputs the following feedback:

    This is nowECC Version 2.22
    Mapping: F021-16MB

    ECC calculation from 0x00000000 to 0x0003592F
    *** Writing only ECC section to file -> sw111770_ECC.out
    No Errors

    I can then convert the ELF produced to binary with the command

    armhex.exe -b --issue_remarks --outfile=sw111770_ECC.bin sw111770_ECC.out 2>&1

    This outputs the folowing feedback

    Translating to Binary format...
       "sw111770_ECC.out"   ==> .ecc0

    The sw111770_ECC.bin file is 27430 bytes long (0x6B26 bytes)

    If I use linker generated ECC and output to binary I get a file which has the application binary (identical to binary generated without ECC), followed by 0x60D0 bytes of ECC. This ECC binary exactly matches the first 0x60D0 bytes of ECC binary generated using nowECC.

     

  • Hi Andy,

    Good to hear that you have both methodes up and running.

    The expected ECC size for your binary is 0x35930 / 8 = 0x6B26 (27430) or 0x60D0 + 0xA56 = 0x6B26

    So the binary from the nowECC ELF file seems to be correct.

    With this it seems that the linker doesn't generate ECC for the whole flash. This indicates, that you LCF isn't set correctly.

    Can you please check the memory usage in the *.map file, like:

    MEMORY CONFIGURATION
    
             name            origin    length      used     unused   attr    fill
    ----------------------  --------  ---------  --------  --------  ----  --------
      VECTORS               00000000   00000020  00000020  00000000     X  ffffffff 
      FLASH0                00000020   00017fe0  00017fe0  00000000  R  X  ffffffff 
      FLASH1                00180000   00180000  00000000  00180000  R  X (ffffffff)
      STACKS                08000000   00001500  00000000  00001500  RW  
      RAM                   08001500   0003eb00  00000d80  0003dd80  RW  
      FLASH7                f0200000   00010000  00000000  00010000  R    (ffffffff)
      ECC_VEC               f0400000   00000004  00000004  00000000  R   
      ECC_FLA0              f0400004   00002ffc  00002ffc  00000000  R   

    Best Regards,

    Christian

  • Well I've only got a partial success on the linker generated ECC, because despite everything I have tried I can't seem to generate more than 0x60D0 bytes of ECC. :(

    MEMORY CONFIGURATION

             name            origin    length      used     unused   attr    fill
    ----------------------  --------  ---------  --------  --------  ----  --------
      FLASH_VECTORS         00000000   00000020  00000020  00000000  R  X
      FLASH_APP             00000020   002fffe0  00035910  002ca6d0  R  X (00000000)
      RAM_STACKS            08000000   00004300  00000000  00004300  RW
      RAM_APP               08004300   00039fa4  00017095  00022f0f  RW
      RAM_KEY_SLOT_1        0803e2a4   00000004  00000000  00000004  RW 
      RAM_KEY_SLOT_2        0803e2a8   00000004  00000000  00000004  RW 
      RAM_KEY_SLOT_3        0803e2ac   00000004  00000000  00000004  RW 
      RAM_KEY_SLOT_4        0803e2b0   00000004  00000000  00000004  RW 
      RAM_CONFIG            0803e2b4   00001d4c  00000000  00001d4c  RW 
      EEPROM_SEC1           f0200000   00004000  00000000  00004000  R  
      EEPROM_SEC2           f0204000   00004000  00000000  00004000  R  
      EEPROM_SEC3           f0208000   00004000  00000000  00004000  R  
      EEPROM_SEC4           f020c000   00004000  00000000  00004000  R  
      ECC_VECTORS           f0400000   00000004  00000004  00000000  R  
      ECC_APP               f0400004   0005fffc  000060cc  00059f30  R  

    The Map shows enough memory set aside for ECC to have 1 byte ECC generated from every 8 bytes in source section, but the 'used' column shows that ECC_APP is short because 8 * 60cc is just  0x30660, not 0x35910

    The segment allocation map also reinforces length of ECC as 60cc, as does the section allocation map

    Can't figure out what is going on, so probably rule out using linker generated ECC and stick with the traditional nowECC route.

     

  • Hi Andy,

    This looks really weird.
    Maybe this has something to do with the fill=false option in conjunction with the vfill=0x00000000.
    Could you please share the complete map file with me and try what happens if fill=true?

    You can use the private message functionality.

    Thanks,
    Christian

  • I've tried all options including vfill=0xFFFFFFFF

    Linker command file has an instruction

    --fill_value=0x00000000

    which I presume defaults fill to 0's. However no effect if comment out and substitute with explicit fill qualifiers in memory definition.

    If you omit the fill=false option (whatever vfill), you get ECC for complete flash, i.e 1/8th of 0x300000 = 0x60000 bytes of ECC

    Interestingly the same linker command file without the ECC directive in the memory map definition can produce out file that generates correct ECC using nowECC

    I'll try send map via message fn you mention

  • Hi Andy,

    Thanks for sending those files, I can now reproduce the faulty behaviour.

    I guess that it has something to do with the GROUP's you used in the LCF. For some reason the linker only calculates ECC for the .text section and not for the other sections in the GROUP. Your .text section is 0x00030660 --> 0x00030660 / 8 = 0x60CC

    On my machine I see the same behaviour with a different CG Tools Version (5.2.4) and a different .text section size of cause.
    I will put together a simple test case and send it to our Compiler Team for further investigation.

    The Issue is filed as SDSCM00052083, you should be able to track this at: https://cqweb.ext.ti.com/cqweb/main?command=GenerateMainFrame&service=CQ&schema=SDO-Web&contextid=SDOWP&username=readonly&password=readonly

    Best Regards,
    Christian

  • Hi Andy,

    I just received the notification from the system, that the bug has been fixed in CGT versions 5.1.13 and 5.2.5.

    Best Regards,
    Christian