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.

MSP432P401R: How to use IAR's ielftool to calculate CRC32 equivalent to CRC32 module in DriverLib?

Part Number: MSP432P401R

Hi folks,

I have hit a wall, and need some help.  I am using the MSP432P401R with the IAR ARM Cortex-M tools.

I have an image for a SPI Flash, which is 256KB in size.  We have reserved the last sector of 4KB for some modifiable calibration parameters, so I have located the CRC32 just before that sector, at locations 0x3FFFC-0x3FFFF.  I am trying to calculate the CRC32 over the remaining space, i.e. from 0x00000 to 0x3FFFB.

Here is the command line I use to try to do this in IAR using ielftool:

ielftool --verbose --fill=0x00;0x00000000-0x0003EFFF --checksum=g_CRC32:4,crc32:i,0xFFFFFFFF;0x00000000-0x0003EFFB SPI_Flash.out SPI_Flash.out
ielftool --verbose --bin SPI_Flash.out SPI_Flash.bin

After doing this, I end up with 0x12 0x6D 0x8F 0x22 in the locations 0x3EFFC thru 0x3EFFF, respectively, which is where g_CRC32 is located.  If read as a little-endian value, this would be 0x228F6D12.  So far so good, and I can read that back in from the SPI Flash without problems.

The difficulty comes when I try to use the CRC32 module in DriverLib.  My code does the following (which was borrowed from an example from DriverLib on using the CRC32 module:

    MAP_CRC32_setSeed(0xFFFFFFFF, CRC32_MODE);

    uint8_t spiBuffer[1024];    // Read a page at a time
    uint32_t addr = 0u;
    size_t nBytes = 0x3FFFC;    // Read all bytes up to stored CRC
    size_t bytesToRead;
    
    // Read a buffer at a time until all bytes have been added to the CRC32
    while (nBytes != 0)
    {
        if (nBytes >= sizeof(spiBuffer))
        {
            bytesToRead = sizeof(spiBuffer);
        }
        else
        {
            bytesToRead = nBytes;
        }
        
        Read(addr, spiBuffer, bytesToRead);
        
        // Add all of the bytes to the CRC32 calculation
        for (size_t i = 0; i < bytesToRead; i++)
        {
            MAP_CRC32_set8BitData(spiBuffer[i], CRC32_MODE);
        }
        
        addr += bytesToRead;
        nBytes -= bytesToRead;
    }
    
    // Getting the result back from the hardware module
    uint32_t hwCalculatedCRC = MAP_CRC32_getResultReversed(CRC32_MODE) ^ 0xFFFFFFFF;

    return hwCalculatedCRC;

Unfortunately, the value of hwCalculatedCRC is 0x529961DC, which isn't even close to what ielftool generated.

There are many options for configuring ielftool, as well as options for configuring the CRC32 module in DriverLib.  I tried to make sure the seed value was consistent, set to 0xFFFFFFFF.

I confess that I'm at a loss, and hoping someone in the forum has gone thru similar pain, perhaps using ielftool to calculate a CRC32 for an executable image on an MSP432, and then using the CRC32 module and DriverLib to calculate a matching CRC32.

I have attached the .out and .bin files that I've been working with, and I'm willing to try any reasonable experiments to get this to work.  Not only do I need to get it working for this SPI Flash, but I will need to perform a similar CRC32 check of my executable's image on the MSP432.

Thanks very much for any help, and please let me know if I can clarify in any way.

ScottSPI_Flash.zip

  • Hello Scott,

    The CRC checksum in ielftool seems to be using 32-bit data alignment while in the code you have posted, the CRC is being calculated on 8-bit data. Can you please try using 32-bit CRC operations and check?
  • Hello, Amit,

    Thanks for your reply.  However, I am not sure what you would like me to try.  How did you determine that ielftool was using 32 bit alignment?  Can that be changed to match the use of 8-bit data as I have done in my code?  I need to see what the DriverLib call would be to use 32-bit data.  If you have an example, that would help tremendously.

    I appreciate your help and the reply.  A bit more info and I'd be very happy to run experiments.   I have to get this working,  and I'm sure others have encountered similar problems.  The DriverLib documentation is a bit sparse.

    Kindest regards,

    Scott

  • Hello Scott

    Can you please send the original .out file that you are using, so that I can run some experiments with the tool and the program?
  • Sure Amit,  thank you for offering to help.  The original, unmodified .out file is in the attached .zip file

    6177.SPI_Flash.zip

    With thanks and best regards,

    Scott

  • I also tried some experiments with the CRC32 module, as suggested using the well-known CRC web site .  They suggest using the string "123456789" as test input for various types of CRCs.  I ran the following, and it produced exactly the same result as this web site, 0xCBF43296.  Therefore, I think that the problem lies somewhere in the use of ielftool itself, and perhaps what it is using for a polynomial, whether it uses lowest-bit first or highest-bit-first, and whether it does a final XOR with 0xFFFFFFFF.

    Here is the code that produces the same result as the above mentioned web site.  Any hints on how to get ielftool to produce the same output would be greatly appreciated!

        char testData[] = "123456789";
        
        MAP_CRC32_setSeed(CRC_32::CRC32_INIT, CRC32_MODE);
        for (size_t i = 0; i < 9; i++)
        {
            MAP_CRC32_set8BitData(testData[i], CRC32_MODE);
        }
    
        // Getting the result back from the hardware module */
        uint32_t calculatedCRC = MAP_CRC32_getResultReversed(CRC32_MODE) ^ 0xFFFFFFFF;
    

    Kind regards,

    Scott

  • Hello Scott,

    I checked the IETF tool example, where they claim it works well along with the options

    www.iar.com/.../

    Thanks for sending the file. I will go through the same and check some other tools as well.
  • Hi Amit,

    After much trial and error, I was finally able to get the IAR tools to do what I needed.  In newer versions of IAR, under project options/Linker/Checksum, you can enter the following data:

    With these settings, a correct CRC32 is generated and placed in a reserved location named __checksum.  To preserve this location, under LInker/Extra Options, you will need to add

    --keep __checksum

    Then, in the linker configuration file, I had the following.  Note the placement of section .checksum at the end of ROM_region:

    /*###ICF### Section handled by ICF editor, don't touch! ****/
    /*-Editor annotation file-*/
    /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */
    /*-Specials-*/
    /*-Memory Regions-*/
    define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
    define symbol __ICFEDIT_region_ROM_end__   = 0x0003FFFF - 0x1000;
    define symbol __ICFEDIT_region_PERSISTENT_STORE_start__ = 0x00040000 - 0x1000;
    define symbol __ICFEDIT_region_PERSISTENT_STORE_end__   = 0x0003FFFF;
    /*-Sizes-*/
    define symbol __ICFEDIT_size_cstack__     = 0x400;
    define symbol __ICFEDIT_size_proc_stack__ = 0x0;
    define symbol __ICFEDIT_size_heap__       = 0x800;
    /**** End of ICF editor section. ###ICF###*/
    
    define memory mem with size = 256K;
    define region ROM_region   =   mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
    
    do not initialize  { section .noinit };
    initialize by copy { readwrite };
    if (isdefinedsymbol(__USE_DLIB_PERTHREAD))
    {
      // Required in a multi-threaded application
      initialize by copy with packing = none { section __DLIB_PERTHREAD };
    }
    
    place at start of ROM_region { section ICONS, section FONTS };
    place at end of ROM_region { section VERSION, section .checksum };
    place in ROM_region { readonly };
    

    Finally, under Optins/Build Actions, I added a post-build command line to convert the .out file to a binary .bin file:

    $TOOLKIT_DIR$\bin\ielftool --bin $TARGET_PATH$ $TARGET_BPATH$.bin

    Clearly, it was quite a bit of pain, but now it is working and makes sense.  I have also attached a zip file containing both the original unmodified .out and the resulting .bin, which has the CRC32 filled in, just prior to a 4k reserved block that I will be using for some modifiable data.

    5460.SPI_Flash.zip

    I sincerely hope this helps someone else.  The same techniques should be able to be used to calculate a CRC32 of the overall program image too - a job for a day very soon!

    With thanks and best regards,

    Scott 

  • Hello Scott

    Thanks for posting a resolution on the forum. Indeed it would be a great help to others. I shall mark you answer as Verified and close the thread. You may re-open the thread in case there is an issue.

**Attention** This is a public forum