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.

CRC or checksum at end of code.

I'm using a TIVA C series, CCS v6.  What I'd like to do is have a CRC value at the end of FLASH that is not part of the CRC calculation, and set a symbol in the linker command file that points to the  last address to be included in the calculation.  It appears that the linker reorders the sections.  This is my linker file

MEMORY
{
    FLASH (RX) : origin = 0x00000000, length = 0x00100000
    SRAM (RWX) : origin = 0x20000000, length = 0x00040000
}

/* Section allocation in memory */

SECTIONS
{
   .intvecs:   > 0x00000000
   .text   :   > FLASH
   .const  :   > FLASH
   .cinit  :   > FLASH
   .pinit  :   > FLASH
   .init_array : END(__flash_end) > FLASH
   .myCRCSect : > FLASH
}

However, myCRCsect does not end up last, and __flash_end does not seem to contain the correct address. Is there a recommended way to do this?

And incidentally, is the correct way in c to reference __flash_end as a pointer?  E.g. *__flash_end ?  I haven't found examples of this, and I'm not sure I'm doing it right.

Thanks for any help.

Mike

  • Hi,

    try to define a group:

    GROUP
    {
      .text
      ...
      .myCRCSect
    } > FLASH
    

    Since __flash_end is a linker time defined symbol, only its address is meaningfull, so don't use it as a pointer but take its address:

    extern int __flash_end;

    void* flash_end_address=&__flash_end;

  • Thanks, that seems to work fine.

    Mike

  • While the GROUP solution works fine, it is overly restrictive.  Another solution that is more flexible is to use the HIGH location specifier.  It would look like ...

        .init_array > FLASH(HIGH), END(__flash_end)

    All the other lines remain unchanged.

    Thanks and regards,

    -George

  • George,

    I like that better, since it also avoids the whole .data section not compressible circular problem.  I got it to work with the following  linker file, but this assumes .cinit will always be last. (myCRCSect contains 4 bytes of precalculated CRC, don't want that included in the calculation so it is moved out of the way.)

       .intvecs:   > 0x00000000
       .text   :   > FLASH
       .const  :   > FLASH
       .cinit  :   > FLASH END(__flash_end)
       .pinit  :   > FLASH
       .init_array : > FLASH 
    
       .myCRCSect :  > FLASH(HIGH)
    

    That is currently true from what I've observed (.init_array is empty and seems to be placed first) but can I rely on that to stay true long term?  Otherwise, without the group, I haven't been able to figure out how to set __flash_end to the first empty address.  I use this to calculate the checksum over everything that is programmed in flash.


    Mike

  • Mike Stich said:
    this assumes .cinit will always be last

    Mike Stich said:
    can I rely on that to stay true long term?

    In most cases in practice, the .cinit section will be the last one allocated to FLASH.  However, that is not guaranteed.  If you need to guarantee it, the only solution is to use GROUP as described above, and just live with the .cinit section not getting compressed.

    Since that is not very nice, I filed SDSCM00050442 in the SDOWP system to request an enhancement to the linker.  The entry requests a method to capture the last location used in a memory range in a symbol.  Feel free to follow it with the SDOWP link below in my signature.

    Thanks and regards,

    -George