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.

TMS570LS3137 / TMS570LS0432 Problem with Linker Command File and Flash API

Other Parts Discussed in Thread: HALCOGEN, TMS570LS3137, TMS570LS0432, NOWECC

Dear experts,

working on a bootloader project for two different versions of TMS570 I came to a point where the program during startup gets stuck during EEPROM blank check performed in the F021 Flash API.

The project consists of the Demo Example provided by HALCOGEN (including FreeRTOS functionality) , uses the FEE routines from Halcogen and application code. Everthings works fine using the linker command file based on the original code from HALCOGEN:

MEMORY
{
    VECTORS (X)  : origin=0x00000000 length=0x00000020
    KERNEL  (RX) : origin=0x00000020 length=(0x00008000 - 0x00000020)
    FLASH0  (RX) : origin=0x00010000 length=(0x00190000 - 0x00010000)
    FLASH1  (RX) : origin=0x00190000 length=0x00180000
    STACKS  (RW) : origin=0x08000000 length=0x00001500
    KRAM    (RW) : origin=0x08001500 length=0x00000800
    RAM     (RW) : origin=(0x08001500+0x00000800) length=(0x0003eaff - 0x00000800)
    
/* USER CODE BEGIN (2) */
/* USER CODE END */
}

/* USER CODE BEGIN (3) */
/* USER CODE END */

/*----------------------------------------------------------------------------*/
/* Section Configuration                                                      */

