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.

Where will the CRC stored for CC2541 ImageA and ImageB in the generated Hex file

Hi,

I had a query regarding the CRC location storage in the ImageA and ImageB hex files.

When we refer to the linker file "cc254x_f256_imgA.xcl" and "cc254x_f256_imgB.xcl", there is a statement:

// Skip CRC & SHDW when calculating the CRC.
//
-J2,crc=8005,=0804-_BANK7_END

Does this mean that the CRC is located in the generated ImageA or ImageB hex files at the offset 8005 (0x1F45) ?

If this understanding is incorrect, then can you please explain, where to find the offset for calculated CRC ?

Do we need to read back the whole flash (contains BIM + ImageA + ImageB) and check where the CRC for ImageA and ImageB are stored ?
Is there any fixed offset in the flash for the same ?

Everytime after OAD of ImageB, does ImageA generate different CRC for ImageB ?
If yes, where we can find this in source code (the updation of CRC from ImageA for ImageB) ?


Thanks,

Sunny

  • Hi Sunny,

    Please refer to the CC254x OAD guide: processors.wiki.ti.com/.../OAD
    The code for validating the the respective images is located in the BIM project.

    Best wishes
  • Hi JXS,

    Thank you for your reply.

    I have been through the OAD Guideline for CC254x and I had really good insight on the OAD Code. But still I have a doubt regarding the checkDL() function.

    1. As per the "OAD_for_CC254x.pdf" section "14.7 Completion of OAD Process" it is mentioned:

    The OAD Target will then invalidate its own image and reset so that the BIM can run the new image in-place.

    e.g. we are running ImgA, and doing a OAD for ImgB, then from the above statement, will ImgA invalidate itself ?

    If the above understanding is correct, then why in checkDL() function, we are setting the crc[0] as 0xFFFF, and writing it to the flash @ 0x4000 (the linker script for ImgA is not changed).

    2. As per our understanding, checkDL() function, always returns false from the below statement:

    return (crc[0] == crc[1]);

    then from where will the device get reset, after a successful OAD.

    It would be really great if you could help us understand checkDL() function in detail.

    Thanks,

    Sunny

  • I would appreciate if someone can throw some light on this.

  • 1. Img B is always checked firstly. So, if A is running and reboots, B will be checked before going to A. If B meets the criteria to be validated, it will validate, and if successful, the BIM will jump to B.

    2. checkDL will return false if crc[0] != crc[1]. Can you clarify what is the concern with this conditional?
    The reset happens if the caller of checkDL gets a TRUE response.

    Best wishes
  • Hi JXS,

    Thank you for the reply.

    But still, we have some confusion for the checkDL() function.

    In the below code block of checkDL() function:

    if (crc[1] == 0xFFFF)
    {
    crc[1] = crcCalcDL();

    #if defined FEATURE_OAD_BIM // If download image is made to run in-place, enable it here.
    uint16 addr = OAD_IMG_D_PAGE * OAD_FLASH_PAGE_MULT + OAD_IMG_CRC_OSET / HAL_FLASH_WORD_SIZE;
    crc[0] = 0xFFFF;
    HalFlashWrite(addr, (uint8 *)crc, 1);
    HalFlashRead(OAD_IMG_D_PAGE, OAD_IMG_CRC_OSET, (uint8 *)crc, sizeof(crc));
    #endif
    }

    return (crc[0] == crc[1]);

    Here, for ImgA, we have the FEATURE_OAD_BIM preprocessor flag defined in our project.

    The crc[1] which we believe is the Shadow CRC, is 0xFFFF when the ImgB is generated. We are checking the 3rd and 4th Byte of the generated .bin file, to confirm the same.

    So we go inside the "if (crc[1] == 0xFFFF)" condition and proceed.

    Now we calculate the shadow CRC and store it in crc[1] via the statement crc[1] = crcCalcDL().

    Also the below statement:

    uint16 addr = OAD_IMG_D_PAGE * OAD_FLASH_PAGE_MULT + OAD_IMG_CRC_OSET / HAL_FLASH_WORD_SIZE;

    is evaluated as:

    uint16 addr = 8 * 512 + 0 / 4;

    So, addr = 4096.
    The actual flash address is 4096 * HAL_FLASH_WORD_SIZE = 0x4000 (the location of CHECKSUM=0x4000-0x4001, for ImgB linker script)

    After that, the crc[0] is invalidated by assigned 0xFFFF to it.
    It is then written to location addr = 4096 (i.e. @0x4000), along with crc[1] having the newly calculated value via the below statement:

    HalFlashWrite(addr, (uint8 *)crc, 1);

    Then a HalFlashRead() is done from the OAD_IMG_D_PAGE (which is OAD_IMG_B_PAGE = 8).
    The OAD_IMG_D_PAGE corresponds to the Flash Location 8 * HAL_FLASH_PAGE_SIZE = 0x4000, where we get crc[0] and crc[1], updated by HalFlashWrite() function.

    Since crc[0] has already been made to 0xFFFF, and crc[1] has the calculated CRC updated by crcCalcDL() function, these two values will not match.

    So, return (crc[0] == crc[1]) will return FALSE, and we will not get a RESET.

    Please do let us know if we have misunderstood anything.


    Thanking you,

    Sunny

  • Hi Sunny,

    I'm not sure I understand "Since crc[0] has already been made to 0xFFFF".

    The final step is to read-back the full CRC struct (both CRC0 & CRC1) from flash before the two values are compared.

    Can you step through the code with a debugger? I think it will be more clear seeing the values in the debugger.

    Best wishes
  • Hi JXS,

    We tried to step through the debugger.

    We are able to put breakpoints in the oadImgBlockWrite() function at the below line:

    if (checkDL())

    But we are not able to step-in the checkDL() function.

    Also we tried to put break point in the checkDL() function, but we are not able to put break point in the checkDL() function.

    We are able to point break points in other functions like crcCalcDL() function.

    If possible, can you please try to put break point in the crcCalcDL() function, and help us out regarding the same.


    Thanks,

    Sunny

  • Hi JXS,

    We found out the update process for crc[0] and crc[1], and how they will be same on successful download.

    We referred to the SWRU191F.pdf document (Section 6.2 Flash Write), it is mentioned that:

    The chip-erase command (through the debug interface) erases all pages in the flash. This is the only way to set bits in the flash to 1. When writing a word to the flash, the 0-bits are programmed to 0 and the 1-bits are ignored (leaves the bit in the flash unchanged). Thus, bits are erased to 1 and can be written to 0.

    So that is the reason for the below code in checkDL() function:

    crc[0] = 0xFFFF;
    HalFlashWrite(addr, (uint8 *)crc, 1);
    HalFlashRead(OAD_IMG_D_PAGE, OAD_IMG_CRC_OSET, (uint8 *)crc, sizeof(crc));

    So by the above code, we update the crc[1], i.e. the Shadow CRC of the OAD Downloaded Image.

    The crc[0] (which is calculated by the IAR during code compilation) is kept as it is by writing crc[0] as 0xFFFF, so the crc[0] located @ 0x4000 for ImgB, will not be written.

    Thanks for your time.

    Regards,

    Sunny

  • Hi Sunny,

    Glad to hear you have been able to understand the OAD process! Your explanation should help others who are searching the forum.

    Best wishes