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.

CCS Linker checksum calculation over the whole flash memory

Hi,

I'm working on a F2801 MCU right now, and we have a requirement of flash integrity check at every startup. I've found a feature in the linker (v6.0.1) that calculates the CRC for some output section which later can be verified during boot, which is almost what we want.

For several reasons, it would be better for us if it is possible somehow to configure the linker to calculate one checksum for the whole flash memory content, instead of several checksums over each sections as it is now. Is it possible somehow to specify that the linker checksum utility should calculate the CRC over the whole flash memory (excluding last words that contains CSM, stored CRC, branch instruction, etc etc.)?

That is, we would like the checksum to be calculated over memory section "FLASHA" instead of output sections specified in the Linker File.

Best regards,

Dan Persson

Syncore Technologies AB

  • Sorry, but the CRC feature can only be applied on a section by section basis.

    Thanks and regards,

    -George

  • Hi Georgem,

    Ok, I see. Thank you for your quick response!

    We just came up with another idea how to solve it. We check that the memory addresses outside these sections and outside the CRC tables are equal to 0xFFFF. Then we can be sure that the compiler has not put any executable code outside the "CRC-controlled" sections by 'mistake'.

    Best regards,

    Dan Persson

    Syncore Technologies AB

  • Is this still not possible?

    Are there any workarounds?  

  • There have been no changes in the linker regarding the CRC feature.

    Thanks and regards,

    -George

  • George,

    Thank you for your answer.

    Can you please review this solution?

    1. During build, do a CRC on all of the individual sections in FLASH
    2. Place the individual results in a CRC Section in FLASH.
    3. During run-time, do a CRC on the CRC Section

    Would this result be the same as if I ran a CRC on the entire FLASH (minus the CRC Section) during run-time? I suppose what I am asking is:  Are the CRCs of a group of subset CRCs the same as a CRC on the full set?

    Backing up a bit, I need a solution for a run-time CRC that works both when downloading via JTAG and downloading via SCI.  At startup, I want to read a stored CRC and compare it to a run-time generated one. When I am downloading via SCI, I can send an "Update CRC" command that does the full flash CRC and stores that value. When I am downloading via JTAG, I want to use the CRC from the linker for this same function.

  • No, the CRC of a set of CRCs would not have the same value as a CRC on the complete FLASH. Even if this was the case, you wouldn't want to do it, because you wouldn't be detecting errors in all of FLASH, you would only be detecting errors in the CRC section.
  • With the linker-generated CRCs, you can use it in the same way, but you can only get CRC values for initialized sections, and there would be one CRC value for each distinct section. The TI linker does not have a feature to perform CRC over the entire FLASH.
  • Very good point above. Doing a CRC on the CRCs would be more for versioning (see below). However, it is not true to the spirit of CRC and I can not have that.

    So, what do you wonderful folks think is my best option?

    I have 2 distinct places in FLASH: A custom bootloader and application (each with their own self-contained text, const, etc). At start up, the bootloader should do a CRC, looking for both compatibility and errors. If the CRCs do not match, the bootloader will not run the application, instead, it will loop, waiting to be loaded via SCI.
  • You can use linker-generated CRC tables, you just can't use them to check every byte of FLASH.  You can use them to check initialized sections.  The bootloader should parse the CRC table and call the crc function (not provided):

    #include <crc_tbl.h>
    extern unsigned int app_crc_table_address;
    
    void wait_until_ok_to_run()
    {
        do
        {
            bool ok_to_run = true;
            volatile CRC_TABLE *app_crc_table = _symval(&app_crc_table_address);
            for (int r = 0; r < app_crc_table->num_recs; r++)
            {
                if (crc(app_crc_table->recs[r].addr, 
                        app_crc_table->recs[r].size) != 
                    app_crc_table->recs[r].crc_value)
                {
                    ok_to_run = false;
                    break;
                }
            }
            if (!ok_to_run) wait_until_sci_is_poked();
        } while(1);
    }