SECTIONS
{
    .intvecs : {} > VECTORS
    /* FreeRTOS Kernel in protected region of Flash */
    .kernelTEXT   : { sys_startup.obj(.const)
                      os_tasks.obj (.const:.string)
                      -l=../lib/rtsv7R4_T_be_v3D16_eabi.lib<auto_init.obj> (.text)
                      -l=../lib/rtsv7R4_T_be_v3D16_eabi.lib<copy_decompress_rle.obj> (*)
                      -l=../lib/rtsv7R4_T_be_v3D16_eabi.lib<cpy_tbl.obj> (*)
                      -l=../lib/rtsv7R4_T_be_v3D16_eabi.lib<copy_zero_init.obj> (*)
                      -l=../lib/rtsv7R4_T_be_v3D16_eabi.lib<copy_decompress_none.obj> (*)
                      -l=../lib/rtsv7R4_T_be_v3D16_eabi.lib<icall32.obj> (.text)
                      -l=../lib/rtsv7R4_T_be_v3D16_eabi.lib<memset32.obj> (.text)
                      -l=../lib/rtsv7R4_T_be_v3D16_eabi.lib<memcpy32.obj> (.text)
                    } > KERNEL
    .cinit        : {} > KERNEL
    .pinit        : {} > KERNEL
    /* Rest of code to user mode flash region */
    .text         : {} > FLASH0 | FLASH1
    .const        : {} > FLASH0 | FLASH1
    /* FreeRTOS Kernel data in protected region of RAM */
    .kernelBSS    : {} > KRAM
    .kernelHEAP   : {} > RAM
    .bss          : {} > RAM
    .data         : {} > RAM    
    .sysmem       : {} > RAM
    FEE_TEXT_SECTION : {} > FLASH0 | FLASH1
    FEE_CONST_SECTION : {} > FLASH0 | FLASH1
    FEE_DATA_SECTION : {} > RAM

Modifiying the linker Command file with the purpose to move the kernel and all subsequent content to start adress of the second sector causes the FAPI to crash during startup.

I debugged into th code as far as possible and found out that the FEE code wants to perform an eeprom blank check of bank #7 which crashes inside the F021 API. I had been using version 02.01.00.

The system gets caught inside a trap with the label flashreal.

What  I do not understand: Why does the behaviour depand on the modification of the linker command file and therefore on thelocation of code in the flash memory?

Thanks, appreciating al helful responses,

Peter

  • some more details:

    CCS Compiler: 5.1.7

    HALCOGEN: 4.00.00

  • Alfred,

    What does your new linker command file look like?  (And which device is crashing, the LS3137, the 0432 or both?

  • Anthony,

    the problem occured with both devices.

    For TMS570LS3137 only one line was changed in comparison to the example above:

    KERNEL  (RX) : origin=0x00008020 length=0x00003000

    The start adress of the kernel is moved to beginning to sector 1.

    On TMS570LS0432 this would be

    KERNEL  (RX) : origin=0x00006020 length=0x00003000

    due to a smaller sector size.

    We had be making experiments, if smaller shift values for the destination of the KERNEL section work. As a result the follwing modifikation works:

    KERNEL  (RX) : origin=0x00000104 length=3000

    while

    KERNEL  (RX) : origin=0x00000108 length=3000

    leads to dabort.asm ->flashErrorReal

    The behaviour seems to related to ecc during startup. Disabling all selftests and ecc leads to a functioning binary starting at adress 0x00008020.

  • In the forum I came across a thread dsicussing the generation of ecc data:

    http://e2e.ti.com/support/microcontrollers/hercules/f/312/t/304439.aspx

    There an alignment to 64 Byte Blocks is discussed.

    So far I had been assuming that ecc data was generated correctly by the debugger by enabling the corresponding checkbox in the CCS GUI, regardless of the structure of the binary to be flashed.

    The code we would like to run has the following structure:

    0x00000000 - 0x0000001F Vectors

    unused area

    0x00008000 - 0x0000801F Vectors

    0x00008020 - ... Program, consts ...

    How is internally dealt with the unused area by the toolchain? How the options for the flash process have to be set? Which data content is assumd by the algorithm calculating the eccs assuming that a 64 Byte alignment of data is needed?

    Thanks for any help?

  • Alfred,

    I need to double check that post - the ECC is checked on 64-bit units so I am now wondering if 64 bytes was a mistake.

    The reason the alignment is required is that unlike the main area in flash, if you were to program say byte 0x1000 but leave bytes 0x1001, 0x1002, ... 0x1007 erased (as 0xFF) you could come back later and program those bytes - because you can make the flash change a bit from 1 to 0 without erasing the whole sector.

    But for ECC since the calculation is done over units of 64 bits;  if you program just 0x1000 you would at the same time need to program the ECC value for 0x1001, 0x1002, ... 0x1007.    Now if you later tried to program something in 0x1001 while you can do that in the main area,  the corresponding ECC update may not be possible because it is very likely that it will require a bit to flip from 0 -> 1 and that can only be done by erasing the entire sector.

    That's where the alignment requirement comes from - it's the nature of the beast because ECC is calculated on 64-bit units.   The only way around this would be to calculate ECC on smaller units but it gets very expensive to do that so economics prevent it.

    Definitely make sure you have the alignment on 8 byte boundaries set in the linker command file  -  I think that is what the forum post that you found was saying with the palign(8) statement. 

    The rest of the forum post covered linker generated ECC which is more robust but also more complex.  For day to day development there's no issue I think in using the silicon to generate it's own ECC which is what the checkbox in CCS does.  The linker generated ECC is arguably better though because you've got an independent CPU generating the ECC values (the CPU on your host PC).

  • We were finally able to iisolate the problem. it is caused be a weird combination of details:

    1) The application crashes due to an ESM group3 error caused by uncorrectable ECC errors during Flash access.

    2) The reason is partially missing ECC data in the corresponding Flash area following adress  0xF040 0000

    3) The ECC information ist missing, regardless die ECC generation was done due to checkbox setting in the CCS GUI o by nowECC.exe

    4) It is not influenced by settings for fill values (GUI + linker command file)

    5) Some of the sections in my linker command file are not completely filled. ECC data is missing only for unused areas.

    6) depending on the structure of the linker command file (see above) the problem occurs or not. If an unused space in one of the sections is larger 104 Bytes, the program is not working.

    Finally we could find out the reason for this:


    We are using some functions of the SafeTiDiagLib. In sl_log.c data is supposed to be place in a corresponding section:

    #ifdef __TI_COMPILER_VERSION__
    #pragma DATA_SECTION ( SL_Pbist_Profile_Struct , "PROFILE_DATA" );
    #endif

    This DATA_SECTION was not explicitely mentioned in my linker command file. As a consequence the linker places it in the earliest available free free space of the memory map. Looks like there would exactly 104 bytes be needed.

    Further this data seems to be "unitailized" and is therefore completely ommited by the ECC data generation algorithms.

    Unfortunately neither the GUI nor nowECC are communicaiong this fact. Only from the diagnostic messages of nowECC (length of ECC blocks generated) can be guessed that the data is missing.

    The only way to get a precise diagnostic of the problem is by using ECC generation by the linker command file. 

    After having searched for quite a while to understand this problem, the following quesions remain:

    Why GUI nor nowECC are able to issue a clear error message, that the generated ECC is partly incorrect or cannot be calculated?

    Why it is not documented that of the mentioned  three possible ecc generation algorithms each seems to behave different and which one should be preferred?

  • Alfred,

    Thanks for getting to the bottom of the issue.

    I don't think an uninitialized data section belongs in flash for starters as these sections are usually for stack or heap.

    Will need to check on this w. the safe TI library team.

    I would think that the place you should see the error/warnings about this would be in the linker stage.  You didn't get any notification about this during the link?