I'm using the MKW41Z Connectivity Software v1.0.2 and I'm seeing something in Flash_Adapter.c that doesn't make sense. In the NV_WriteHWParameters() function it's computing and storing the CRC in the pHwParams variable and then it's setting the identificationWord element, which causes the calculated CRC to (probably) no longer be valid. Is this a bug, or am I missing something? Here's the code (observe the order of operations on lines 3 and 4):
if(!FLib_MemCmp(pHwParams, (void*)FREESCALE_PROD_DATA_BASE_ADDR, sizeof(hardwareParameters_t)))
{
pHwParams->hardwareParamsCrc = NV_ComputeCrcOverHWParameters(pHwParams);
FLib_MemCpy(pHwParams->identificationWord, (void*)mProdDataIdentifier, sizeof(mProdDataIdentifier));
status = NV_FlashEraseSector((uint32_t)FREESCALE_PROD_DATA_BASE_ADDR, FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE);
if( 0 == status )
{
status = NV_FlashProgramUnaligned((uint32_t)FREESCALE_PROD_DATA_BASE_ADDR,
sizeof(hardwareParameters_t),
(uint8_t*)pHwParams);
}
}
NV_ComputeCrcOverHWParameters starts computing CRC after the identificationWord field, hence, the CRC is still valid:
uint8_t *ptr = (uint8_t *)(&pHwParams->reserved);
uint16_t len = (uint8_t *)(&pHwParams->hardwareParamsCrc) -
(uint8_t *)(&pHwParams->reserved);
Here's the struct definition:
typedef PACKED_STRUCT hardwareParameters_tag
{
uint8_t identificationWord[10]; /* valid data present */
uint8_t reserved[32]; /* for backward compatibillity */
uint8_t ieee_802_15_4_address[8]; /* IEEE 802.15.4 MAC address */
uint8_t bluetooth_address[6]; /* Bluetooth address */
uint32_t xtalTrim; /* KW4x only */
uint32_t edCalibrationOffset; /* KW01 ED offset */
uint32_t pllFStepOffset; /* KW01 fine tune pll */
uint32_t gInternalStorageAddr; /* The start address of the internal storage used for OTA update.
A value of 0xFFFFFFFF means that the External storage is used.
Warning: The offset to this field in respect to the start address of the structure
must not be changed.*/
/* For forward compatibility additional fields may be added here
Existing data in flash will not be compatible after modifying the hardwareParameters_t typedef*/
uint16_t hardwareParamsCrc; /* crc for data between start of reserved area and start of hardwareParamsCrc field (not included). */
}hardwareParameters_t;
Note the struct is packed at 1 byte boundary.