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.

[参考译文] CC1312R:更改 OAD 外部闪存扇区大小会导致向 extFlash 中的地址0x0写入无效数据

Guru**** 1624165 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1347975/cc1312r-changing-oad-external-flash-sector-size-causes-invalid-write-to-address-0x0-in-extflash

器件型号:CC1312R

大家好!

在我的设计中、我希望外部闪存中有一个 OAD 映像、以及一个备份出厂映像。

我的 OAD 闪存扇区大小为0x80000字节、通过测试、我看到出厂映像和 OAD 映像无法放入此大小的扇区:

上传的图像位于地址范围:0x20000 - 0x60380。

出厂映像位于地址范围:0x37000 - 0x7EC20。

因此、我曾尝试将 OAD 闪存扇区大小从0x80000增大到0x120000、之后我看到创建出厂映像会在需要写入扇区元数据时失败。

uint8_t OADStorage_createFactoryImageBackup(void)
{
    uint8_t rtn = OADStorage_Status_Success;
    uint8_t status = 0;
    uint32_t dstAddr = oadFindFactImgAddr();
    uint32_t dstAddrStart = dstAddr;
    uint32_t imgStart = _imgHdr.imgPayload.startAddr;
    uint32_t imgLen = _imgHdr.fixedHdr.imgEndAddr - (uint32_t)&_imgHdr;

    /* initialize external flash driver */
    if(flash_open() != 0)
    {
        // First erase factory image metadata page
        if(eraseFlashPg(EXT_FLASH_PAGE(EFL_ADDR_META)) != FLASH_SUCCESS)
        {
            return OADStorage_FlashError;
        }

        /* Erase - external portion to be written*/
        status = oadEraseExtFlashPages(EXT_FLASH_PAGE(dstAddr),
                (_imgHdr.fixedHdr.imgEndAddr - _imgHdr.imgPayload.startAddr -1),
                 EFL_PAGE_SIZE);
        if(status == OADStorage_Status_Success)
        {
            /* COPY - image from internal to external */
//            if(writeFlashPg(dstAddrStart, sizeof(imgHdr_t), (uint8_t *)(imgStart), imgLen) == FLASH_SUCCESS)
          if(writeFlash(dstAddr, (uint8_t *)(imgStart), imgLen) == FLASH_SUCCESS)
           {
               imgHdr_t imgHdr = { .fixedHdr.imgID = OAD_EXTFL_ID_VAL }; /* Write OAD flash metadata identification */

               /* Copy Image header from internal flash image, skip ID values */
               memcpy( ((uint8_t *)&imgHdr + CRC_OFFSET), ((uint8_t *)imgStart + 8) , OAD_IMG_HDR_LEN);

               /*
                * Calculate the CRC32 value and update that in image header as CRC32
                * wouldn't be available for running image.
                */
               imgHdr.fixedHdr.crc32 = CRC32_calc(imgHdr.imgPayload.startAddr, INTFLASH_PAGE_SIZE, 0,  imgLen, false);

               /* Update CRC status */
               imgHdr.fixedHdr.crcStat = CRC_VALID;

               /* Update image length */
               imgHdr.fixedHdr.len = _imgHdr.fixedHdr.imgEndAddr - (uint32_t)&_imgHdr;

               uint32_t *ptr = (uint32_t *)&imgHdr;

               /* update external flash storage address */
               ptr[OAD_IMG_HDR_LEN/4] = dstAddrStart;

               /* Allow application or some other place in BIM to mark factory image as
                  pending copy (OAD_IMG_COPY_PEND). Should not be done here, as
                  what is in flash at this time will already be the factory
                  image. */
               imgHdr.fixedHdr.imgCpStat = DEFAULT_STATE;
               imgHdr.fixedHdr.imgType = OAD_IMG_TYPE_FACTORY;

               /* WRITE METADATA */
                if(writeFlash(EFL_ADDR_META, (uint8_t *)&imgHdr, OAD_IMG_HDR_LEN + 8) != FLASH_SUCCESS)
                {
                   rtn = OADStorage_FlashError;
                }
            } // end of if(writeFlash((dstAddr+4,  (uint8_t *)(imgStart +4), (imgLen -4)) == FLASH_SUCCESS)
            else
            {
                rtn = OADStorage_FlashError;
            }
       }
       else //  if(extFlashErase(dstAddr, imgLen))
       {
           rtn = OADStorage_FlashError;
       } //  end of if(extFlashErase(dstAddr, imgLen))

        ExtImageInfo_t metadataHdr={0};
               /* Read whole metadata header */
          readFlash(0, (uint8_t *)&metadataHdr, EFL_METADATA_LEN);
        /* close driver */
        flash_close();

     } // end of flash_Open



    return(rtn);
}

内联:

if (writeFlash (EFL_ADDR_meta、(uint8_t *)&imgHdr、OAD_IMG_HDR_LEN + 8)!= FLASH_SUCCESS)

writeFlash 返回 NVS_STATUS_INV_WRITE、我不明白为什么。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Yarden、您好、

    我假设这是一个15.4堆栈示例 、并且您要使用外部 OAD 作为起点?

    此致、
    SID