diff --git a/flight/pios/common/pios_flashfs_objlist.c b/flight/pios/common/pios_flashfs_objlist.c index 4111eb029..1fbb66411 100644 --- a/flight/pios/common/pios_flashfs_objlist.c +++ b/flight/pios/common/pios_flashfs_objlist.c @@ -31,11 +31,8 @@ #include "openpilot.h" #include "uavobjectmanager.h" - -// Private functions -static int32_t PIOS_FLASHFS_ClearObjectTableHeader(); -static int32_t PIOS_FLASHFS_GetObjAddress(uint32_t objId, uint16_t instId); -static int32_t PIOS_FLASHFS_GetNewAddress(uint32_t objId, uint16_t instId); +#ifdef PIOS_INCLUDE_FLASH_OBJLIST +#include // Private variables static int32_t numObjects = -1; @@ -43,109 +40,187 @@ static int32_t numObjects = -1; // Private structures // Header for objects in the file system table struct objectHeader { - uint32_t objMagic; - uint32_t objId; - uint32_t instId; - uint32_t address; + uint32_t objMagic; + uint32_t objId; + uint32_t instId; + uint32_t address; } __attribute__((packed));; struct fileHeader { - uint32_t id; - uint16_t instId; - uint16_t size; + uint32_t id; + uint16_t instId; + uint16_t size; } __attribute__((packed)); +enum pios_flashfs_dev_magic { + PIOS_FLASHFS_DEV_MAGIC = 0xF1A58205, +}; -#define MAX_BADMAGIC 1000 +struct flashfs_dev { + uint32_t magic; + const struct flashfs_cfg *cfg; + const struct pios_flash_driver *driver; + uintptr_t flash_id; +}; + +// Private functions +static int32_t PIOS_FLASHFS_ClearObjectTableHeader(struct flashfs_dev *dev); +static int32_t PIOS_FLASHFS_GetObjAddress(struct flashfs_dev *dev, uint32_t objId, uint16_t instId); +static int32_t PIOS_FLASHFS_GetNewAddress(struct flashfs_dev *dev, uint32_t objId, uint16_t instId); + +#define MAX_BADMAGIC 1000 + +static struct flashfs_dev *PIOS_FLASHFS_Alloc() +{ + struct flashfs_dev *dev; + + dev = (struct flashfs_dev *)pios_malloc(sizeof(*dev)); + if (!dev) { + return NULL; + } + + dev->magic = PIOS_FLASHFS_DEV_MAGIC; + return dev; +} +int32_t PIOS_FLASHFS_validate(struct flashfs_dev *dev) +{ + return dev && dev->magic == PIOS_FLASHFS_DEV_MAGIC; +} -static const struct flashfs_cfg * cfg; /** * @brief Initialize the flash object setting FS * @return 0 if success, -1 if failure */ -int32_t PIOS_FLASHFS_Init(const struct flashfs_cfg * new_cfg) + +int32_t PIOS_FLASHFS_Init(uintptr_t *fs_id, const struct flashfs_cfg *cfg, const struct pios_flash_driver *driver, uintptr_t flash_id) { - cfg = new_cfg; - - // Check for valid object table or create one - uint32_t object_table_magic; - uint32_t magic_fail_count = 0; - bool magic_good = false; + PIOS_Assert(cfg); + PIOS_Assert(fs_id); + PIOS_Assert(driver); - while(!magic_good) { - if (PIOS_Flash_Jedec_ReadData(0, (uint8_t *)&object_table_magic, sizeof(object_table_magic)) != 0) - return -1; - if(object_table_magic != new_cfg->table_magic) { - if(magic_fail_count++ > MAX_BADMAGIC) { - if(PIOS_FLASHFS_Format() != 0) - return -1; + // PIOS_Assert((cfg->total_fs_size / cfg->arena_size > 1)); + + /* Make sure the underlying flash driver provides the minimal set of required methods */ + PIOS_Assert(driver->start_transaction); + PIOS_Assert(driver->end_transaction); + PIOS_Assert(driver->write_data); + PIOS_Assert(driver->rewrite_data); + PIOS_Assert(driver->read_data); + + struct flashfs_dev *dev; + + dev = PIOS_FLASHFS_Alloc(); + if (!dev) { + return -1; + } + + /* Bind configuration parameters to this filesystem instance */ + dev->cfg = cfg; /* filesystem configuration */ + dev->driver = driver; /* lower-level flash driver */ + dev->flash_id = flash_id; /* lower-level flash device id */ + + // Check for valid object table or create one + uint32_t object_table_magic; + uint32_t magic_fail_count = 0; + bool magic_good = false; + *fs_id = (uintptr_t)dev; + + while (!magic_good) { + if (dev->driver->read_data(dev->flash_id, 0, (uint8_t *)&object_table_magic, sizeof(object_table_magic)) != 0) { + return -1; + } + if (object_table_magic != dev->cfg->table_magic) { + if (magic_fail_count++ > MAX_BADMAGIC) { + if (PIOS_FLASHFS_Format(*fs_id) != 0) { + return -1; + } #if defined(PIOS_LED_HEARTBEAT) - PIOS_LED_Toggle(PIOS_LED_HEARTBEAT); -#endif /* PIOS_LED_HEARTBEAT */ - magic_fail_count = 0; - magic_good = true; - } else { - PIOS_DELAY_WaituS(1000); - } - } - else { - magic_good = true; - } + PIOS_LED_Toggle(PIOS_LED_HEARTBEAT); +#endif /* PIOS_LED_HEARTBEAT */ + magic_fail_count = 0; + magic_good = true; + } else { + PIOS_DELAY_WaituS(1000); + } + } else { + magic_good = true; + } + } - } + uint32_t addr = cfg->obj_table_start; + struct objectHeader header; + numObjects = 0; - int32_t addr = cfg->obj_table_start; - struct objectHeader header; - numObjects = 0; + // Loop through header area while objects detect to count how many saved + while (addr < cfg->obj_table_end) { + // Read the instance data + if (dev->driver->read_data(dev->flash_id, addr, (uint8_t *)&header, sizeof(header)) != 0) { + return -1; + } - // Loop through header area while objects detect to count how many saved - while(addr < cfg->obj_table_end) { - // Read the instance data - if (PIOS_Flash_Jedec_ReadData(addr, (uint8_t *)&header, sizeof(header)) != 0) - return -1; + // Counting number of valid headers + if (header.objMagic != cfg->obj_magic) { + break; + } - // Counting number of valid headers - if(header.objMagic != cfg->obj_magic) - break; + numObjects++; + addr += sizeof(header); + } - numObjects++; - addr += sizeof(header); - } - - return 0; + return 0; } /** * @brief Erase the whole flash chip and create the file system * @return 0 if successful, -1 if not */ -int32_t PIOS_FLASHFS_Format() +int32_t PIOS_FLASHFS_Format(uintptr_t fs_id) { - if(PIOS_Flash_Jedec_EraseChip() != 0) - return -1; - if(PIOS_FLASHFS_ClearObjectTableHeader() != 0) - return -1; - return 0; + struct flashfs_dev *dev = (struct flashfs_dev *)fs_id; + + if (!PIOS_FLASHFS_validate(dev)) { + return -1; + } + + if (!dev->driver->start_transaction(dev->flash_id)) { + return -1; + } + + + if (dev->driver->erase_chip) { + if (dev->driver->erase_chip(dev->flash_id) != 0) { + dev->driver->end_transaction(dev->flash_id); + return -1; + } + } + + if (PIOS_FLASHFS_ClearObjectTableHeader(dev) != 0) { + return -1; + } + return 0; } /** * @brief Erase the headers for all objects in the flash chip * @return 0 if successful, -1 if not */ -static int32_t PIOS_FLASHFS_ClearObjectTableHeader() +static int32_t PIOS_FLASHFS_ClearObjectTableHeader(struct flashfs_dev *dev) { - if(PIOS_Flash_Jedec_EraseSector(0) != 0) - return -1; + if (dev->driver->erase_sector(dev->flash_id, 0) != 0) { + return -1; + } - if (PIOS_Flash_Jedec_WriteData(0, (uint8_t *)&cfg->table_magic, sizeof(cfg->table_magic)) != 0) - return -1; + if (dev->driver->write_data(dev->flash_id, 0, (uint8_t *)&dev->cfg->table_magic, sizeof(dev->cfg->table_magic)) != 0) { + return -1; + } - uint32_t object_table_magic; - PIOS_Flash_Jedec_ReadData(0, (uint8_t *)&object_table_magic, sizeof(object_table_magic)); - if(object_table_magic != cfg->table_magic) - return -1; + uint32_t object_table_magic; + dev->driver->read_data(dev->flash_id, 0, (uint8_t *)&object_table_magic, sizeof(object_table_magic)); + if (object_table_magic != dev->cfg->table_magic) { + return -1; + } - return 0; + return 0; } /** @@ -154,27 +229,30 @@ static int32_t PIOS_FLASHFS_ClearObjectTableHeader() * @parma instId Instance id for that object * @return address if successful, -1 if not found */ -static int32_t PIOS_FLASHFS_GetObjAddress(uint32_t objId, uint16_t instId) +static int32_t PIOS_FLASHFS_GetObjAddress(struct flashfs_dev *dev, uint32_t objId, uint16_t instId) { - int32_t addr = cfg->obj_table_start; - struct objectHeader header; + uint32_t addr = dev->cfg->obj_table_start; + struct objectHeader header; - // Loop through header area while objects detect to count how many saved - while(addr < cfg->obj_table_end) { - // Read the instance data - if (PIOS_Flash_Jedec_ReadData(addr, (uint8_t *) &header, sizeof(header)) != 0) - return -1; - if(header.objMagic != cfg->obj_magic) - break; // stop searching once hit first non-object header - else if (header.objId == objId && header.instId == instId) - break; - addr += sizeof(header); - } + // Loop through header area while objects detect to count how many saved + while (addr < dev->cfg->obj_table_end) { + // Read the instance data + if (dev->driver->read_data(dev->flash_id, addr, (uint8_t *)&header, sizeof(header)) != 0) { + return -1; + } + if (header.objMagic != dev->cfg->obj_magic) { + break; // stop searching once hit first non-object header + } else if (header.objId == objId && header.instId == instId) { + break; + } + addr += sizeof(header); + } - if (header.objId == objId && header.instId == instId) - return header.address; + if (header.objId == objId && header.instId == instId) { + return header.address; + } - return -1; + return -1; } /** @@ -188,36 +266,40 @@ static int32_t PIOS_FLASHFS_GetObjAddress(uint32_t objId, uint16_t instId) * @retval -4 FS not initialized * @retval -5 */ -int32_t PIOS_FLASHFS_GetNewAddress(uint32_t objId, uint16_t instId) +static int32_t PIOS_FLASHFS_GetNewAddress(struct flashfs_dev *dev, uint32_t objId, uint16_t instId) { - struct objectHeader header; + struct objectHeader header; - if(numObjects < 0) - return -4; + if (numObjects < 0) { + return -4; + } - // Don't worry about max size of flash chip here, other code will catch that - header.objMagic = cfg->obj_magic; - header.objId = objId; - header.instId = instId; - header.address = cfg->obj_table_end + cfg->sector_size * numObjects; + // Don't worry about max size of flash chip here, other code will catch that + header.objMagic = dev->cfg->obj_magic; + header.objId = objId; + header.instId = instId; + header.address = dev->cfg->obj_table_end + dev->cfg->sector_size * numObjects; - int32_t addr = cfg->obj_table_start + sizeof(header) * numObjects; + int32_t addr = dev->cfg->obj_table_start + sizeof(header) * numObjects; - // No room for this header in object table - if((addr + sizeof(header)) > cfg->obj_table_end) - return -2; + // No room for this header in object table + if ((addr + sizeof(header)) > dev->cfg->obj_table_end) { + return -2; + } - // Verify the address is within the chip - if((addr + cfg->sector_size) > cfg->chip_size) - return -5; + // Verify the address is within the chip + if ((addr + dev->cfg->sector_size) > dev->cfg->chip_size) { + return -5; + } - if(PIOS_Flash_Jedec_WriteData(addr, (uint8_t *) &header, sizeof(header)) != 0) - return -3; + if (dev->driver->write_data(dev->flash_id, addr, (uint8_t *)&header, sizeof(header)) != 0) { + return -3; + } - // This numObejcts value must stay consistent or there will be a break in the table - // and later the table will have bad values in it - numObjects++; - return header.address; + // This numObejcts value must stay consistent or there will be a break in the table + // and later the table will have bad values in it + numObjects++; + return header.address; } @@ -229,67 +311,75 @@ int32_t PIOS_FLASHFS_GetNewAddress(uint32_t objId, uint16_t instId) * @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_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data) +int32_t PIOS_FLASHFS_ObjSave(uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t *obj_data, uint16_t obj_size) { - uint32_t objId = UAVObjGetID(obj); - uint8_t crc = 0; + struct flashfs_dev *dev = (struct flashfs_dev *)fs_id; - if(PIOS_Flash_Jedec_StartTransaction() != 0) - return -1; + if (!PIOS_FLASHFS_validate(dev)) { + return -1; + } - int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId); - // Object currently not saved - if(addr < 0) - addr = PIOS_FLASHFS_GetNewAddress(objId, instId); + uint8_t crc = 0; - // Could not allocate a sector - if(addr < 0) { - PIOS_Flash_Jedec_EndTransaction(); - return -1; - } + if (dev->driver->start_transaction(dev->flash_id) != 0) { + return -1; + } - struct fileHeader header = { - .id = objId, - .instId = instId, - .size = UAVObjGetNumBytes(obj) - }; - - // Update CRC - crc = PIOS_CRC_updateCRC(0, (uint8_t *) &header, sizeof(header)); - crc = PIOS_CRC_updateCRC(crc, (uint8_t *) data, UAVObjGetNumBytes(obj)); + int32_t addr = PIOS_FLASHFS_GetObjAddress(dev, obj_id, obj_inst_id); - if(PIOS_Flash_Jedec_EraseSector(addr) != 0) { - PIOS_Flash_Jedec_EndTransaction(); - return -2; - } + // Object currently not saved + if (addr < 0) { + addr = PIOS_FLASHFS_GetNewAddress(dev, obj_id, obj_inst_id); + } - struct pios_flash_chunk chunks[3] = { - { - .addr = (uint8_t *) &header, - .len = sizeof(header), - }, - { - .addr = (uint8_t *) data, - .len = UAVObjGetNumBytes(obj) - }, - { - .addr = (uint8_t *) &crc, - .len = sizeof(crc) - } - }; + // Could not allocate a sector + if (addr < 0) { + dev->driver->end_transaction(dev->flash_id); + return -1; + } - if(PIOS_Flash_Jedec_WriteChunks(addr, chunks, NELEMENTS(chunks)) != 0) { - PIOS_Flash_Jedec_EndTransaction(); - return -1; - } - - if(PIOS_Flash_Jedec_EndTransaction() != 0) { - PIOS_Flash_Jedec_EndTransaction(); - return -1; - } + struct fileHeader header = { + .id = obj_id, + .instId = obj_inst_id, + .size = obj_size, + }; - return 0; + // Update CRC + crc = PIOS_CRC_updateCRC(0, (uint8_t *)&header, sizeof(header)); + crc = PIOS_CRC_updateCRC(crc, obj_data, obj_size); + + if (dev->driver->erase_sector(dev->flash_id, addr) != 0) { + dev->driver->end_transaction(dev->flash_id); + return -2; + } + + struct pios_flash_chunk chunks[3] = { + { + .addr = (uint8_t *)&header, + .len = sizeof(header), + }, + { + .addr = obj_data, + .len = obj_size + }, + { + .addr = (uint8_t *)&crc, + .len = sizeof(crc) + } + }; + + if (dev->driver->write_chunks(dev->flash_id, addr, chunks, NELEMENTS(chunks)) != 0) { + dev->driver->end_transaction(dev->flash_id); + return -1; + } + + if (dev->driver->end_transaction(dev->flash_id) != 0) { + dev->driver->end_transaction(dev->flash_id); + return -1; + } + + return 0; } /** @@ -306,72 +396,77 @@ int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data) * @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) +int32_t PIOS_FLASHFS_ObjLoad(uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t *obj_data, uint16_t obj_size) { - uint32_t objId = UAVObjGetID(obj); - uint16_t objSize = UAVObjGetNumBytes(obj); - uint8_t crc = 0; - uint8_t crcFlash = 0; - const uint8_t crc_read_step = 8; - uint8_t crc_read_buffer[crc_read_step]; + struct flashfs_dev *dev = (struct flashfs_dev *)fs_id; - if(PIOS_Flash_Jedec_StartTransaction() != 0) - return -1; + if (!PIOS_FLASHFS_validate(dev)) { + return -1; + } + uint8_t crc = 0; + uint8_t crcFlash = 0; + const uint8_t crc_read_step = 8; + uint8_t crc_read_buffer[crc_read_step]; - int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId); + if (dev->driver->start_transaction(dev->flash_id) != 0) { + return -1; + } - // Object currently not saved - if(addr < 0) { - PIOS_Flash_Jedec_EndTransaction(); - return -1; - } + int32_t addr = PIOS_FLASHFS_GetObjAddress(dev, obj_id, obj_inst_id); - struct fileHeader header; + // Object currently not saved + if (addr < 0) { + dev->driver->end_transaction(dev->flash_id); + return -1; + } - // Load header - // This information IS redundant with the object table id. Oh well. Better safe than sorry. - if(PIOS_Flash_Jedec_ReadData(addr, (uint8_t *) &header, sizeof(header)) != 0) { - PIOS_Flash_Jedec_EndTransaction(); - return -2; - } - - // Update CRC - crc = PIOS_CRC_updateCRC(0, (uint8_t *) &header, sizeof(header)); + struct fileHeader header; - if((header.id != objId) || (header.instId != instId)) { - PIOS_Flash_Jedec_EndTransaction(); - return -3; - } - - // To avoid having to allocate the RAM for a copy of the object, we read by chunks - // and compute the CRC - for(uint32_t i = 0; i < objSize; i += crc_read_step) { - PIOS_Flash_Jedec_ReadData(addr + sizeof(header) + i, crc_read_buffer, crc_read_step); - uint8_t valid_bytes = ((i + crc_read_step) >= objSize) ? objSize - i : crc_read_step; - crc = PIOS_CRC_updateCRC(crc, crc_read_buffer, valid_bytes); - } + // Load header + // This information IS redundant with the object table id. Oh well. Better safe than sorry. + if (dev->driver->read_data(dev->flash_id, addr, (uint8_t *)&header, sizeof(header)) != 0) { + dev->driver->end_transaction(dev->flash_id); + return -2; + } - // Read CRC (written so will work when CRC changes to uint16) - if(PIOS_Flash_Jedec_ReadData(addr + sizeof(header) + objSize, (uint8_t *) &crcFlash, sizeof(crcFlash)) != 0) { - PIOS_Flash_Jedec_EndTransaction(); - return -5; - } + // Update CRC + crc = PIOS_CRC_updateCRC(0, (uint8_t *)&header, sizeof(header)); - if(crc != crcFlash) { - PIOS_Flash_Jedec_EndTransaction(); - return -6; - } + if ((header.id != obj_id) || (header.instId != obj_inst_id)) { + dev->driver->end_transaction(dev->flash_id); + return -3; + } - // Read the instance data - if (PIOS_Flash_Jedec_ReadData(addr + sizeof(header), data, objSize) != 0) { - PIOS_Flash_Jedec_EndTransaction(); - return -4; - } + // To avoid having to allocate the RAM for a copy of the object, we read by chunks + // and compute the CRC + for (uint32_t i = 0; i < obj_size; i += crc_read_step) { + dev->driver->read_data(dev->flash_id, addr + sizeof(header) + i, crc_read_buffer, crc_read_step); + uint8_t valid_bytes = ((i + crc_read_step) >= obj_size) ? obj_size - i : crc_read_step; + crc = PIOS_CRC_updateCRC(crc, crc_read_buffer, valid_bytes); + } - if(PIOS_Flash_Jedec_EndTransaction() != 0) - return -1; + // Read CRC (written so will work when CRC changes to uint16) + if (dev->driver->read_data(dev->flash_id, addr + sizeof(header) + obj_size, (uint8_t *)&crcFlash, sizeof(crcFlash)) != 0) { + dev->driver->end_transaction(dev->flash_id); + return -5; + } - return 0; + if (crc != crcFlash) { + dev->driver->end_transaction(dev->flash_id); + return -6; + } + + // Read the instance data + if (dev->driver->read_data(dev->flash_id, addr + sizeof(header), obj_data, obj_size) != 0) { + dev->driver->end_transaction(dev->flash_id); + return -4; + } + + if (dev->driver->end_transaction(dev->flash_id) != 0) { + return -1; + } + + return 0; } /** @@ -385,18 +480,26 @@ int32_t PIOS_FLASHFS_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data) * remains but destination sector is erased. This will make the load fail as the * file header won't match the object. At next save it goes back there. */ -int32_t PIOS_FLASHFS_ObjDelete(UAVObjHandle obj, uint16_t instId) +int32_t PIOS_FLASHFS_ObjDelete(uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id) { - uint32_t objId = UAVObjGetID(obj); + struct flashfs_dev *dev = (struct flashfs_dev *)fs_id; - int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId); + if (!PIOS_FLASHFS_validate(dev)) { + return -1; + } - // Object currently not saved - if(addr < 0) - return -1; - if(PIOS_Flash_Jedec_EraseSector(addr) != 0) - return -2; + int32_t addr = PIOS_FLASHFS_GetObjAddress(dev, obj_id, obj_inst_id); - return 0; + // Object currently not saved + if (addr < 0) { + return -1; + } + + if (dev->driver->erase_sector(dev->flash_id, addr) != 0) { + return -2; + } + + return 0; } +#endif /* PIOS_INCLUDE_FLASH_OBJLIST */ diff --git a/flight/pios/inc/pios_flashfs_objlist.h b/flight/pios/inc/pios_flashfs_objlist.h index a330da230..9e7eefd8a 100644 --- a/flight/pios/inc/pios_flashfs_objlist.h +++ b/flight/pios/inc/pios_flashfs_objlist.h @@ -12,36 +12,32 @@ * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "openpilot.h" #include "uavobjectmanager.h" - +#include struct flashfs_cfg { - uint32_t table_magic; - uint32_t obj_magic; - uint32_t obj_table_start; - uint32_t obj_table_end; - uint32_t sector_size; - uint32_t chip_size; + uint32_t table_magic; + uint32_t obj_magic; + uint32_t obj_table_start; + uint32_t obj_table_end; + uint32_t sector_size; + uint32_t chip_size; }; -int32_t PIOS_FLASHFS_Init(const struct flashfs_cfg * cfg); -int32_t PIOS_FLASHFS_Format(); -int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data); -int32_t PIOS_FLASHFS_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data); -int32_t PIOS_FLASHFS_ObjDelete(UAVObjHandle obj, uint16_t instId); +int32_t PIOS_FLASHFS_Init(uintptr_t *fs_id, const struct flashfs_cfg *cfg, const struct pios_flash_driver *driver, uintptr_t flash_id);