mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-20 10:54:14 +01:00
OP-152: Save CRC for object and header into flash and only load object if CRC
matches. Read the flash first bytewise to compute CRC instead of buffering which is more RAM efficient but very inefficient as it sets up many one byte SPI transfers. Also incremented the filesystem magic flag to trigger an automatic flash wipe on this upgrade.
This commit is contained in:
parent
3e5d02cbaf
commit
599483d5ac
@ -56,7 +56,7 @@ struct fileHeader {
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
#define OBJECT_TABLE_MAGIC 0x85FB3C33
|
||||
#define OBJECT_TABLE_MAGIC 0x85FB3C34
|
||||
#define OBJ_MAGIC 0x3015AE71
|
||||
#define OBJECT_TABLE_START 0x00000010
|
||||
#define OBJECT_TABLE_END 0x00001000
|
||||
@ -194,6 +194,7 @@ int32_t PIOS_FLASHFS_GetNewAddress(uint32_t objId, uint16_t instId)
|
||||
int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data)
|
||||
{
|
||||
uint32_t objId = UAVObjGetID(obj);
|
||||
uint8_t crc = 0;
|
||||
|
||||
int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId);
|
||||
|
||||
@ -215,14 +216,23 @@ int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data)
|
||||
return -2;
|
||||
|
||||
// Save header
|
||||
// This information IS redundant with the object table id. Oh well. Better safe than sorry.
|
||||
|
||||
// This information IS redundant with the object table id. Oh well. Better safe than sorry.
|
||||
if(PIOS_Flash_W25X_WriteData(addr, (uint8_t *) &header, sizeof(header)) != 0)
|
||||
return -3;
|
||||
|
||||
|
||||
// Update CRC
|
||||
crc = PIOS_CRC_updateCRC(0, (uint8_t *) &header, sizeof(header));
|
||||
|
||||
// Save data
|
||||
if(PIOS_Flash_W25X_WriteData(addr + sizeof(header), data, UAVObjGetNumBytes(obj)) != 0)
|
||||
return -4;
|
||||
|
||||
// Update CRC
|
||||
crc = PIOS_CRC_updateCRC(crc, (uint8_t *) data, UAVObjGetNumBytes(obj));
|
||||
|
||||
// Save CRC (written so will work when CRC changes to uint16)
|
||||
if(PIOS_Flash_W25X_WriteData(addr + sizeof(header) + UAVObjGetNumBytes(obj), (uint8_t *) &crc, sizeof(crc)) != 0)
|
||||
return -4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -236,12 +246,16 @@ int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data)
|
||||
* @retval -2 if unable to retrieve object header
|
||||
* @retval -3 if loaded data instId or objId don't match
|
||||
* @retval -4 if unable to retrieve instance data
|
||||
* @retval -5 if unable to read CRC
|
||||
* @retval -6 if CRC doesn't match
|
||||
* @note This uses one sector on the flash chip per object so that no buffering in ram
|
||||
* must be done when erasing the sector before a save
|
||||
*/
|
||||
int32_t PIOS_FLASHFS_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data)
|
||||
{
|
||||
uint32_t objId = UAVObjGetID(obj);
|
||||
uint8_t crc = 0;
|
||||
uint8_t crcFlash = 0;
|
||||
|
||||
int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId);
|
||||
|
||||
@ -256,13 +270,31 @@ int32_t PIOS_FLASHFS_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data)
|
||||
if(PIOS_Flash_W25X_ReadData(addr, (uint8_t *) &header, sizeof(header)) != 0)
|
||||
return -2;
|
||||
|
||||
// Update CRC
|
||||
crc = PIOS_CRC_updateCRC(0, (uint8_t *) &header, sizeof(header));
|
||||
|
||||
if((header.id != objId) || (header.instId != instId))
|
||||
return -3;
|
||||
|
||||
// To avoid having to allocate the RAM for a copy of the object, we read once bytewise
|
||||
// and compute the CRC (inefficient)
|
||||
for(uint32_t i = 0; i < UAVObjGetNumBytes(obj); i++) {
|
||||
uint8_t byte;
|
||||
PIOS_Flash_W25X_ReadData(addr + sizeof(header) + i, &byte, 1);
|
||||
crc = PIOS_CRC_updateByte(crc, byte);
|
||||
}
|
||||
|
||||
// Read CRC (written so will work when CRC changes to uint16)
|
||||
if(PIOS_Flash_W25X_ReadData(addr + sizeof(header) + UAVObjGetNumBytes(obj), (uint8_t *) &crcFlash, sizeof(crcFlash)) != 0)
|
||||
return -5;
|
||||
|
||||
if(crc != crcFlash)
|
||||
return -6;
|
||||
|
||||
// Read the instance data
|
||||
if (PIOS_Flash_W25X_ReadData(addr + sizeof(header), data, UAVObjGetNumBytes(obj)) != 0)
|
||||
return -4;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -705,24 +705,24 @@ UAVObjHandle UAVObjLoadFromFile(FILEINFO * file)
|
||||
int32_t UAVObjLoad(UAVObjHandle obj, uint16_t instId)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
|
||||
ObjectList *objEntry = (ObjectList *) obj;
|
||||
ObjectList *objEntry = (ObjectList *) obj;
|
||||
|
||||
if (objEntry == NULL)
|
||||
return -1;
|
||||
if (objEntry == NULL)
|
||||
return -1;
|
||||
|
||||
ObjectInstList *instEntry = getInstance(objEntry, instId);
|
||||
ObjectInstList *instEntry = getInstance(objEntry, instId);
|
||||
|
||||
if (instEntry == NULL)
|
||||
return -1;
|
||||
if (instEntry == NULL)
|
||||
return -1;
|
||||
|
||||
if (instEntry->data == NULL)
|
||||
return -1;
|
||||
if (instEntry->data == NULL)
|
||||
return -1;
|
||||
|
||||
// Fire event on success
|
||||
if (PIOS_FLASHFS_ObjLoad(obj, instId, instEntry->data) == 0)
|
||||
sendEvent(objEntry, instId, EV_UNPACKED);
|
||||
else
|
||||
return -1;
|
||||
// Fire event on success
|
||||
if (PIOS_FLASHFS_ObjLoad(obj, instId, instEntry->data) == 0)
|
||||
sendEvent(objEntry, instId, EV_UNPACKED);
|
||||
else
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_INCLUDE_SDCARD)
|
||||
|
Loading…
x
Reference in New Issue
Block a user