1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-21 11:54:15 +01:00

Merge remote-tracking branch 'origin/amorale/OP-954_logfs_settings_in_internal_flash' into next

Conflicts:
	flight/pios/common/pios_flashfs_logfs.c
This commit is contained in:
Alessio Morale 2013-05-18 15:53:25 +02:00
commit c1f767b12d
39 changed files with 1017 additions and 294 deletions

View File

@ -471,38 +471,41 @@ static void ProcessInputStream(UAVTalkConnection connectionHandle, uint8_t rxbyt
switch (obj_per.Operation) { switch (obj_per.Operation) {
case OBJECTPERSISTENCE_OPERATION_LOAD: case OBJECTPERSISTENCE_OPERATION_LOAD:
{ {
#if defined(PIOS_INCLUDE_FLASH_EEPROM) #if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
// Load the settings. // Load the settings.
OPLinkSettingsData oplinkSettings; void *obj = UAVObjGetByID(obj_per.ObjectID);
if (PIOS_EEPROM_Load((uint8_t*)&oplinkSettings, sizeof(OPLinkSettingsData)) == 0) if (obj == 0) {
OPLinkSettingsSet(&oplinkSettings);
else
success = false; success = false;
} else {
// Load selected instance
success = (UAVObjLoad(obj, obj_per.InstanceID) == 0);
}
#endif #endif
break; break;
} }
case OBJECTPERSISTENCE_OPERATION_SAVE: case OBJECTPERSISTENCE_OPERATION_SAVE:
{ {
#if defined(PIOS_INCLUDE_FLASH_EEPROM) #if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
// Save the settings. void *obj = UAVObjGetByID(obj_per.ObjectID);
OPLinkSettingsData oplinkSettings; if (obj == 0) {
OPLinkSettingsGet(&oplinkSettings);
int32_t ret = PIOS_EEPROM_Save((uint8_t*)&oplinkSettings, sizeof(OPLinkSettingsData));
if (ret != 0)
success = false; success = false;
} else {
// Save selected instance
success = UAVObjSave(obj, obj_per.InstanceID) == 0;
}
#endif #endif
break; break;
} }
case OBJECTPERSISTENCE_OPERATION_DELETE: case OBJECTPERSISTENCE_OPERATION_DELETE:
{ {
#if defined(PIOS_INCLUDE_FLASH_EEPROM) #if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
// Erase the settings. void *obj = UAVObjGetByID(obj_per.ObjectID);
OPLinkSettingsData oplinkSettings; if (obj == 0) {
uint8_t *ptr = (uint8_t*)&oplinkSettings;
memset(ptr, 0, sizeof(OPLinkSettingsData));
int32_t ret = PIOS_EEPROM_Save(ptr, sizeof(OPLinkSettingsData));
if (ret != 0)
success = false; success = false;
} else {
// Save selected instance
success = UAVObjDelete(obj, obj_per.InstanceID) == 0;
}
#endif #endif
break; break;
} }

View File

@ -318,7 +318,7 @@ static void objectUpdatedCb(UAVObjEvent * ev)
retval = UAVObjDeleteMetaobjects(); retval = UAVObjDeleteMetaobjects();
} }
} else if (objper.Operation == OBJECTPERSISTENCE_OPERATION_FULLERASE) { } else if (objper.Operation == OBJECTPERSISTENCE_OPERATION_FULLERASE) {
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) #if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
retval = PIOS_FLASHFS_Format(0); retval = PIOS_FLASHFS_Format(0);
#else #else
retval = -1; retval = -1;

View File

@ -39,7 +39,12 @@
* Filesystem state data tracked in RAM * Filesystem state data tracked in RAM
*/ */
enum pios_flashfs_logfs_dev_magic {
PIOS_FLASHFS_LOGFS_DEV_MAGIC = 0x94938201,
};
struct logfs_state { struct logfs_state {
enum pios_flashfs_logfs_dev_magic magic;
const struct flashfs_logfs_cfg * cfg; const struct flashfs_logfs_cfg * cfg;
bool mounted; bool mounted;
uint8_t active_arena_id; uint8_t active_arena_id;
@ -56,8 +61,6 @@ struct logfs_state {
uintptr_t flash_id; uintptr_t flash_id;
}; };
static struct logfs_state logfs;
/* /*
* Internal Utility functions * Internal Utility functions
*/ */
@ -66,14 +69,14 @@ static struct logfs_state logfs;
* @brief Return the offset in flash of a particular slot within an arena * @brief Return the offset in flash of a particular slot within an arena
* @return address of the requested slot * @return address of the requested slot
*/ */
static uintptr_t logfs_get_addr(uint8_t arena_id, uint16_t slot_id) static uintptr_t logfs_get_addr(const struct logfs_state * logfs, uint8_t arena_id, uint16_t slot_id)
{ {
PIOS_Assert(arena_id < (logfs.cfg->total_fs_size / logfs.cfg->arena_size)); PIOS_Assert(arena_id < (logfs->cfg->total_fs_size / logfs->cfg->arena_size));
PIOS_Assert(slot_id < (logfs.cfg->arena_size / logfs.cfg->slot_size)); PIOS_Assert(slot_id < (logfs->cfg->arena_size / logfs->cfg->slot_size));
return (logfs.cfg->start_offset + return (logfs->cfg->start_offset +
(arena_id * logfs.cfg->arena_size) + (arena_id * logfs->cfg->arena_size) +
(slot_id * logfs.cfg->slot_size)); (slot_id * logfs->cfg->slot_size));
} }
/* /*
@ -112,27 +115,27 @@ struct arena_header {
* @return 0 if success, < 0 on failure * @return 0 if success, < 0 on failure
* @note Must be called while holding the flash transaction lock * @note Must be called while holding the flash transaction lock
*/ */
static int32_t logfs_erase_arena(uint8_t arena_id) static int32_t logfs_erase_arena(const struct logfs_state * logfs, uint8_t arena_id)
{ {
uintptr_t arena_addr = logfs_get_addr (arena_id, 0); uintptr_t arena_addr = logfs_get_addr (logfs, arena_id, 0);
/* Erase all of the sectors in the arena */ /* Erase all of the sectors in the arena */
for (uint8_t sector_id = 0; for (uint8_t sector_id = 0;
sector_id < (logfs.cfg->arena_size / logfs.cfg->sector_size); sector_id < (logfs->cfg->arena_size / logfs->cfg->sector_size);
sector_id++) { sector_id++) {
if (logfs.driver->erase_sector(logfs.flash_id, if (logfs->driver->erase_sector(logfs->flash_id,
arena_addr + (sector_id * logfs.cfg->sector_size))) { arena_addr + (sector_id * logfs->cfg->sector_size))) {
return -1; return -1;
} }
} }
/* Mark this arena as fully erased */ /* Mark this arena as fully erased */
struct arena_header arena_hdr = { struct arena_header arena_hdr = {
.magic = logfs.cfg->fs_magic, .magic = logfs->cfg->fs_magic,
.state = ARENA_STATE_ERASED, .state = ARENA_STATE_ERASED,
}; };
if (logfs.driver->write_data(logfs.flash_id, if (logfs->driver->write_data(logfs->flash_id,
arena_addr, arena_addr,
(uint8_t *)&arena_hdr, (uint8_t *)&arena_hdr,
sizeof(arena_hdr)) != 0) { sizeof(arena_hdr)) != 0) {
@ -149,13 +152,13 @@ static int32_t logfs_erase_arena(uint8_t arena_id)
* @note Arena must have been previously erased before calling this * @note Arena must have been previously erased before calling this
* @note Must be called while holding the flash transaction lock * @note Must be called while holding the flash transaction lock
*/ */
static int32_t logfs_reserve_arena (uint8_t arena_id) static int32_t logfs_reserve_arena (const struct logfs_state * logfs, uint8_t arena_id)
{ {
uintptr_t arena_addr = logfs_get_addr (arena_id, 0); uintptr_t arena_addr = logfs_get_addr (logfs, arena_id, 0);
/* Read in the current arena header */ /* Read in the current arena header */
struct arena_header arena_hdr; struct arena_header arena_hdr;
if (logfs.driver->read_data(logfs.flash_id, if (logfs->driver->read_data(logfs->flash_id,
arena_addr, arena_addr,
(uint8_t *)&arena_hdr, (uint8_t *)&arena_hdr,
sizeof(arena_hdr)) != 0) { sizeof(arena_hdr)) != 0) {
@ -170,7 +173,7 @@ static int32_t logfs_reserve_arena (uint8_t arena_id)
arena_hdr.state = ARENA_STATE_RESERVED; arena_hdr.state = ARENA_STATE_RESERVED;
/* Write the arena header back to flash */ /* Write the arena header back to flash */
if (logfs.driver->write_data(logfs.flash_id, if (logfs->driver->write_data(logfs->flash_id,
arena_addr, arena_addr,
(uint8_t *)&arena_hdr, (uint8_t *)&arena_hdr,
sizeof(arena_hdr)) != 0) { sizeof(arena_hdr)) != 0) {
@ -186,9 +189,9 @@ static int32_t logfs_reserve_arena (uint8_t arena_id)
* @return 0 if success, < 0 on failure * @return 0 if success, < 0 on failure
* @note Must be called while holding the flash transaction lock * @note Must be called while holding the flash transaction lock
*/ */
static int32_t logfs_erase_all_arenas() static int32_t logfs_erase_all_arenas(const struct logfs_state * logfs)
{ {
uint16_t num_arenas = logfs.cfg->total_fs_size / logfs.cfg->arena_size; uint16_t num_arenas = logfs->cfg->total_fs_size / logfs->cfg->arena_size;
for (uint16_t arena = 0; arena < num_arenas; arena++) { for (uint16_t arena = 0; arena < num_arenas; arena++) {
#ifdef PIOS_LED_HEARTBEAT #ifdef PIOS_LED_HEARTBEAT
@ -197,7 +200,7 @@ static int32_t logfs_erase_all_arenas()
#ifdef PIOS_INCLUDE_WDG #ifdef PIOS_INCLUDE_WDG
PIOS_WDG_Clear(); PIOS_WDG_Clear();
#endif #endif
if (logfs_erase_arena(arena) != 0) if (logfs_erase_arena(logfs, arena) != 0)
return -1; return -1;
} }
@ -210,13 +213,13 @@ static int32_t logfs_erase_all_arenas()
* @note Arena must have been previously erased or reserved before calling this * @note Arena must have been previously erased or reserved before calling this
* @note Must be called while holding the flash transaction lock * @note Must be called while holding the flash transaction lock
*/ */
static int32_t logfs_activate_arena(uint8_t arena_id) static int32_t logfs_activate_arena(const struct logfs_state * logfs, uint8_t arena_id)
{ {
uintptr_t arena_addr = logfs_get_addr(arena_id, 0); uintptr_t arena_addr = logfs_get_addr(logfs, arena_id, 0);
/* Make sure this arena has been previously erased */ /* Make sure this arena has been previously erased */
struct arena_header arena_hdr; struct arena_header arena_hdr;
if (logfs.driver->read_data(logfs.flash_id, if (logfs->driver->read_data(logfs->flash_id,
arena_addr, arena_addr,
(uint8_t *)&arena_hdr, (uint8_t *)&arena_hdr,
sizeof (arena_hdr)) != 0) { sizeof (arena_hdr)) != 0) {
@ -231,7 +234,7 @@ static int32_t logfs_activate_arena(uint8_t arena_id)
/* Mark this arena as active */ /* Mark this arena as active */
arena_hdr.state = ARENA_STATE_ACTIVE; arena_hdr.state = ARENA_STATE_ACTIVE;
if (logfs.driver->write_data(logfs.flash_id, if (logfs->driver->write_data(logfs->flash_id,
arena_addr, arena_addr,
(uint8_t *)&arena_hdr, (uint8_t *)&arena_hdr,
sizeof(arena_hdr)) != 0) { sizeof(arena_hdr)) != 0) {
@ -248,16 +251,16 @@ static int32_t logfs_activate_arena(uint8_t arena_id)
* @note Arena must have been previously active before calling this * @note Arena must have been previously active before calling this
* @note Must be called while holding the flash transaction lock * @note Must be called while holding the flash transaction lock
*/ */
static int32_t logfs_obsolete_arena(uint8_t arena_id) static int32_t logfs_obsolete_arena(const struct logfs_state * logfs, uint8_t arena_id)
{ {
uintptr_t arena_addr = logfs_get_addr (arena_id, 0); uintptr_t arena_addr = logfs_get_addr (logfs, arena_id, 0);
/* We shouldn't be retiring the currently active arena */ /* We shouldn't be retiring the currently active arena */
PIOS_Assert(!logfs.mounted); PIOS_Assert(!logfs->mounted);
/* Make sure this arena was previously active */ /* Make sure this arena was previously active */
struct arena_header arena_hdr; struct arena_header arena_hdr;
if (logfs.driver->read_data(logfs.flash_id, if (logfs->driver->read_data(logfs->flash_id,
arena_addr, arena_addr,
(uint8_t *)&arena_hdr, (uint8_t *)&arena_hdr,
sizeof (arena_hdr)) != 0) { sizeof (arena_hdr)) != 0) {
@ -272,7 +275,7 @@ static int32_t logfs_obsolete_arena(uint8_t arena_id)
/* Mark this arena as obsolete */ /* Mark this arena as obsolete */
arena_hdr.state = ARENA_STATE_OBSOLETE; arena_hdr.state = ARENA_STATE_OBSOLETE;
if (logfs.driver->write_data(logfs.flash_id, if (logfs->driver->write_data(logfs->flash_id,
arena_addr, arena_addr,
(uint8_t *)&arena_hdr, (uint8_t *)&arena_hdr,
sizeof(arena_hdr)) != 0) { sizeof(arena_hdr)) != 0) {
@ -290,23 +293,23 @@ static int32_t logfs_obsolete_arena(uint8_t arena_id)
* @return -2 if failed to read arena header * @return -2 if failed to read arena header
* @note Must be called while holding the flash transaction lock * @note Must be called while holding the flash transaction lock
*/ */
static int32_t logfs_find_active_arena() static int32_t logfs_find_active_arena(const struct logfs_state * logfs)
{ {
/* Search for the lowest numbered active arena */ /* Search for the lowest numbered active arena */
for (uint8_t arena_id = 0; for (uint8_t arena_id = 0;
arena_id < logfs.cfg->total_fs_size / logfs.cfg->arena_size; arena_id < logfs->cfg->total_fs_size / logfs->cfg->arena_size;
arena_id++) { arena_id++) {
uintptr_t arena_addr = logfs_get_addr (arena_id, 0); uintptr_t arena_addr = logfs_get_addr (logfs, arena_id, 0);
/* Load the arena header */ /* Load the arena header */
struct arena_header arena_hdr; struct arena_header arena_hdr;
if (logfs.driver->read_data(logfs.flash_id, if (logfs->driver->read_data(logfs->flash_id,
arena_addr, arena_addr,
(uint8_t *)&arena_hdr, (uint8_t *)&arena_hdr,
sizeof (arena_hdr)) != 0) { sizeof (arena_hdr)) != 0) {
return -2; return -2;
} }
if ((arena_hdr.state == ARENA_STATE_ACTIVE) && if ((arena_hdr.state == ARENA_STATE_ACTIVE) &&
(arena_hdr.magic == logfs.cfg->fs_magic)) { (arena_hdr.magic == logfs->cfg->fs_magic)) {
/* This is the first active arena */ /* This is the first active arena */
return arena_id; return arena_id;
} }
@ -349,7 +352,7 @@ struct slot_header {
} __attribute__((packed)); } __attribute__((packed));
/* NOTE: Must be called while holding the flash transaction lock */ /* NOTE: Must be called while holding the flash transaction lock */
static int32_t logfs_raw_copy_bytes (uintptr_t src_addr, uint16_t src_size, uintptr_t dst_addr) static int32_t logfs_raw_copy_bytes (const struct logfs_state * logfs, uintptr_t src_addr, uint16_t src_size, uintptr_t dst_addr)
{ {
#define RAW_COPY_BLOCK_SIZE 16 #define RAW_COPY_BLOCK_SIZE 16
uint8_t data_block[RAW_COPY_BLOCK_SIZE]; uint8_t data_block[RAW_COPY_BLOCK_SIZE];
@ -365,7 +368,7 @@ static int32_t logfs_raw_copy_bytes (uintptr_t src_addr, uint16_t src_size, uint
} }
/* Read a block of data from source */ /* Read a block of data from source */
if (logfs.driver->read_data(logfs.flash_id, if (logfs->driver->read_data(logfs->flash_id,
src_addr, src_addr,
data_block, data_block,
blk_size) != 0) { blk_size) != 0) {
@ -374,7 +377,7 @@ static int32_t logfs_raw_copy_bytes (uintptr_t src_addr, uint16_t src_size, uint
} }
/* Write a block of data to destination */ /* Write a block of data to destination */
if (logfs.driver->write_data(logfs.flash_id, if (logfs->driver->write_data(logfs->flash_id,
dst_addr, dst_addr,
data_block, data_block,
blk_size) != 0) { blk_size) != 0) {
@ -396,9 +399,9 @@ static int32_t logfs_raw_copy_bytes (uintptr_t src_addr, uint16_t src_size, uint
* true = all slots in the arena are in the ACTIVE state (ie. garbage collection won't free anything) * true = all slots in the arena are in the ACTIVE state (ie. garbage collection won't free anything)
* false = some slots in the arena are either currently free or could be free'd by garbage collection * false = some slots in the arena are either currently free or could be free'd by garbage collection
*/ */
static bool logfs_fs_is_full(void) static bool logfs_fs_is_full(const struct logfs_state * logfs)
{ {
return (logfs.num_active_slots == (logfs.cfg->arena_size / logfs.cfg->slot_size) - 1); return (logfs->num_active_slots == (logfs->cfg->arena_size / logfs->cfg->slot_size) - 1);
} }
/* /*
@ -406,37 +409,37 @@ static bool logfs_fs_is_full(void)
* true = there are no unwritten slots left in the log (garbage collection may or may not help) * true = there are no unwritten slots left in the log (garbage collection may or may not help)
* false = there are still some entirely unused slots left in the log * false = there are still some entirely unused slots left in the log
*/ */
static bool logfs_log_is_full(void) static bool logfs_log_is_full(const struct logfs_state * logfs)
{ {
return (logfs.num_free_slots == 0); return (logfs->num_free_slots == 0);
} }
static int32_t logfs_unmount_log(void) static int32_t logfs_unmount_log(struct logfs_state * logfs)
{ {
PIOS_Assert (logfs.mounted); PIOS_Assert (logfs->mounted);
logfs.num_active_slots = 0; logfs->num_active_slots = 0;
logfs.num_free_slots = 0; logfs->num_free_slots = 0;
logfs.mounted = false; logfs->mounted = false;
return 0; return 0;
} }
static int32_t logfs_mount_log(uint8_t arena_id) static int32_t logfs_mount_log(struct logfs_state * logfs, uint8_t arena_id)
{ {
PIOS_Assert (!logfs.mounted); PIOS_Assert (!logfs->mounted);
logfs.num_active_slots = 0; logfs->num_active_slots = 0;
logfs.num_free_slots = 0; logfs->num_free_slots = 0;
logfs.active_arena_id = arena_id; logfs->active_arena_id = arena_id;
/* Scan the log to find out how full it is */ /* Scan the log to find out how full it is */
for (uint16_t slot_id = 1; for (uint16_t slot_id = 1;
slot_id < (logfs.cfg->arena_size / logfs.cfg->slot_size); slot_id < (logfs->cfg->arena_size / logfs->cfg->slot_size);
slot_id++) { slot_id++) {
struct slot_header slot_hdr; struct slot_header slot_hdr;
uintptr_t slot_addr = logfs_get_addr (logfs.active_arena_id, slot_id); uintptr_t slot_addr = logfs_get_addr (logfs, logfs->active_arena_id, slot_id);
if (logfs.driver->read_data(logfs.flash_id, if (logfs->driver->read_data(logfs->flash_id,
slot_addr, slot_addr,
(uint8_t *)&slot_hdr, (uint8_t *)&slot_hdr,
sizeof (slot_hdr)) != 0) { sizeof (slot_hdr)) != 0) {
@ -448,14 +451,14 @@ static int32_t logfs_mount_log(uint8_t arena_id)
* end of the arena. * end of the arena.
*/ */
PIOS_Assert (slot_hdr.state == SLOT_STATE_EMPTY || PIOS_Assert (slot_hdr.state == SLOT_STATE_EMPTY ||
logfs.num_free_slots == 0); logfs->num_free_slots == 0);
switch (slot_hdr.state) { switch (slot_hdr.state) {
case SLOT_STATE_EMPTY: case SLOT_STATE_EMPTY:
logfs.num_free_slots++; logfs->num_free_slots++;
break; break;
case SLOT_STATE_ACTIVE: case SLOT_STATE_ACTIVE:
logfs.num_active_slots++; logfs->num_active_slots++;
break; break;
case SLOT_STATE_RESERVED: case SLOT_STATE_RESERVED:
case SLOT_STATE_OBSOLETE: case SLOT_STATE_OBSOLETE:
@ -464,12 +467,59 @@ static int32_t logfs_mount_log(uint8_t arena_id)
} }
/* Scan is complete, mark the arena mounted */ /* Scan is complete, mark the arena mounted */
logfs.active_arena_id = arena_id; logfs->active_arena_id = arena_id;
logfs.mounted = true; logfs->mounted = true;
return 0; return 0;
} }
static bool PIOS_FLASHFS_Logfs_validate(const struct logfs_state * logfs)
{
return (logfs && (logfs->magic == PIOS_FLASHFS_LOGFS_DEV_MAGIC));
}
#if defined(PIOS_INCLUDE_FREERTOS)
static struct logfs_state * PIOS_FLASHFS_Logfs_alloc(void)
{
struct logfs_state * logfs;
logfs = (struct logfs_state *)pvPortMalloc(sizeof(*logfs));
if (!logfs) return (NULL);
logfs->magic = PIOS_FLASHFS_LOGFS_DEV_MAGIC;
return(logfs);
}
static void PIOS_FLASHFS_Logfs_free(struct logfs_state * logfs)
{
/* Invalidate the magic */
logfs->magic = ~PIOS_FLASHFS_LOGFS_DEV_MAGIC;
vPortFree(logfs);
}
#else
static struct logfs_state pios_flashfs_logfs_devs[PIOS_FLASHFS_LOGFS_MAX_DEVS];
static uint8_t pios_flashfs_logfs_num_devs;
static struct logfs_state * PIOS_FLASHFS_Logfs_alloc(void)
{
struct logfs_state * logfs;
if (pios_flashfs_logfs_num_devs >= PIOS_FLASHFS_LOGFS_MAX_DEVS) {
return (NULL);
}
logfs = &pios_flashfs_logfs_devs[pios_flashfs_logfs_num_devs++];
logfs->magic = PIOS_FLASHFS_LOGFS_DEV_MAGIC;
return (logfs);
}
static void PIOS_FLASHFS_Logfs_free(struct logfs_state * logfs)
{
/* Invalidate the magic */
logfs->magic = ~PIOS_FLASHFS_LOGFS_DEV_MAGIC;
/* Can't free the resources with this simple allocator */
}
#endif
/** /**
* @brief Initialize the flash object setting FS * @brief Initialize the flash object setting FS
* @return 0 if success, -1 if failure * @return 0 if success, -1 if failure
@ -490,15 +540,23 @@ int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t * fs_id, const struct flashfs_logfs_cf
PIOS_Assert(driver->write_data); PIOS_Assert(driver->write_data);
PIOS_Assert(driver->read_data); PIOS_Assert(driver->read_data);
/* Bind configuration parameters to this filesystem instance */
logfs.cfg = cfg; /* filesystem configuration */
logfs.driver = driver; /* lower-level flash driver */
logfs.flash_id = flash_id; /* lower-level flash device id */
logfs.mounted = false;
int8_t rc; int8_t rc;
if (logfs.driver->start_transaction(logfs.flash_id) != 0) { struct logfs_state * logfs;
logfs = (struct logfs_state *) PIOS_FLASHFS_Logfs_alloc();
if (!logfs) {
rc = -1;
goto out_exit;
}
/* Bind configuration parameters to this filesystem instance */
logfs->cfg = cfg; /* filesystem configuration */
logfs->driver = driver; /* lower-level flash driver */
logfs->flash_id = flash_id; /* lower-level flash device id */
logfs->mounted = false;
if (logfs->driver->start_transaction(logfs->flash_id) != 0) {
rc = -1; rc = -1;
goto out_exit; goto out_exit;
} }
@ -507,16 +565,16 @@ int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t * fs_id, const struct flashfs_logfs_cf
int32_t arena_id; int32_t arena_id;
for (uint8_t try = 0; !found && try < 2; try++) { for (uint8_t try = 0; !found && try < 2; try++) {
/* Find the active arena */ /* Find the active arena */
arena_id = logfs_find_active_arena(); arena_id = logfs_find_active_arena(logfs);
if (arena_id >= 0) { if (arena_id >= 0) {
/* Found the active arena */ /* Found the active arena */
found = true; found = true;
break; break;
} else { } else {
/* No active arena found, erase and activate arena 0 */ /* No active arena found, erase and activate arena 0 */
if (logfs_erase_arena(0) != 0) if (logfs_erase_arena(logfs, 0) != 0)
break; break;
if (logfs_activate_arena(0) != 0) if (logfs_activate_arena(logfs, 0) != 0)
break; break;
} }
} }
@ -528,7 +586,7 @@ int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t * fs_id, const struct flashfs_logfs_cf
} }
/* We've found an active arena, mount it */ /* We've found an active arena, mount it */
if (logfs_mount_log(arena_id) != 0) { if (logfs_mount_log(logfs, arena_id) != 0) {
/* Failed to mount the log, something is broken */ /* Failed to mount the log, something is broken */
rc = -3; rc = -3;
goto out_end_trans; goto out_end_trans;
@ -537,32 +595,50 @@ int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t * fs_id, const struct flashfs_logfs_cf
/* Log has been mounted */ /* Log has been mounted */
rc = 0; rc = 0;
*fs_id = (uintptr_t) &logfs; *fs_id = (uintptr_t) logfs;
out_end_trans: out_end_trans:
logfs.driver->end_transaction(logfs.flash_id); logfs->driver->end_transaction(logfs->flash_id);
out_exit:
return rc;
}
int32_t PIOS_FLASHFS_Logfs_Destroy(uintptr_t fs_id)
{
int32_t rc;
struct logfs_state * logfs = (struct logfs_state *)fs_id;
if (!PIOS_FLASHFS_Logfs_validate(logfs)) {
rc = -1;
goto out_exit;
}
PIOS_FLASHFS_Logfs_free(logfs);
rc = 0;
out_exit: out_exit:
return rc; return rc;
} }
/* NOTE: Must be called while holding the flash transaction lock */ /* NOTE: Must be called while holding the flash transaction lock */
static int32_t logfs_garbage_collect (void) { static int32_t logfs_garbage_collect (struct logfs_state * logfs) {
PIOS_Assert (logfs.mounted); PIOS_Assert (logfs->mounted);
/* Source arena is the active arena */ /* Source arena is the active arena */
uint8_t src_arena_id = logfs.active_arena_id; uint8_t src_arena_id = logfs->active_arena_id;
/* Compute destination arena */ /* Compute destination arena */
uint8_t dst_arena_id = (logfs.active_arena_id + 1) % (logfs.cfg->total_fs_size / logfs.cfg->arena_size); uint8_t dst_arena_id = (logfs->active_arena_id + 1) % (logfs->cfg->total_fs_size / logfs->cfg->arena_size);
/* Erase destination arena */ /* Erase destination arena */
if (logfs_erase_arena (dst_arena_id) != 0) { if (logfs_erase_arena (logfs, dst_arena_id) != 0) {
return -1; return -1;
} }
/* Reserve the destination arena so we can start filling it */ /* Reserve the destination arena so we can start filling it */
if (logfs_reserve_arena (dst_arena_id) != 0) { if (logfs_reserve_arena (logfs, dst_arena_id) != 0) {
/* Unable to reserve the arena */ /* Unable to reserve the arena */
return -2; return -2;
} }
@ -570,11 +646,11 @@ static int32_t logfs_garbage_collect (void) {
/* Copy active slots from active arena to destination arena */ /* Copy active slots from active arena to destination arena */
uint16_t dst_slot_id = 1; uint16_t dst_slot_id = 1;
for (uint16_t src_slot_id = 1; for (uint16_t src_slot_id = 1;
src_slot_id < (logfs.cfg->arena_size / logfs.cfg->slot_size); src_slot_id < (logfs->cfg->arena_size / logfs->cfg->slot_size);
src_slot_id++) { src_slot_id++) {
struct slot_header slot_hdr; struct slot_header slot_hdr;
uintptr_t src_addr = logfs_get_addr (src_arena_id, src_slot_id); uintptr_t src_addr = logfs_get_addr (logfs, src_arena_id, src_slot_id);
if (logfs.driver->read_data(logfs.flash_id, if (logfs->driver->read_data(logfs->flash_id,
src_addr, src_addr,
(uint8_t *)&slot_hdr, (uint8_t *)&slot_hdr,
sizeof (slot_hdr)) != 0) { sizeof (slot_hdr)) != 0) {
@ -582,8 +658,9 @@ static int32_t logfs_garbage_collect (void) {
} }
if (slot_hdr.state == SLOT_STATE_ACTIVE) { if (slot_hdr.state == SLOT_STATE_ACTIVE) {
uintptr_t dst_addr = logfs_get_addr (dst_arena_id, dst_slot_id); uintptr_t dst_addr = logfs_get_addr (logfs, dst_arena_id, dst_slot_id);
if (logfs_raw_copy_bytes(src_addr, if (logfs_raw_copy_bytes(logfs,
src_addr,
sizeof(slot_hdr) + slot_hdr.obj_size, sizeof(slot_hdr) + slot_hdr.obj_size,
dst_addr) != 0) { dst_addr) != 0) {
/* Failed to copy all bytes */ /* Failed to copy all bytes */
@ -597,22 +674,22 @@ static int32_t logfs_garbage_collect (void) {
} }
/* Activate the destination arena */ /* Activate the destination arena */
if (logfs_activate_arena (dst_arena_id) != 0) { if (logfs_activate_arena (logfs, dst_arena_id) != 0) {
return -5; return -5;
} }
/* Unmount the source arena */ /* Unmount the source arena */
if (logfs_unmount_log () != 0) { if (logfs_unmount_log (logfs) != 0) {
return -6; return -6;
} }
/* Obsolete the source arena */ /* Obsolete the source arena */
if (logfs_obsolete_arena (src_arena_id) != 0) { if (logfs_obsolete_arena (logfs, src_arena_id) != 0) {
return -7; return -7;
} }
/* Mount the new arena */ /* Mount the new arena */
if (logfs_mount_log (dst_arena_id) != 0) { if (logfs_mount_log (logfs, dst_arena_id) != 0) {
return -8; return -8;
} }
@ -620,7 +697,7 @@ static int32_t logfs_garbage_collect (void) {
} }
/* NOTE: Must be called while holding the flash transaction lock */ /* NOTE: Must be called while holding the flash transaction lock */
static int16_t logfs_object_find_next (struct slot_header * slot_hdr, uint16_t * curr_slot, uint32_t obj_id, uint16_t obj_inst_id) static int16_t logfs_object_find_next (const struct logfs_state * logfs, struct slot_header * slot_hdr, uint16_t * curr_slot, uint32_t obj_id, uint16_t obj_inst_id)
{ {
PIOS_Assert(slot_hdr); PIOS_Assert(slot_hdr);
PIOS_Assert(curr_slot); PIOS_Assert(curr_slot);
@ -629,11 +706,11 @@ static int16_t logfs_object_find_next (struct slot_header * slot_hdr, uint16_t *
if (*curr_slot == 0) *curr_slot = 1; if (*curr_slot == 0) *curr_slot = 1;
for (uint16_t slot_id = *curr_slot; for (uint16_t slot_id = *curr_slot;
slot_id < (logfs.cfg->arena_size / logfs.cfg->slot_size); slot_id < (logfs->cfg->arena_size / logfs->cfg->slot_size);
slot_id++) { slot_id++) {
uintptr_t slot_addr = logfs_get_addr (logfs.active_arena_id, slot_id); uintptr_t slot_addr = logfs_get_addr (logfs, logfs->active_arena_id, slot_id);
if (logfs.driver->read_data(logfs.flash_id, if (logfs->driver->read_data(logfs->flash_id,
slot_addr, slot_addr,
(uint8_t *)slot_hdr, (uint8_t *)slot_hdr,
sizeof (*slot_hdr)) != 0) { sizeof (*slot_hdr)) != 0) {
@ -661,7 +738,7 @@ static int16_t logfs_object_find_next (struct slot_header * slot_hdr, uint16_t *
/* NOTE: Must be called while holding the flash transaction lock */ /* NOTE: Must be called while holding the flash transaction lock */
/* OPTIMIZE: could trust that there is at most one active version of every object and terminate the search when we find one */ /* OPTIMIZE: could trust that there is at most one active version of every object and terminate the search when we find one */
static int8_t logfs_delete_object (uint32_t obj_id, uint16_t obj_inst_id) static int8_t logfs_delete_object (struct logfs_state * logfs, uint32_t obj_id, uint16_t obj_inst_id)
{ {
int8_t rc; int8_t rc;
@ -669,13 +746,13 @@ static int8_t logfs_delete_object (uint32_t obj_id, uint16_t obj_inst_id)
uint16_t curr_slot_id = 0; uint16_t curr_slot_id = 0;
do { do {
struct slot_header slot_hdr; struct slot_header slot_hdr;
switch (logfs_object_find_next (&slot_hdr, &curr_slot_id, obj_id, obj_inst_id)) { switch (logfs_object_find_next (logfs, &slot_hdr, &curr_slot_id, obj_id, obj_inst_id)) {
case 0: case 0:
/* Found a matching slot. Obsolete it. */ /* Found a matching slot. Obsolete it. */
slot_hdr.state = SLOT_STATE_OBSOLETE; slot_hdr.state = SLOT_STATE_OBSOLETE;
uintptr_t slot_addr = logfs_get_addr (logfs.active_arena_id, curr_slot_id); uintptr_t slot_addr = logfs_get_addr (logfs, logfs->active_arena_id, curr_slot_id);
if (logfs.driver->write_data(logfs.flash_id, if (logfs->driver->write_data(logfs->flash_id,
slot_addr, slot_addr,
(uint8_t *)&slot_hdr, (uint8_t *)&slot_hdr,
sizeof(slot_hdr)) != 0) { sizeof(slot_hdr)) != 0) {
@ -683,7 +760,7 @@ static int8_t logfs_delete_object (uint32_t obj_id, uint16_t obj_inst_id)
goto out_exit; goto out_exit;
} }
/* Object has been successfully obsoleted and is no longer active */ /* Object has been successfully obsoleted and is no longer active */
logfs.num_active_slots--; logfs->num_active_slots--;
break; break;
case -1: case -1:
/* Search completed, object not found */ /* Search completed, object not found */
@ -702,27 +779,27 @@ out_exit:
} }
/* NOTE: Must be called while holding the flash transaction lock */ /* NOTE: Must be called while holding the flash transaction lock */
static int8_t logfs_reserve_free_slot (uint16_t * slot_id, struct slot_header * slot_hdr, uint32_t obj_id, uint16_t obj_inst_id, uint16_t obj_size) static int8_t logfs_reserve_free_slot (struct logfs_state * logfs, uint16_t * slot_id, struct slot_header * slot_hdr, uint32_t obj_id, uint16_t obj_inst_id, uint16_t obj_size)
{ {
PIOS_Assert(slot_id); PIOS_Assert(slot_id);
PIOS_Assert(slot_hdr); PIOS_Assert(slot_hdr);
if (logfs.num_free_slots < 1) { if (logfs->num_free_slots < 1) {
/* No free slots to allocate */ /* No free slots to allocate */
return -1; return -1;
} }
if (obj_size > (logfs.cfg->slot_size - sizeof (slot_hdr))) { if (obj_size > (logfs->cfg->slot_size - sizeof (slot_hdr))) {
/* This object is too big for the slot */ /* This object is too big for the slot */
return -2; return -2;
} }
uint16_t candidate_slot_id = (logfs.cfg->arena_size / logfs.cfg->slot_size) - logfs.num_free_slots; uint16_t candidate_slot_id = (logfs->cfg->arena_size / logfs->cfg->slot_size) - logfs->num_free_slots;
PIOS_Assert(candidate_slot_id > 0); PIOS_Assert(candidate_slot_id > 0);
uintptr_t slot_addr = logfs_get_addr (logfs.active_arena_id, candidate_slot_id); uintptr_t slot_addr = logfs_get_addr (logfs, logfs->active_arena_id, candidate_slot_id);
if (logfs.driver->read_data(logfs.flash_id, if (logfs->driver->read_data(logfs->flash_id,
slot_addr, slot_addr,
(uint8_t *)slot_hdr, (uint8_t *)slot_hdr,
sizeof (*slot_hdr)) != 0) { sizeof (*slot_hdr)) != 0) {
@ -742,7 +819,7 @@ static int8_t logfs_reserve_free_slot (uint16_t * slot_id, struct slot_header *
slot_hdr->obj_inst_id = obj_inst_id; slot_hdr->obj_inst_id = obj_inst_id;
slot_hdr->obj_size = obj_size; slot_hdr->obj_size = obj_size;
if (logfs.driver->write_data(logfs.flash_id, if (logfs->driver->write_data(logfs->flash_id,
slot_addr, slot_addr,
(uint8_t *)slot_hdr, (uint8_t *)slot_hdr,
sizeof(*slot_hdr)) != 0) { sizeof(*slot_hdr)) != 0) {
@ -751,33 +828,33 @@ static int8_t logfs_reserve_free_slot (uint16_t * slot_id, struct slot_header *
} }
/* FIXME: If the header write (above) failed, may have partially written data, thus corrupting that slot but we would have missed decrementing this counter */ /* FIXME: If the header write (above) failed, may have partially written data, thus corrupting that slot but we would have missed decrementing this counter */
logfs.num_free_slots--; logfs->num_free_slots--;
*slot_id = candidate_slot_id; *slot_id = candidate_slot_id;
return 0; return 0;
} }
/* NOTE: Must be called while holding the flash transaction lock */ /* NOTE: Must be called while holding the flash transaction lock */
static int8_t logfs_append_to_log (uint32_t obj_id, uint16_t obj_inst_id, uint8_t * obj_data, uint16_t obj_size) static int8_t logfs_append_to_log (struct logfs_state * logfs, uint32_t obj_id, uint16_t obj_inst_id, uint8_t * obj_data, uint16_t obj_size)
{ {
/* Reserve a free slot for our new object */ /* Reserve a free slot for our new object */
uint16_t free_slot_id; uint16_t free_slot_id;
struct slot_header slot_hdr; struct slot_header slot_hdr;
if (logfs_reserve_free_slot (&free_slot_id, &slot_hdr, obj_id, obj_inst_id, obj_size) != 0) { if (logfs_reserve_free_slot (logfs, &free_slot_id, &slot_hdr, obj_id, obj_inst_id, obj_size) != 0) {
/* Failed to reserve a free slot */ /* Failed to reserve a free slot */
return -1; return -1;
} }
/* Compute slot address */ /* Compute slot address */
uintptr_t slot_addr = logfs_get_addr (logfs.active_arena_id, free_slot_id); uintptr_t slot_addr = logfs_get_addr (logfs, logfs->active_arena_id, free_slot_id);
/* Write the data into the reserved slot, starting after the slot header */ /* Write the data into the reserved slot, starting after the slot header */
uintptr_t slot_offset = sizeof(slot_hdr); uintptr_t slot_offset = sizeof(slot_hdr);
while (obj_size > 0) { while (obj_size > 0) {
/* Individual writes must fit entirely within a single page buffer. */ /* Individual writes must fit entirely within a single page buffer. */
uint16_t page_remaining = logfs.cfg->page_size - (slot_offset % logfs.cfg->page_size); uint16_t page_remaining = logfs->cfg->page_size - (slot_offset % logfs->cfg->page_size);
uint16_t write_size = MIN(obj_size, page_remaining); uint16_t write_size = MIN(obj_size, page_remaining);
if (logfs.driver->write_data (logfs.flash_id, if (logfs->driver->write_data (logfs->flash_id,
slot_addr + slot_offset, slot_addr + slot_offset,
obj_data, obj_data,
write_size) != 0) { write_size) != 0) {
@ -793,7 +870,7 @@ static int8_t logfs_append_to_log (uint32_t obj_id, uint16_t obj_inst_id, uint8_
/* Mark this slot active in one atomic step */ /* Mark this slot active in one atomic step */
slot_hdr.state = SLOT_STATE_ACTIVE; slot_hdr.state = SLOT_STATE_ACTIVE;
if (logfs.driver->write_data (logfs.flash_id, if (logfs->driver->write_data (logfs->flash_id,
slot_addr, slot_addr,
(uint8_t *)&slot_hdr, (uint8_t *)&slot_hdr,
sizeof(slot_hdr)) != 0) { sizeof(slot_hdr)) != 0) {
@ -802,7 +879,7 @@ static int8_t logfs_append_to_log (uint32_t obj_id, uint16_t obj_inst_id, uint8_
} }
/* Object has been successfully written to the slot */ /* Object has been successfully written to the slot */
logfs.num_active_slots++; logfs->num_active_slots++;
return 0; return 0;
} }
@ -822,26 +899,34 @@ static int8_t logfs_append_to_log (uint32_t obj_id, uint16_t obj_inst_id, uint8_
* @param[in] obj_data Contents of the object being saved * @param[in] obj_data Contents of the object being saved
* @param[in] obj_size Size of the object being saved * @param[in] obj_size Size of the object being saved
* @return 0 if success or error code * @return 0 if success or error code
* @retval -1 if failed to start transaction * @retval -1 if fs_id is not a valid filesystem instance
* @retval -2 if failure to delete any previous versions of the object * @retval -2 if failed to start transaction
* @retval -3 if filesystem is entirely full and garbage collection won't help * @retval -3 if failure to delete any previous versions of the object
* @retval -4 if garbage collection failed * @retval -4 if filesystem is entirely full and garbage collection won't help
* @retval -5 if filesystem is full even after garbage collection should have freed space * @retval -5 if garbage collection failed
* @retval -6 if writing the new object to the filesystem failed * @retval -6 if filesystem is full even after garbage collection should have freed space
* @retval -7 if writing the new object to the filesystem failed
*/ */
int32_t PIOS_FLASHFS_ObjSave(__attribute__((unused)) uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t * obj_data, uint16_t obj_size) 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)
{ {
int8_t rc; int8_t rc;
PIOS_Assert(obj_size <= (logfs.cfg->slot_size - sizeof(struct slot_header))); struct logfs_state * logfs = (struct logfs_state *)fs_id;
if (logfs.driver->start_transaction(logfs.flash_id) != 0) { if (!PIOS_FLASHFS_Logfs_validate(logfs)) {
rc = -1; rc = -1;
goto out_exit; goto out_exit;
} }
if (logfs_delete_object (obj_id, obj_inst_id) != 0) { PIOS_Assert(obj_size <= (logfs->cfg->slot_size - sizeof(struct slot_header)));
if (logfs->driver->start_transaction(logfs->flash_id) != 0) {
rc = -2; rc = -2;
goto out_exit;
}
if (logfs_delete_object (logfs, obj_id, obj_inst_id) != 0) {
rc = -3;
goto out_end_trans; goto out_end_trans;
} }
@ -851,36 +936,36 @@ int32_t PIOS_FLASHFS_ObjSave(__attribute__((unused)) uint32_t fs_id, uint32_t ob
*/ */
/* Check if the arena is entirely full. */ /* Check if the arena is entirely full. */
if (logfs_fs_is_full()) { if (logfs_fs_is_full(logfs)) {
/* Note: Filesystem Full means we're full of *active* records so gc won't help at all. */ /* Note: Filesystem Full means we're full of *active* records so gc won't help at all. */
rc = -3; rc = -4;
goto out_end_trans; goto out_end_trans;
} }
/* Is garbage collection required? */ /* Is garbage collection required? */
if (logfs_log_is_full()) { if (logfs_log_is_full(logfs)) {
/* Note: Log Full means the log is full but may contain obsolete slots so gc may free some space */ /* Note: Log Full means the log is full but may contain obsolete slots so gc may free some space */
if (logfs_garbage_collect() != 0) { if (logfs_garbage_collect(logfs) != 0) {
rc = -4; rc = -5;
goto out_end_trans; goto out_end_trans;
} }
/* Check one more time just to be sure we actually free'd some space */ /* Check one more time just to be sure we actually free'd some space */
if (logfs_log_is_full()) { if (logfs_log_is_full(logfs)) {
/* /*
* Log is still full even after gc! * Log is still full even after gc!
* NOTE: This should not happen since the filesystem wasn't full * NOTE: This should not happen since the filesystem wasn't full
* when we checked above so gc should have helped. * when we checked above so gc should have helped.
*/ */
PIOS_DEBUG_Assert(0); PIOS_DEBUG_Assert(0);
rc = -5; rc = -6;
goto out_end_trans; goto out_end_trans;
} }
} }
/* We have room for our new object. Append it to the log. */ /* We have room for our new object. Append it to the log. */
if (logfs_append_to_log(obj_id, obj_inst_id, obj_data, obj_size) != 0) { if (logfs_append_to_log(logfs, obj_id, obj_inst_id, obj_data, obj_size) != 0) {
/* Error during append */ /* Error during append */
rc = -6; rc = -7;
goto out_end_trans; goto out_end_trans;
} }
@ -888,7 +973,7 @@ int32_t PIOS_FLASHFS_ObjSave(__attribute__((unused)) uint32_t fs_id, uint32_t ob
rc = 0; rc = 0;
out_end_trans: out_end_trans:
logfs.driver->end_transaction(logfs.flash_id); logfs->driver->end_transaction(logfs->flash_id);
out_exit: out_exit:
return rc; return rc;
@ -902,47 +987,55 @@ out_exit:
* @param[in] obj_data Buffer to hold the contents of the loaded object * @param[in] obj_data Buffer to hold the contents of the loaded object
* @param[in] obj_size Size of the object to be loaded * @param[in] obj_size Size of the object to be loaded
* @return 0 if success or error code * @return 0 if success or error code
* @retval -1 if failed to start transaction * @retval -1 if fs_id is not a valid filesystem instance
* @retval -2 if object not found in filesystem * @retval -2 if failed to start transaction
* @retval -3 if object size in filesystem does not exactly match buffer size * @retval -3 if object not found in filesystem
* @retval -4 if reading the object data from flash fails * @retval -4 if object size in filesystem does not exactly match buffer size
* @retval -5 if reading the object data from flash fails
*/ */
int32_t PIOS_FLASHFS_ObjLoad(__attribute__((unused)) uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t * obj_data, uint16_t obj_size) 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)
{ {
int8_t rc; int8_t rc;
PIOS_Assert(obj_size <= (logfs.cfg->slot_size - sizeof(struct slot_header))); struct logfs_state * logfs = (struct logfs_state *)fs_id;
if (logfs.driver->start_transaction(logfs.flash_id) != 0) { if (!PIOS_FLASHFS_Logfs_validate(logfs)) {
rc = -1; rc = -1;
goto out_exit; goto out_exit;
} }
PIOS_Assert(obj_size <= (logfs->cfg->slot_size - sizeof(struct slot_header)));
if (logfs->driver->start_transaction(logfs->flash_id) != 0) {
rc = -2;
goto out_exit;
}
/* Find the object in the log */ /* Find the object in the log */
uint16_t slot_id = 0; uint16_t slot_id = 0;
struct slot_header slot_hdr; struct slot_header slot_hdr;
if (logfs_object_find_next (&slot_hdr, &slot_id, obj_id, obj_inst_id) != 0) { if (logfs_object_find_next (logfs, &slot_hdr, &slot_id, obj_id, obj_inst_id) != 0) {
/* Object does not exist in fs */ /* Object does not exist in fs */
rc = -2; rc = -3;
goto out_end_trans; goto out_end_trans;
} }
/* Sanity check what we've found */ /* Sanity check what we've found */
if (slot_hdr.obj_size != obj_size) { if (slot_hdr.obj_size != obj_size) {
/* Object sizes don't match. Not safe to copy contents. */ /* Object sizes don't match. Not safe to copy contents. */
rc = -3; rc = -4;
goto out_end_trans; goto out_end_trans;
} }
/* Read the contents of the object from the log */ /* Read the contents of the object from the log */
if (obj_size > 0) { if (obj_size > 0) {
uintptr_t slot_addr = logfs_get_addr (logfs.active_arena_id, slot_id); uintptr_t slot_addr = logfs_get_addr (logfs, logfs->active_arena_id, slot_id);
if (logfs.driver->read_data(logfs.flash_id, if (logfs->driver->read_data(logfs->flash_id,
slot_addr + sizeof(slot_hdr), slot_addr + sizeof(slot_hdr),
(uint8_t *)obj_data, (uint8_t *)obj_data,
obj_size) != 0) { obj_size) != 0) {
/* Failed to read object data from the log */ /* Failed to read object data from the log */
rc = -4; rc = -5;
goto out_end_trans; goto out_end_trans;
} }
} }
@ -951,7 +1044,7 @@ int32_t PIOS_FLASHFS_ObjLoad(__attribute__((unused)) uint32_t fs_id, uint32_t ob
rc = 0; rc = 0;
out_end_trans: out_end_trans:
logfs.driver->end_transaction(logfs.flash_id); logfs->driver->end_transaction(logfs->flash_id);
out_exit: out_exit:
return rc; return rc;
@ -963,20 +1056,28 @@ out_exit:
* @param[in] obj UAVObject ID of the object to delete * @param[in] obj UAVObject ID of the object to delete
* @param[in] obj_inst_id The instance of the object to delete * @param[in] obj_inst_id The instance of the object to delete
* @return 0 if success or error code * @return 0 if success or error code
* @retval -1 if failed to start transaction * @retval -1 if fs_id is not a valid filesystem instance
* @retval -2 if failed to delete the object from the filesystem * @retval -2 if failed to start transaction
* @retval -3 if failed to delete the object from the filesystem
*/ */
int32_t PIOS_FLASHFS_ObjDelete(__attribute__((unused)) uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id) int32_t PIOS_FLASHFS_ObjDelete(uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id)
{ {
int8_t rc; int8_t rc;
if (logfs.driver->start_transaction(logfs.flash_id) != 0) { struct logfs_state * logfs = (struct logfs_state *)fs_id;
if (!PIOS_FLASHFS_Logfs_validate(logfs)) {
rc = -1; rc = -1;
goto out_exit; goto out_exit;
} }
if (logfs_delete_object (obj_id, obj_inst_id) != 0) { if (logfs->driver->start_transaction(logfs->flash_id) != 0) {
rc = -2; rc = -2;
goto out_exit;
}
if (logfs_delete_object (logfs, obj_id, obj_inst_id) != 0) {
rc = -3;
goto out_end_trans; goto out_end_trans;
} }
@ -984,7 +1085,7 @@ int32_t PIOS_FLASHFS_ObjDelete(__attribute__((unused)) uint32_t fs_id, uint32_t
rc = 0; rc = 0;
out_end_trans: out_end_trans:
logfs.driver->end_transaction(logfs.flash_id); logfs->driver->end_transaction(logfs->flash_id);
out_exit: out_exit:
return rc; return rc;
@ -994,46 +1095,54 @@ out_exit:
* @brief Erases all filesystem arenas and activate the first arena * @brief Erases all filesystem arenas and activate the first arena
* @param[in] fs_id The filesystem to use for this action * @param[in] fs_id The filesystem to use for this action
* @return 0 if success or error code * @return 0 if success or error code
* @retval -1 if failed to start transaction * @retval -1 if fs_id is not a valid filesystem instance
* @retval -2 if failed to erase all arenas * @retval -2 if failed to start transaction
* @retval -3 if failed to activate arena 0 * @retval -3 if failed to erase all arenas
* @retval -4 if failed to mount arena 0 * @retval -4 if failed to activate arena 0
* @retval -5 if failed to mount arena 0
*/ */
int32_t PIOS_FLASHFS_Format(__attribute__((unused)) uint32_t fs_id) int32_t PIOS_FLASHFS_Format(uintptr_t fs_id)
{ {
int32_t rc; int32_t rc;
if (logfs.mounted) { struct logfs_state * logfs = (struct logfs_state *)fs_id;
logfs_unmount_log();
}
if (logfs.driver->start_transaction(logfs.flash_id) != 0) { if (!PIOS_FLASHFS_Logfs_validate(logfs)) {
rc = -1; rc = -1;
goto out_exit; goto out_exit;
} }
if (logfs_erase_all_arenas() != 0) { if (logfs->mounted) {
rc = -2; logfs_unmount_log(logfs);
goto out_end_trans;
} }
/* Reinitialize arena 0 */ if (logfs->driver->start_transaction(logfs->flash_id) != 0) {
if (logfs_activate_arena(0) != 0) { rc = -2;
goto out_exit;
}
if (logfs_erase_all_arenas(logfs) != 0) {
rc = -3; rc = -3;
goto out_end_trans; goto out_end_trans;
} }
/* Mount arena 0 */ /* Reinitialize arena 0 */
if (logfs_mount_log(0) != 0) { if (logfs_activate_arena(logfs, 0) != 0) {
rc = -4; rc = -4;
goto out_end_trans; goto out_end_trans;
} }
/* Mount arena 0 */
if (logfs_mount_log(logfs, 0) != 0) {
rc = -5;
goto out_end_trans;
}
/* Chip erased and log remounted successfully */ /* Chip erased and log remounted successfully */
rc = 0; rc = 0;
out_end_trans: out_end_trans:
logfs.driver->end_transaction(logfs.flash_id); logfs->driver->end_transaction(logfs->flash_id);
out_exit: out_exit:
return rc; return rc;

View File

@ -29,9 +29,9 @@
#include <stdint.h> #include <stdint.h>
int32_t PIOS_FLASHFS_Format(uint32_t fs_id); int32_t PIOS_FLASHFS_Format(uintptr_t fs_id);
int32_t PIOS_FLASHFS_ObjSave(uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t * obj_data, uint16_t obj_size); 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);
int32_t PIOS_FLASHFS_ObjLoad(uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t * obj_data, uint16_t obj_size); 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);
int32_t PIOS_FLASHFS_ObjDelete(uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id); int32_t PIOS_FLASHFS_ObjDelete(uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id);
#endif /* PIOS_FLASHFS_H */ #endif /* PIOS_FLASHFS_H */

View File

@ -43,4 +43,6 @@ struct flashfs_logfs_cfg {
int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t * fs_id, const struct flashfs_logfs_cfg * cfg, const struct pios_flash_driver * driver, uintptr_t flash_id); int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t * fs_id, const struct flashfs_logfs_cfg * cfg, const struct pios_flash_driver * driver, uintptr_t flash_id);
int32_t PIOS_FLASHFS_Logfs_Destroy(uintptr_t fs_id);
#endif /* PIOS_FLASHFS_LOGFS_PRIV_H */ #endif /* PIOS_FLASHFS_LOGFS_PRIV_H */

View File

@ -279,12 +279,15 @@
#endif #endif
#ifdef PIOS_INCLUDE_FLASH #ifdef PIOS_INCLUDE_FLASH
/* #define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS */ /* #define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS */
/* #define FLASH_FREERTOS */ /* #define FLASH_FREERTOS */
#include <pios_flash.h> #include <pios_flash.h>
#include <pios_flashfs.h> #include <pios_flashfs.h>
#endif #endif
/* driver for storage on internal flash */
/* #define PIOS_INCLUDE_FLASH_INTERNAL */
#ifdef PIOS_INCLUDE_FLASH_EEPROM #ifdef PIOS_INCLUDE_FLASH_EEPROM
#include <pios_eeprom.h> #include <pios_eeprom.h>
#endif #endif

View File

@ -2,7 +2,7 @@ MEMORY
{ {
BL_FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x03000 - 0x00080 BL_FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x03000 - 0x00080
BD_INFO (r) : ORIGIN = 0x08003000 - 0x80, LENGTH = 0x00080 BD_INFO (r) : ORIGIN = 0x08003000 - 0x80, LENGTH = 0x00080
FLASH (rx) : ORIGIN = 0x08003000, LENGTH = 0x20000 - 0x03000 - 0x00400 FLASH (rx) : ORIGIN = 0x08003000, LENGTH = 0x20000 - 0x03000 - 0x04000
EE_FLASH (rw) : ORIGIN = 0x0801FC00, LENGTH = 0x00400 EE_FLASH (rw) : ORIGIN = 0x0801C000, LENGTH = 0x04000
SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x05000 SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x05000
} }

View File

@ -0,0 +1,291 @@
/**
******************************************************************************
*
* @file pios_flash_internal.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
* @brief brief goes here.
* --
* @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
* (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
* 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.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "pios.h"
#ifdef PIOS_INCLUDE_FLASH_INTERNAL
#include "stm32f10x_flash.h"
#include "pios_flash_internal_priv.h"
#include "pios_flash.h"
#include <stdbool.h>
struct device_flash_sector {
uint32_t start;
uint32_t size;
uint16_t st_sector;
};
static bool PIOS_Flash_Internal_GetSectorInfo(uint32_t address, uint8_t * sector_number, uint32_t *sector_start, uint32_t *sector_size)
{
uint16_t sector = (address - 0x08000000) / 1024;
if(sector <= 127) {
/* address lies within this sector */
*sector_number = sector;
*sector_start = sector * 1024 + 0x08000000;
*sector_size = 1024;
return (true);
}
return (false);
}
enum pios_internal_flash_dev_magic {
PIOS_INTERNAL_FLASH_DEV_MAGIC = 0x33445902,
};
struct pios_internal_flash_dev {
enum pios_internal_flash_dev_magic magic;
#if defined(PIOS_INCLUDE_FREERTOS)
xSemaphoreHandle transaction_lock;
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
};
static bool PIOS_Flash_Internal_Validate(struct pios_internal_flash_dev * flash_dev) {
return (flash_dev && (flash_dev->magic == PIOS_INTERNAL_FLASH_DEV_MAGIC));
}
#if defined(PIOS_INCLUDE_FREERTOS)
static struct pios_internal_flash_dev * PIOS_Flash_Internal_alloc(void)
{
struct pios_internal_flash_dev * flash_dev;
flash_dev = (struct pios_internal_flash_dev *)pvPortMalloc(sizeof(* flash_dev));
if (!flash_dev) return (NULL);
flash_dev->magic = PIOS_INTERNAL_FLASH_DEV_MAGIC;
return(flash_dev);
}
#else
static struct pios_internal_flash_dev pios_internal_flash_devs[PIOS_INTERNAL_FLASH_MAX_DEVS];
static uint8_t pios_internal_flash_num_devs;
static struct pios_internal_flash_dev * PIOS_Flash_Internal_alloc(void)
{
struct pios_internal_flash_dev * flash_dev;
if (pios_internal_flash_num_devs >= PIOS_INTERNAL_FLASH_MAX_DEVS) {
return (NULL);
}
flash_dev = &pios_internal_flash_devs[pios_internal_flash_num_devs++];
flash_dev->magic = PIOS_INTERNAL_FLASH_DEV_MAGIC;
return (flash_dev);
}
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
int32_t PIOS_Flash_Internal_Init(uintptr_t * flash_id, __attribute__((unused)) const struct pios_flash_internal_cfg * cfg)
{
struct pios_internal_flash_dev * flash_dev;
flash_dev = PIOS_Flash_Internal_alloc();
if (flash_dev == NULL)
return -1;
#if defined(PIOS_INCLUDE_FREERTOS)
flash_dev->transaction_lock = xSemaphoreCreateMutex();
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
*flash_id = (uintptr_t) flash_dev;
return 0;
}
/**********************************
*
* Provide a PIOS flash driver API
*
*********************************/
#include "pios_flash.h"
static int32_t PIOS_Flash_Internal_StartTransaction(uintptr_t flash_id)
{
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
if (!PIOS_Flash_Internal_Validate(flash_dev))
return -1;
#if defined(PIOS_INCLUDE_FREERTOS)
if (xSemaphoreTake(flash_dev->transaction_lock, portMAX_DELAY) != pdTRUE)
return -2;
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
/* Unlock the internal flash so we can write to it */
FLASH_Unlock();
return 0;
}
static int32_t PIOS_Flash_Internal_EndTransaction(uintptr_t flash_id)
{
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
if (!PIOS_Flash_Internal_Validate(flash_dev))
return -1;
#if defined(PIOS_INCLUDE_FREERTOS)
if (xSemaphoreGive(flash_dev->transaction_lock) != pdTRUE)
return -2;
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
/* Lock the internal flash again so we can no longer write to it */
FLASH_Lock();
return 0;
}
static int32_t PIOS_Flash_Internal_EraseSector(uintptr_t flash_id, uint32_t addr)
{
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
if (!PIOS_Flash_Internal_Validate(flash_dev))
return -1;
uint8_t sector_number;
uint32_t sector_start;
uint32_t sector_size;
if (!PIOS_Flash_Internal_GetSectorInfo(addr,
&sector_number,
&sector_start,
&sector_size)) {
/* We're asking for an invalid flash address */
return -2;
}
if (FLASH_ErasePage(sector_start) != FLASH_COMPLETE)
return -3;
return 0;
}
static int32_t PIOS_Flash_Internal_WriteData(uintptr_t flash_id, uint32_t addr, uint8_t * data, uint16_t len)
{
PIOS_Assert(data);
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
if (!PIOS_Flash_Internal_Validate(flash_dev))
return -1;
uint8_t sector_number;
uint32_t sector_start;
uint32_t sector_size;
uint32_t hword_data;
uint32_t offset;
/* Ensure that the base address is in a valid sector */
if (!PIOS_Flash_Internal_GetSectorInfo(addr,
&sector_number,
&sector_start,
&sector_size)) {
/* We're asking for an invalid flash address */
return -2;
}
/* Ensure that the entire write occurs within the same sector */
if ((uintptr_t)addr + len > sector_start + sector_size) {
/* Write crosses the end of the sector */
return -3;
}
/* Write the data */
uint32_t temp_addr = addr;
uint16_t numberOfhWords = len / 2;
uint16_t x = 0;
FLASH_Status status;
for ( x = 0; x < numberOfhWords; ++x) {
offset = 2 * x;
hword_data = (data[offset + 1] << 8) | data[offset];
if(hword_data != *(uint16_t *)(temp_addr + offset)) {
status = FLASH_ProgramHalfWord(temp_addr + offset, hword_data);
} else {
status = FLASH_COMPLETE;
}
PIOS_Assert(status == FLASH_COMPLETE);
}
uint16_t mod = len % 2;
if(mod == 1) {
offset = 2 * x;
hword_data = 0xFF00 | data[offset];
if(hword_data != *(uint16_t *)(temp_addr + offset)) {
status = FLASH_ProgramHalfWord(temp_addr + offset, hword_data);
} else {
status = FLASH_COMPLETE;
}
PIOS_Assert(status == FLASH_COMPLETE);
}
return 0;
}
static int32_t PIOS_Flash_Internal_ReadData(uintptr_t flash_id, uint32_t addr, uint8_t * data, uint16_t len)
{
PIOS_Assert(data);
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
if (!PIOS_Flash_Internal_Validate(flash_dev))
return -1;
uint8_t sector_number;
uint32_t sector_start;
uint32_t sector_size;
/* Ensure that the base address is in a valid sector */
if (!PIOS_Flash_Internal_GetSectorInfo(addr,
&sector_number,
&sector_start,
&sector_size)) {
/* We're asking for an invalid flash address */
return -2;
}
/* Ensure that the entire read occurs within the same sector */
if ((uintptr_t)addr + len > sector_start + sector_size) {
/* Read crosses the end of the sector */
return -3;
}
/* Read the data into the buffer directly */
memcpy(data, (void *)addr, len);
return 0;
}
/* Provide a flash driver to external drivers */
const struct pios_flash_driver pios_internal_flash_driver = {
.start_transaction = PIOS_Flash_Internal_StartTransaction,
.end_transaction = PIOS_Flash_Internal_EndTransaction,
.erase_sector = PIOS_Flash_Internal_EraseSector,
.write_data = PIOS_Flash_Internal_WriteData,
.read_data = PIOS_Flash_Internal_ReadData,
};
#endif /* PIOS_INCLUDE_FLASH_INTERNAL */

View File

@ -276,16 +276,20 @@ static int32_t PIOS_Flash_Internal_WriteData(uintptr_t flash_id, uint32_t addr,
/* Write crosses the end of the sector */ /* Write crosses the end of the sector */
return -3; return -3;
} }
FLASH_Status status;
for (uint16_t i = 0; i < len/4; i++){
uint32_t data_word = *(uint32_t *)(data + i*4);
status = FLASH_ProgramWord(addr + i * 4, data_word);
if(status != FLASH_COMPLETE)
return -4;
}
/* Write the data */ /* Write the data */
for (uint16_t i = 0; i < len; i++) { for (uint16_t i = len - len % 4; i < len; i++) {
FLASH_Status status;
/*
* This is inefficient. Should try to do word writes.
* Not sure if word writes need to be aligned though.
*/
status = FLASH_ProgramByte(addr + i, data[i]); status = FLASH_ProgramByte(addr + i, data[i]);
PIOS_Assert(status == FLASH_COMPLETE); if(status != FLASH_COMPLETE)
return -5;
} }
return 0; return 0;

View File

@ -168,6 +168,20 @@ void PIOS_USBHOOK_RegisterEpOutCallback(uint8_t epnum, uint16_t max_len, pios_us
/* /*
* FIXME do not hardcode endpoint type * FIXME do not hardcode endpoint type
*/ */
/*
* Make sure we refuse OUT transactions until we explicitly
* connect a receive buffer with PIOS_USBHOOK_EndpointRx().
*
* Without this, the ST USB code will receive on this endpoint
* and blindly write the data to a NULL pointer which will
* have the side effect of placing the internal flash into an
* errored state. Address 0x0000_0000 is aliased into internal
* flash via the "Section 2.4 Boot configuration" BOOT0/1 pins.
*/
DCD_SetEPStatus(&pios_usb_otg_core_handle,
epnum,
USB_OTG_EP_RX_NAK);
} }
extern void PIOS_USBHOOK_DeRegisterEpOutCallback(uint8_t epnum) extern void PIOS_USBHOOK_DeRegisterEpOutCallback(uint8_t epnum)

View File

@ -107,9 +107,10 @@
/* #define PIOS_INCLUDE_SDCARD */ /* #define PIOS_INCLUDE_SDCARD */
/* #define LOG_FILENAME "startup.log" */ /* #define LOG_FILENAME "startup.log" */
#define PIOS_INCLUDE_FLASH #define PIOS_INCLUDE_FLASH
#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS #define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS
/* #define FLASH_FREERTOS */ /* #define FLASH_FREERTOS */
/* #define PIOS_INCLUDE_FLASH_EEPROM */ /* #define PIOS_INCLUDE_FLASH_EEPROM */
/* #define PIOS_INCLUDE_FLASH_INTERNAL */
/* PIOS radio modules */ /* PIOS radio modules */
/* #define PIOS_INCLUDE_RFM22B */ /* #define PIOS_INCLUDE_RFM22B */

View File

@ -76,6 +76,8 @@ uint32_t pios_com_hkosd_id;
uint32_t pios_usb_rctx_id; uint32_t pios_usb_rctx_id;
uintptr_t pios_uavo_settings_fs_id;
/** /**
* Configuration for MPU6000 chip * Configuration for MPU6000 chip
*/ */
@ -169,13 +171,12 @@ void PIOS_Board_Init(void) {
#endif #endif
uintptr_t flash_id; uintptr_t flash_id;
uintptr_t fs_id;
switch(bdinfo->board_rev) { switch(bdinfo->board_rev) {
case BOARD_REVISION_CC: case BOARD_REVISION_CC:
if (PIOS_Flash_Jedec_Init(&flash_id, pios_spi_flash_accel_id, 1)) { if (PIOS_Flash_Jedec_Init(&flash_id, pios_spi_flash_accel_id, 1)) {
PIOS_DEBUG_Assert(0); PIOS_DEBUG_Assert(0);
} }
if (PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_w25x_cfg, &pios_jedec_flash_driver, flash_id)) { if (PIOS_FLASHFS_Logfs_Init(&pios_uavo_settings_fs_id, &flashfs_w25x_cfg, &pios_jedec_flash_driver, flash_id)) {
PIOS_DEBUG_Assert(0); PIOS_DEBUG_Assert(0);
} }
break; break;
@ -183,7 +184,7 @@ void PIOS_Board_Init(void) {
if (PIOS_Flash_Jedec_Init(&flash_id, pios_spi_flash_accel_id, 0)) { if (PIOS_Flash_Jedec_Init(&flash_id, pios_spi_flash_accel_id, 0)) {
PIOS_DEBUG_Assert(0); PIOS_DEBUG_Assert(0);
} }
if (PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_m25p_cfg, &pios_jedec_flash_driver, flash_id)) { if (PIOS_FLASHFS_Logfs_Init(&pios_uavo_settings_fs_id, &flashfs_m25p_cfg, &pios_jedec_flash_driver, flash_id)) {
PIOS_DEBUG_Assert(0); PIOS_DEBUG_Assert(0);
} }
break; break;
@ -205,7 +206,7 @@ void PIOS_Board_Init(void) {
PIOS_IAP_ReadBootCmd(1) == PIOS_IAP_CLEAR_FLASH_CMD_1 && PIOS_IAP_ReadBootCmd(1) == PIOS_IAP_CLEAR_FLASH_CMD_1 &&
PIOS_IAP_ReadBootCmd(2) == PIOS_IAP_CLEAR_FLASH_CMD_2) PIOS_IAP_ReadBootCmd(2) == PIOS_IAP_CLEAR_FLASH_CMD_2)
{ {
PIOS_FLASHFS_Format(fs_id); PIOS_FLASHFS_Format(pios_uavo_settings_fs_id);
PIOS_IAP_WriteBootCmd(0,0); PIOS_IAP_WriteBootCmd(0,0);
PIOS_IAP_WriteBootCmd(1,0); PIOS_IAP_WriteBootCmd(1,0);
PIOS_IAP_WriteBootCmd(2,0); PIOS_IAP_WriteBootCmd(2,0);

View File

@ -12,13 +12,28 @@ MODEL_SUFFIX := _PX
OPENOCD_JTAG_CONFIG := stlink-v2.cfg OPENOCD_JTAG_CONFIG := stlink-v2.cfg
OPENOCD_CONFIG := stm32f1x.stlink.cfg OPENOCD_CONFIG := stm32f1x.stlink.cfg
# Flash memory map for OPLM:
# Sector start size use
# 0 0x0800 0000 1k BL
# 1 0x0800 0400 1k BL
# .. ..
# 10 0x0800 2C00 1k BL
# 11 0x0800 3000 1k FW
# 12 0x0800 1000 1k FW
# .. ..
# 125 0x0801 F400 1k FW
# 126 0x0801 F800 1k EE
# 127 0x0801 FC00 1k EE
# Note: These must match the values in link_$(BOARD)_memory.ld # Note: These must match the values in link_$(BOARD)_memory.ld
BL_BANK_BASE := 0x08000000 # Start of bootloader flash BL_BANK_BASE := 0x08000000 # Start of bootloader flash
BL_BANK_SIZE := 0x00003000 # Should include BD_INFO region BL_BANK_SIZE := 0x00003000 # Should include BD_INFO region
FW_BANK_BASE := 0x08003000 # Start of firmware flash FW_BANK_BASE := 0x08003000 # Start of firmware flash
FW_BANK_SIZE := 0x0001CC00 # Should include FW_DESC_SIZE FW_BANK_SIZE := 0x0001CC00 # Should include FW_DESC_SIZE
EE_BANK_BASE := 0x0801FC00 # EEPROM storage area FW_BANK_SIZE := 0x00019000 # Should include FW_DESC_SIZE
EE_BANK_SIZE := 0x00000400 # Size of EEPROM storage area EE_BANK_BASE := 0x0801C000 # EEPROM storage area
EE_BANK_SIZE := 0x00004000 # Size of EEPROM storage area
FW_DESC_SIZE := 0x00000064 FW_DESC_SIZE := 0x00000064

View File

@ -99,6 +99,29 @@ const struct pios_led_cfg * PIOS_BOARD_HW_DEFS_GetLedCfg (__attribute__((unused)
#endif /* PIOS_INCLUDE_LED */ #endif /* PIOS_INCLUDE_LED */
#if defined(PIOS_INCLUDE_FLASH)
#include "pios_flashfs_logfs_priv.h"
#include "pios_flash_internal_priv.h"
static const struct pios_flash_internal_cfg flash_internal_cfg = {
};
static const struct flashfs_logfs_cfg flashfs_internal_cfg = {
.fs_magic = 0x99abcfef,
.total_fs_size = EE_BANK_SIZE, /* 2K bytes (2x1KB sectors) */
.arena_size = 0x00002000, /* 4 * slot size = 1K bytes = 1 sector */
.slot_size = 0x00000100, /* 256 bytes */
.start_offset = EE_BANK_BASE, /* start after the bootloader */
.sector_size = 0x00000400, /* 1K bytes */
.page_size = 0x00000400, /* 1K bytes */
};
#include "pios_flash.h"
#endif /* PIOS_INCLUDE_FLASH */
#if defined(PIOS_INCLUDE_SPI) #if defined(PIOS_INCLUDE_SPI)
#include <pios_spi_priv.h> #include <pios_spi_priv.h>

View File

@ -106,10 +106,11 @@
/* #define PIOS_OVERO_SPI */ /* #define PIOS_OVERO_SPI */
/* #define PIOS_INCLUDE_SDCARD */ /* #define PIOS_INCLUDE_SDCARD */
/* #define LOG_FILENAME "startup.log" */ /* #define LOG_FILENAME "startup.log" */
/* #define PIOS_INCLUDE_FLASH */ #define PIOS_INCLUDE_FLASH
/* #define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS */ #define PIOS_INCLUDE_FLASH_INTERNAL
#define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS
/* #define FLASH_FREERTOS */ /* #define FLASH_FREERTOS */
#define PIOS_INCLUDE_FLASH_EEPROM //#define PIOS_INCLUDE_FLASH_EEPROM
/* PIOS radio modules */ /* PIOS radio modules */
#define PIOS_INCLUDE_RFM22B #define PIOS_INCLUDE_RFM22B

View File

@ -73,6 +73,8 @@ uint32_t pios_com_radio_id = 0;
uint8_t *pios_uart_rx_buffer; uint8_t *pios_uart_rx_buffer;
uint8_t *pios_uart_tx_buffer; uint8_t *pios_uart_tx_buffer;
uintptr_t pios_uavo_settings_fs_id;
/** /**
* PIOS_Board_Init() * PIOS_Board_Init()
* initializes all the core subsystems on this specific hardware * initializes all the core subsystems on this specific hardware
@ -83,6 +85,12 @@ void PIOS_Board_Init(void) {
/* Delay system */ /* Delay system */
PIOS_DELAY_Init(); PIOS_DELAY_Init();
#ifdef PIOS_INCLUDE_FLASH_LOGFS_SETTINGS
uintptr_t flash_id;
PIOS_Flash_Internal_Init(&flash_id, &flash_internal_cfg);
PIOS_FLASHFS_Logfs_Init(&pios_uavo_settings_fs_id, &flashfs_internal_cfg, &pios_internal_flash_driver, flash_id);
#endif
/* Initialize UAVObject libraries */ /* Initialize UAVObject libraries */
EventDispatcherInitialize(); EventDispatcherInitialize();
UAVObjInitialize(); UAVObjInitialize();
@ -109,8 +117,6 @@ void PIOS_Board_Init(void) {
#endif /* PIOS_INCLUDE_LED */ #endif /* PIOS_INCLUDE_LED */
OPLinkSettingsData oplinkSettings; OPLinkSettingsData oplinkSettings;
#if defined(PIOS_INCLUDE_FLASH_EEPROM)
PIOS_EEPROM_Init(&pios_eeprom_cfg);
/* IAP System Setup */ /* IAP System Setup */
PIOS_IAP_Init(); PIOS_IAP_Init();
@ -120,7 +126,8 @@ void PIOS_Board_Init(void) {
PIOS_IAP_ReadBootCmd(2) == PIOS_IAP_CLEAR_FLASH_CMD_2) { PIOS_IAP_ReadBootCmd(2) == PIOS_IAP_CLEAR_FLASH_CMD_2) {
OPLinkSettingsGet(&oplinkSettings); OPLinkSettingsGet(&oplinkSettings);
OPLinkSettingsSetDefaults(&oplinkSettings,0); OPLinkSettingsSetDefaults(&oplinkSettings,0);
PIOS_EEPROM_Save((uint8_t*)&oplinkSettings, sizeof(OPLinkSettingsData)); OPLinkSettingsSet(&oplinkSettings);
//PIOS_EEPROM_Save((uint8_t*)&oplinkSettings, sizeof(OPLinkSettingsData));
for (uint32_t i = 0; i < 10; i++) { for (uint32_t i = 0; i < 10; i++) {
PIOS_DELAY_WaitmS(100); PIOS_DELAY_WaitmS(100);
PIOS_LED_Toggle(PIOS_LED_HEARTBEAT); PIOS_LED_Toggle(PIOS_LED_HEARTBEAT);
@ -129,15 +136,8 @@ void PIOS_Board_Init(void) {
PIOS_IAP_WriteBootCmd(1,0); PIOS_IAP_WriteBootCmd(1,0);
PIOS_IAP_WriteBootCmd(2,0); PIOS_IAP_WriteBootCmd(2,0);
} }
/* Read the settings from flash. */
/* NOTE: We probably need to save/restore the objID here incase the object changed but the size doesn't */
if (PIOS_EEPROM_Load((uint8_t*)&oplinkSettings, sizeof(OPLinkSettingsData)) == 0)
OPLinkSettingsSet(&oplinkSettings);
else
OPLinkSettingsGet(&oplinkSettings);
#else
OPLinkSettingsGet(&oplinkSettings); OPLinkSettingsGet(&oplinkSettings);
#endif /* PIOS_INCLUDE_FLASH_EEPROM */
/* Initialize the task monitor */ /* Initialize the task monitor */
if (PIOS_TASK_MONITOR_Initialize(TASKINFO_RUNNING_NUMELEM)) { if (PIOS_TASK_MONITOR_Initialize(TASKINFO_RUNNING_NUMELEM)) {

View File

@ -14,18 +14,19 @@ OPENOCD_CONFIG := stm32f4xx.stlink.cfg
#OPENOCD_CONFIG := stm32f4xx.cfg #OPENOCD_CONFIG := stm32f4xx.cfg
# Flash memory map for OSD: # Flash memory map for OSD:
# Sector start size use # Sector start size use
# 0 0x0800 0000 16k BL # 0 0x0800 0000 16k BL
# 1 0x0800 4000 16k BL # 1 0x0800 4000 16k BL
# 2 0x0800 8000 16k EE # 2 0x0800 8000 16k EE
# 3 0x0800 C000 16k EE # 3 0x0800 C000 16k EE
# 4 0x0801 0000 64k Unused # 4 0x0801 0000 64k Unused
# 5 0x0802 0000 128k FW # 5 0x0802 0000 128k FW
# 6 0x0804 0000 128k FW # 6 0x0804 0000 128k FW
# 7 0x0806 0000 128k FW # 7 0x0806 0000 128k FW
# 8 0x0808 0000 128k Unused # 8 0x0808 0000 128k Unused
# .. .. # 9 0x080A 0000 128k Unused
# 11 0x080E 0000 128k Unused # 10 0x080C 0000 128k Unused ..
# 11 0x080E 0000 128k Unused
# Note: These must match the values in link_$(BOARD)_memory.ld # Note: These must match the values in link_$(BOARD)_memory.ld
BL_BANK_BASE := 0x08000000 # Start of bootloader flash BL_BANK_BASE := 0x08000000 # Start of bootloader flash

View File

@ -99,10 +99,6 @@ else
SRC += $(OPTESTS)/test_common.c SRC += $(OPTESTS)/test_common.c
SRC += $(OPTESTS)/$(TESTAPP).c SRC += $(OPTESTS)/$(TESTAPP).c
endif endif
CDEFS += -DEE_BANK_BASE=$(EE_BANK_BASE)
CDEFS += -DEE_BANK_SIZE=$(EE_BANK_SIZE)
# Optional component libraries # Optional component libraries
include $(PIOS)/common/libraries/dosfs/library.mk include $(PIOS)/common/libraries/dosfs/library.mk

View File

@ -109,7 +109,7 @@
#define LOG_FILENAME "startup.log" #define LOG_FILENAME "startup.log"
#define PIOS_INCLUDE_FLASH #define PIOS_INCLUDE_FLASH
#define PIOS_INCLUDE_FLASH_INTERNAL #define PIOS_INCLUDE_FLASH_INTERNAL
#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS #define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS
/* #define FLASH_FREERTOS */ /* #define FLASH_FREERTOS */
/* #define PIOS_INCLUDE_FLASH_EEPROM */ /* #define PIOS_INCLUDE_FLASH_EEPROM */

View File

@ -105,6 +105,8 @@ uint32_t pios_com_gps_id;
uint32_t pios_com_telem_usb_id; uint32_t pios_com_telem_usb_id;
uint32_t pios_com_telem_rf_id; uint32_t pios_com_telem_rf_id;
uintptr_t pios_uavo_settings_fs_id;
/** /**
* TIM3 is triggered by the HSYNC signal into its ETR line and will divide the * TIM3 is triggered by the HSYNC signal into its ETR line and will divide the
* APB1_CLOCK to generate a pixel clock that is used by the SPI CLK lines. * APB1_CLOCK to generate a pixel clock that is used by the SPI CLK lines.
@ -162,11 +164,10 @@ void PIOS_Board_Init(void) {
#endif #endif
#endif /* PIOS_INCLUDE_SPI */ #endif /* PIOS_INCLUDE_SPI */
#ifdef PIOS_INCLUDE_FLASH_SECTOR_SETTINGS #ifdef PIOS_INCLUDE_FLASH_LOGFS_SETTINGS
uintptr_t flash_id; uintptr_t flash_id;
uintptr_t fs_id;
PIOS_Flash_Internal_Init(&flash_id, &flash_internal_cfg); PIOS_Flash_Internal_Init(&flash_id, &flash_internal_cfg);
PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_internal_cfg, &pios_internal_flash_driver, flash_id); PIOS_FLASHFS_Logfs_Init(&pios_uavo_settings_fs_id, &flashfs_internal_cfg, &pios_internal_flash_driver, flash_id);
#elif !defined(PIOS_USE_SETTINGS_ON_SDCARD) #elif !defined(PIOS_USE_SETTINGS_ON_SDCARD)
#error No setting storage specified. (define PIOS_USE_SETTINGS_ON_SDCARD or INCLUDE_FLASH_SECTOR_SETTINGS) #error No setting storage specified. (define PIOS_USE_SETTINGS_ON_SDCARD or INCLUDE_FLASH_SECTOR_SETTINGS)
#endif #endif

View File

@ -12,11 +12,31 @@ MODEL_SUFFIX :=
OPENOCD_JTAG_CONFIG := stlink-v2.cfg OPENOCD_JTAG_CONFIG := stlink-v2.cfg
OPENOCD_CONFIG := stm32f4xx.stlink.cfg OPENOCD_CONFIG := stm32f4xx.stlink.cfg
# Flash memory map for Revolution:
# Sector start size use
# 0 0x0800 0000 16k BL
# 1 0x0800 4000 16k BL
# 2 0x0800 8000 16k EE
# 3 0x0800 C000 16k EE
# 4 0x0801 0000 64k Unused
# 5 0x0802 0000 128k FW
# 6 0x0804 0000 128k FW
# 7 0x0806 0000 128k FW
# 8 0x0808 0000 128k Unused
# 9 0x080A 0000 128k Unused
# 10 0x080C 0000 128k Unused ..
# 11 0x080E 0000 128k Unused
# Note: These must match the values in link_$(BOARD)_memory.ld # Note: These must match the values in link_$(BOARD)_memory.ld
BL_BANK_BASE := 0x08000000 # Start of bootloader flash BL_BANK_BASE := 0x08000000 # Start of bootloader flash
BL_BANK_SIZE := 0x00008000 # Should include BD_INFO region BL_BANK_SIZE := 0x00008000 # Should include BD_INFO region
# Leave the remaining 16KB and 64KB sectors for other uses # 16KB for settings storage
EE_BANK_BASE := 0x08008000 # EEPROM storage area
EE_BANK_SIZE := 0x00008000 # Size of EEPROM storage area
# Leave the remaining 64KB sectors for other uses
FW_BANK_BASE := 0x08020000 # Start of firmware flash FW_BANK_BASE := 0x08020000 # Start of firmware flash
FW_BANK_SIZE := 0x00060000 # Should include FW_DESC_SIZE FW_BANK_SIZE := 0x00060000 # Should include FW_DESC_SIZE

View File

@ -665,8 +665,9 @@ const struct pios_rfm22b_cfg * PIOS_BOARD_HW_DEFS_GetRfm22Cfg (uint32_t board_re
#if defined(PIOS_INCLUDE_FLASH) #if defined(PIOS_INCLUDE_FLASH)
#include "pios_flashfs_logfs_priv.h" #include "pios_flashfs_logfs_priv.h"
#include "pios_flash_jedec_priv.h" #include "pios_flash_jedec_priv.h"
#include "pios_flash_internal_priv.h"
static const struct flashfs_logfs_cfg flashfs_m25p_cfg = { static const struct flashfs_logfs_cfg flashfs_external_cfg = {
.fs_magic = 0x99abceef, .fs_magic = 0x99abceef,
.total_fs_size = 0x00200000, /* 2M bytes (32 sectors = entire chip) */ .total_fs_size = 0x00200000, /* 2M bytes (32 sectors = entire chip) */
.arena_size = 0x00010000, /* 256 * slot size */ .arena_size = 0x00010000, /* 256 * slot size */
@ -677,6 +678,20 @@ static const struct flashfs_logfs_cfg flashfs_m25p_cfg = {
.page_size = 0x00000100, /* 256 bytes */ .page_size = 0x00000100, /* 256 bytes */
}; };
static const struct pios_flash_internal_cfg flash_internal_cfg = { };
static const struct flashfs_logfs_cfg flashfs_internal_cfg = {
.fs_magic = 0x99abcfef,
.total_fs_size = EE_BANK_SIZE, /* 32K bytes (2x16KB sectors) */
.arena_size = 0x00004000, /* 64 * slot size = 16K bytes = 1 sector */
.slot_size = 0x00000100, /* 256 bytes */
.start_offset = EE_BANK_BASE, /* start after the bootloader */
.sector_size = 0x00004000, /* 16K bytes */
.page_size = 0x00004000, /* 16K bytes */
};
#endif /* PIOS_INCLUDE_FLASH */ #endif /* PIOS_INCLUDE_FLASH */
#include <pios_usart_priv.h> #include <pios_usart_priv.h>

View File

@ -107,7 +107,8 @@
/* #define PIOS_INCLUDE_SDCARD */ /* #define PIOS_INCLUDE_SDCARD */
/* #define LOG_FILENAME "startup.log" */ /* #define LOG_FILENAME "startup.log" */
#define PIOS_INCLUDE_FLASH #define PIOS_INCLUDE_FLASH
#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS #define PIOS_INCLUDE_FLASH_INTERNAL
#define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS
#define FLASH_FREERTOS #define FLASH_FREERTOS
/* #define PIOS_INCLUDE_FLASH_EEPROM */ /* #define PIOS_INCLUDE_FLASH_EEPROM */

View File

@ -236,6 +236,9 @@ uint32_t pios_com_hkosd_id = 0;
uint32_t pios_rfm22b_id = 0; uint32_t pios_rfm22b_id = 0;
#endif #endif
uintptr_t pios_uavo_settings_fs_id;
uintptr_t pios_user_fs_id;
/* /*
* Setup a com port based on the passed cfg, driver and buffer sizes. tx size of -1 make the port rx only * Setup a com port based on the passed cfg, driver and buffer sizes. tx size of -1 make the port rx only
*/ */
@ -349,13 +352,23 @@ void PIOS_Board_Init(void) {
#if defined(PIOS_INCLUDE_FLASH) #if defined(PIOS_INCLUDE_FLASH)
/* Connect flash to the appropriate interface and configure it */ /* Connect flash to the appropriate interface and configure it */
uintptr_t flash_id; uintptr_t flash_id;
// initialize the internal settings storage flash
if (PIOS_Flash_Internal_Init(&flash_id, &flash_internal_cfg)) {
PIOS_DEBUG_Assert(0);
}
if (PIOS_FLASHFS_Logfs_Init(&pios_uavo_settings_fs_id, &flashfs_internal_cfg, &pios_internal_flash_driver, flash_id)) {
PIOS_DEBUG_Assert(0);
}
// Initialize the external USER flash
if (PIOS_Flash_Jedec_Init(&flash_id, pios_spi_telem_flash_id, 1)) { if (PIOS_Flash_Jedec_Init(&flash_id, pios_spi_telem_flash_id, 1)) {
PIOS_DEBUG_Assert(0); PIOS_DEBUG_Assert(0);
} }
uintptr_t fs_id; if (PIOS_FLASHFS_Logfs_Init(&pios_user_fs_id, &flashfs_external_cfg, &pios_jedec_flash_driver, flash_id)) {
if (PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_m25p_cfg, &pios_jedec_flash_driver, flash_id)) { PIOS_DEBUG_Assert(0);
PIOS_DEBUG_Assert(0);
} }
#endif #endif
@ -370,7 +383,7 @@ void PIOS_Board_Init(void) {
PIOS_IAP_ReadBootCmd(1) == PIOS_IAP_CLEAR_FLASH_CMD_1 && PIOS_IAP_ReadBootCmd(1) == PIOS_IAP_CLEAR_FLASH_CMD_1 &&
PIOS_IAP_ReadBootCmd(2) == PIOS_IAP_CLEAR_FLASH_CMD_2) PIOS_IAP_ReadBootCmd(2) == PIOS_IAP_CLEAR_FLASH_CMD_2)
{ {
PIOS_FLASHFS_Format(fs_id); PIOS_FLASHFS_Format(pios_uavo_settings_fs_id);
PIOS_IAP_WriteBootCmd(0,0); PIOS_IAP_WriteBootCmd(0,0);
PIOS_IAP_WriteBootCmd(1,0); PIOS_IAP_WriteBootCmd(1,0);
PIOS_IAP_WriteBootCmd(2,0); PIOS_IAP_WriteBootCmd(2,0);

View File

@ -16,7 +16,12 @@ OPENOCD_CONFIG := stm32f4xx.stlink.cfg
BL_BANK_BASE := 0x08000000 # Start of bootloader flash BL_BANK_BASE := 0x08000000 # Start of bootloader flash
BL_BANK_SIZE := 0x00008000 # Should include BD_INFO region BL_BANK_SIZE := 0x00008000 # Should include BD_INFO region
# Leave the remaining 16KB and 64KB sectors for other uses # 16KB for settings storage
EE_BANK_BASE := 0x08008000 # EEPROM storage area
EE_BANK_SIZE := 0x00008000 # Size of EEPROM storage area
# Leave the remaining 64KB sectors for other uses
FW_BANK_BASE := 0x08020000 # Start of firmware flash FW_BANK_BASE := 0x08020000 # Start of firmware flash
FW_BANK_SIZE := 0x00060000 # Should include FW_DESC_SIZE FW_BANK_SIZE := 0x00060000 # Should include FW_DESC_SIZE

View File

@ -448,16 +448,31 @@ void PIOS_SPI_flash_irq_handler(void)
#if defined(PIOS_INCLUDE_FLASH) #if defined(PIOS_INCLUDE_FLASH)
#include "pios_flashfs_logfs_priv.h" #include "pios_flashfs_logfs_priv.h"
#include "pios_flash_jedec_priv.h" #include "pios_flash_jedec_priv.h"
#include "pios_flash_internal_priv.h"
static const struct flashfs_logfs_cfg flashfs_m25p_cfg = { static const struct flashfs_logfs_cfg flashfs_external_cfg = {
.fs_magic = 0x99abceef, .fs_magic = 0x99abceef,
.total_fs_size = 0x00200000, /* 2M bytes (32 sectors = entire chip) */ .total_fs_size = 0x00200000, /* 2M bytes (32 sectors = entire chip) */
.arena_size = 0x00010000, /* 256 * slot size */ .arena_size = 0x00010000, /* 256 * slot size */
.slot_size = 0x00000100, /* 256 bytes */ .slot_size = 0x00000100, /* 256 bytes */
.start_offset = 0, /* start at the beginning of the chip */ .start_offset = 0, /* start at the beginning of the chip */
.sector_size = 0x00010000, /* 64K bytes */ .sector_size = 0x00010000, /* 64K bytes */
.page_size = 0x00000100, /* 256 bytes */ .page_size = 0x00000100, /* 256 bytes */
};
static const struct pios_flash_internal_cfg flash_internal_cfg = { };
static const struct flashfs_logfs_cfg flashfs_internal_cfg = {
.fs_magic = 0x99abcfef,
.total_fs_size = EE_BANK_SIZE, /* 32K bytes (2x16KB sectors) */
.arena_size = 0x00004000, /* 64 * slot size = 16K bytes = 1 sector */
.slot_size = 0x00000100, /* 256 bytes */
.start_offset = EE_BANK_BASE, /* start after the bootloader */
.sector_size = 0x00004000, /* 16K bytes */
.page_size = 0x00004000, /* 16K bytes */
}; };
#endif /* PIOS_INCLUDE_FLASH */ #endif /* PIOS_INCLUDE_FLASH */

View File

@ -107,7 +107,8 @@
/* #define PIOS_INCLUDE_SDCARD */ /* #define PIOS_INCLUDE_SDCARD */
/* #define LOG_FILENAME "startup.log" */ /* #define LOG_FILENAME "startup.log" */
#define PIOS_INCLUDE_FLASH #define PIOS_INCLUDE_FLASH
#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS #define PIOS_INCLUDE_FLASH_INTERNAL
#define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS
#define FLASH_FREERTOS #define FLASH_FREERTOS
/* #define PIOS_INCLUDE_FLASH_EEPROM */ /* #define PIOS_INCLUDE_FLASH_EEPROM */

View File

@ -306,6 +306,10 @@ uint32_t pios_com_bridge_id = 0;
uint32_t pios_com_overo_id = 0; uint32_t pios_com_overo_id = 0;
uint32_t pios_com_hkosd_id = 0; uint32_t pios_com_hkosd_id = 0;
uintptr_t pios_uavo_settings_fs_id;
uintptr_t pios_user_fs_id;
/* /*
* Setup a com port based on the passed cfg, driver and buffer sizes. tx size of -1 make the port rx only * Setup a com port based on the passed cfg, driver and buffer sizes. tx size of -1 make the port rx only
*/ */
@ -377,6 +381,18 @@ void PIOS_Board_Init(void) {
PIOS_LED_Init(&pios_led_cfg); PIOS_LED_Init(&pios_led_cfg);
/* Connect flash to the appropriate interface and configure it */
uintptr_t flash_id;
// initialize the internal settings storage flash
if (PIOS_Flash_Internal_Init(&flash_id, &flash_internal_cfg)) {
PIOS_DEBUG_Assert(0);
}
if (PIOS_FLASHFS_Logfs_Init(&pios_uavo_settings_fs_id, &flashfs_internal_cfg, &pios_internal_flash_driver, flash_id)) {
PIOS_DEBUG_Assert(0);
}
/* Set up the SPI interface to the accelerometer*/ /* Set up the SPI interface to the accelerometer*/
if (PIOS_SPI_Init(&pios_spi_accel_id, &pios_spi_accel_cfg)) { if (PIOS_SPI_Init(&pios_spi_accel_id, &pios_spi_accel_cfg)) {
PIOS_DEBUG_Assert(0); PIOS_DEBUG_Assert(0);
@ -391,22 +407,20 @@ void PIOS_Board_Init(void) {
if (PIOS_SPI_Init(&pios_spi_flash_id, &pios_spi_flash_cfg)) { if (PIOS_SPI_Init(&pios_spi_flash_id, &pios_spi_flash_cfg)) {
PIOS_DEBUG_Assert(0); PIOS_DEBUG_Assert(0);
} }
/* Connect flash to the appropriate interface and configure it */ /* Connect flash to the appropriate interface and configure it */
uintptr_t flash_id;
if (PIOS_Flash_Jedec_Init(&flash_id, pios_spi_flash_id, 0)) { if (PIOS_Flash_Jedec_Init(&flash_id, pios_spi_flash_id, 0)) {
PIOS_DEBUG_Assert(0); PIOS_DEBUG_Assert(0);
} }
#else #else
/* Connect flash to the appropriate interface and configure it */ /* Connect flash to the appropriate interface and configure it */
uintptr_t flash_id;
if (PIOS_Flash_Jedec_Init(&flash_id, pios_spi_accel_id, 1)) { if (PIOS_Flash_Jedec_Init(&flash_id, pios_spi_accel_id, 1)) {
PIOS_DEBUG_Assert(0); PIOS_DEBUG_Assert(0);
} }
#endif #endif
uintptr_t fs_id; if (PIOS_FLASHFS_Logfs_Init(&pios_user_fs_id, &flashfs_external_cfg, &pios_jedec_flash_driver, flash_id)) {
if (PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_m25p_cfg, &pios_jedec_flash_driver, flash_id)) { PIOS_DEBUG_Assert(0);
PIOS_DEBUG_Assert(0); }
}
#if defined(PIOS_INCLUDE_RTC) #if defined(PIOS_INCLUDE_RTC)
PIOS_RTC_Init(&pios_rtc_main_cfg); PIOS_RTC_Init(&pios_rtc_main_cfg);
@ -419,7 +433,7 @@ void PIOS_Board_Init(void) {
PIOS_IAP_ReadBootCmd(1) == PIOS_IAP_CLEAR_FLASH_CMD_1 && PIOS_IAP_ReadBootCmd(1) == PIOS_IAP_CLEAR_FLASH_CMD_1 &&
PIOS_IAP_ReadBootCmd(2) == PIOS_IAP_CLEAR_FLASH_CMD_2) PIOS_IAP_ReadBootCmd(2) == PIOS_IAP_CLEAR_FLASH_CMD_2)
{ {
PIOS_FLASHFS_Format(fs_id); PIOS_FLASHFS_Format(pios_uavo_settings_fs_id);
PIOS_IAP_WriteBootCmd(0,0); PIOS_IAP_WriteBootCmd(0,0);
PIOS_IAP_WriteBootCmd(1,0); PIOS_IAP_WriteBootCmd(1,0);
PIOS_IAP_WriteBootCmd(2,0); PIOS_IAP_WriteBootCmd(2,0);

View File

@ -91,7 +91,7 @@
#define PIOS_INCLUDE_SETTINGS #define PIOS_INCLUDE_SETTINGS
#define PIOS_INCLUDE_FLASH #define PIOS_INCLUDE_FLASH
/* A really shitty setting saving implementation */ /* A really shitty setting saving implementation */
//#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS //#define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS
/* Other Interfaces */ /* Other Interfaces */
//#define PIOS_INCLUDE_I2C_ESC //#define PIOS_INCLUDE_I2C_ESC

View File

@ -74,6 +74,8 @@ uint32_t pios_com_telem_usb_id = 0;
uint32_t pios_com_telem_rf_id = 0; uint32_t pios_com_telem_rf_id = 0;
uint32_t pios_com_bridge_id = 0; uint32_t pios_com_bridge_id = 0;
uintptr_t pios_uavo_settings_fs_id;
/* /*
* Setup a com port based on the passed cfg, driver and buffer sizes. tx size of -1 make the port rx only * Setup a com port based on the passed cfg, driver and buffer sizes. tx size of -1 make the port rx only
*/ */

View File

@ -0,0 +1,3 @@
#include <stdlib.h>
#define pvPortMalloc(xSize) (malloc(xSize))
#define vPortFree(pv) (free(pv))

View File

@ -1,9 +1,14 @@
#ifndef PIOS_H #ifndef PIOS_H
#define PIOS_H #define PIOS_H
/* PIOS board specific feature selection */ /* PIOS Feature Selection */
#include "pios_config.h" #include "pios_config.h"
#ifdef PIOS_INCLUDE_FREERTOS
/* FreeRTOS Includes */
#include "FreeRTOS.h"
#endif
#ifdef PIOS_INCLUDE_FLASH #ifdef PIOS_INCLUDE_FLASH
#include <pios_flash.h> #include <pios_flash.h>
#include <pios_flashfs.h> #include <pios_flashfs.h>

View File

@ -3,5 +3,7 @@
/* Enable/Disable PiOS modules */ /* Enable/Disable PiOS modules */
#define PIOS_INCLUDE_FLASH #define PIOS_INCLUDE_FLASH
//#define PIOS_FLASHFS_LOGFS_MAX_DEVS 5
#define PIOS_INCLUDE_FREERTOS
#endif /* PIOS_CONFIG_H */ #endif /* PIOS_CONFIG_H */

View File

@ -2,7 +2,7 @@
#include <stdio.h> /* fopen/fread/fwrite/fseek */ #include <stdio.h> /* fopen/fread/fwrite/fseek */
#include <assert.h> /* assert */ #include <assert.h> /* assert */
#include <string.h> /* memset */ #include <string.h> /* memset */
#include <unistd.h>
#include <stdbool.h> #include <stdbool.h>
#include "pios_flash_ut_priv.h" #include "pios_flash_ut_priv.h"
@ -55,6 +55,25 @@ int32_t PIOS_Flash_UT_Init(uintptr_t * flash_id, const struct pios_flash_ut_cfg
return 0; return 0;
} }
int32_t PIOS_Flash_UT_Destroy(uintptr_t flash_id) {
/* Check inputs */
assert(flash_id);
struct flash_ut_dev * flash_dev = (void*)flash_id;
if (flash_dev->flash_file == NULL) {
return -1;
}
fclose(flash_dev->flash_file);
free(flash_dev);
unlink (FLASH_IMAGE_FILE);
return 0;
}
/********************************** /**********************************
* *
* Provide a PIOS flash driver API * Provide a PIOS flash driver API

View File

@ -7,6 +7,7 @@ struct pios_flash_ut_cfg {
int32_t PIOS_Flash_UT_Init(uintptr_t * flash_id, const struct pios_flash_ut_cfg * cfg); int32_t PIOS_Flash_UT_Init(uintptr_t * flash_id, const struct pios_flash_ut_cfg * cfg);
int32_t PIOS_Flash_UT_Destroy(uintptr_t flash_id);
extern const struct pios_flash_driver pios_ut_flash_driver; extern const struct pios_flash_driver pios_ut_flash_driver;
#if !defined(FLASH_IMAGE_FILE) #if !defined(FLASH_IMAGE_FILE)

View File

@ -13,7 +13,8 @@ extern struct pios_flash_ut_cfg flash_config;
#include "pios_flashfs_logfs_priv.h" #include "pios_flashfs_logfs_priv.h"
extern struct flashfs_logfs_cfg flashfs_config; extern struct flashfs_logfs_cfg flashfs_config_partition_a;
extern struct flashfs_logfs_cfg flashfs_config_partition_b;
#include "pios_flashfs.h" /* PIOS_FLASHFS_* */ #include "pios_flashfs.h" /* PIOS_FLASHFS_* */
@ -30,6 +31,9 @@ extern struct flashfs_logfs_cfg flashfs_config;
#define OBJ3_ID 0x99999999 #define OBJ3_ID 0x99999999
#define OBJ3_SIZE (256 - 12) // leave room for the slot header #define OBJ3_SIZE (256 - 12) // leave room for the slot header
#define OBJ4_ID 0x90901111
#define OBJ4_SIZE (768) // only fits in partition b slots
// To use a test fixture, derive a class from testing::Test. // To use a test fixture, derive a class from testing::Test.
class LogfsTestRaw : public testing::Test { class LogfsTestRaw : public testing::Test {
protected: protected:
@ -62,6 +66,11 @@ protected:
for (uint32_t i = 0; i < sizeof(obj3); i++) { for (uint32_t i = 0; i < sizeof(obj3); i++) {
obj3[i] = 0x30 + (i % 10); obj3[i] = 0x30 + (i % 10);
} }
/* Set up obj4 */
for (uint32_t i = 0; i < sizeof(obj4); i++) {
obj4[i] = 0x40 + (i % 10);
}
} }
virtual void TearDown() { virtual void TearDown() {
@ -72,11 +81,13 @@ protected:
unsigned char obj1_alt[OBJ1_SIZE]; unsigned char obj1_alt[OBJ1_SIZE];
unsigned char obj2[OBJ2_SIZE]; unsigned char obj2[OBJ2_SIZE];
unsigned char obj3[OBJ3_SIZE]; unsigned char obj3[OBJ3_SIZE];
unsigned char obj4[OBJ4_SIZE];
}; };
TEST_F(LogfsTestRaw, FlashInit) { TEST_F(LogfsTestRaw, FlashInit) {
uintptr_t flash_id; uintptr_t flash_id;
EXPECT_EQ(0, PIOS_Flash_UT_Init(&flash_id, &flash_config)); EXPECT_EQ(0, PIOS_Flash_UT_Init(&flash_id, &flash_config));
PIOS_Flash_UT_Destroy(flash_id);
} }
TEST_F(LogfsTestRaw, LogfsInit) { TEST_F(LogfsTestRaw, LogfsInit) {
@ -84,7 +95,9 @@ TEST_F(LogfsTestRaw, LogfsInit) {
EXPECT_EQ(0, PIOS_Flash_UT_Init(&flash_id, &flash_config)); EXPECT_EQ(0, PIOS_Flash_UT_Init(&flash_id, &flash_config));
uintptr_t fs_id; uintptr_t fs_id;
EXPECT_EQ(0, PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_config, &pios_ut_flash_driver, flash_id)); EXPECT_EQ(0, PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_config_partition_a, &pios_ut_flash_driver, flash_id));
PIOS_FLASHFS_Logfs_Destroy(fs_id);
PIOS_Flash_UT_Destroy(flash_id);
} }
class LogfsTestCooked : public LogfsTestRaw { class LogfsTestCooked : public LogfsTestRaw {
@ -94,14 +107,33 @@ protected:
LogfsTestRaw::SetUp(); LogfsTestRaw::SetUp();
/* Init the flash and the flashfs so we don't need to repeat this in every test */ /* Init the flash and the flashfs so we don't need to repeat this in every test */
uintptr_t flash_id;
EXPECT_EQ(0, PIOS_Flash_UT_Init(&flash_id, &flash_config)); EXPECT_EQ(0, PIOS_Flash_UT_Init(&flash_id, &flash_config));
EXPECT_EQ(0, PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_config, &pios_ut_flash_driver, flash_id)); EXPECT_EQ(0, PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_config_partition_a, &pios_ut_flash_driver, flash_id));
} }
virtual void TearDown() {
PIOS_FLASHFS_Logfs_Destroy(fs_id);
PIOS_Flash_UT_Destroy(flash_id);
}
uintptr_t flash_id;
uintptr_t fs_id; uintptr_t fs_id;
}; };
TEST_F(LogfsTestCooked, BadIdLogfsFormat) {
EXPECT_EQ(-1, PIOS_FLASHFS_Format(fs_id + 1));
}
TEST_F(LogfsTestCooked, BadIdSave) {
EXPECT_EQ(-1, PIOS_FLASHFS_ObjSave(fs_id + 1, OBJ1_ID, 0, obj1, sizeof(obj1)));
}
TEST_F(LogfsTestCooked, BadIdLoad) {
unsigned char obj1_check[OBJ1_SIZE];
memset(obj1_check, 0, sizeof(obj1_check));
EXPECT_EQ(-1, PIOS_FLASHFS_ObjLoad(fs_id + 1, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
}
TEST_F(LogfsTestCooked, LogfsFormat) { TEST_F(LogfsTestCooked, LogfsFormat) {
EXPECT_EQ(0, PIOS_FLASHFS_Format(fs_id)); EXPECT_EQ(0, PIOS_FLASHFS_Format(fs_id));
} }
@ -129,7 +161,7 @@ TEST_F(LogfsTestCooked, WriteVerifyDeleteVerifyOne) {
EXPECT_EQ(0, PIOS_FLASHFS_ObjDelete(fs_id, OBJ1_ID, 0)); EXPECT_EQ(0, PIOS_FLASHFS_ObjDelete(fs_id, OBJ1_ID, 0));
EXPECT_EQ(-2, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check))); EXPECT_EQ(-3, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
} }
TEST_F(LogfsTestCooked, WriteTwoVerifyOneA) { TEST_F(LogfsTestCooked, WriteTwoVerifyOneA) {
@ -170,7 +202,7 @@ TEST_F(LogfsTestCooked, WriteVerifyZeroLength) {
} }
TEST_F(LogfsTestCooked, WriteMaxSize) { TEST_F(LogfsTestCooked, WriteMaxSize) {
/* Write a zero length object */ /* Write a max length object */
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ3_ID, 0, obj3, sizeof(obj3))); EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ3_ID, 0, obj3, sizeof(obj3)));
} }
@ -178,7 +210,7 @@ TEST_F(LogfsTestCooked, ReadNonexistent) {
/* Read back a zero length object -- basically an existence check */ /* Read back a zero length object -- basically an existence check */
unsigned char obj1_check[OBJ1_SIZE]; unsigned char obj1_check[OBJ1_SIZE];
memset(obj1_check, 0, sizeof(obj1_check)); memset(obj1_check, 0, sizeof(obj1_check));
EXPECT_EQ(-2, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check))); EXPECT_EQ(-3, PIOS_FLASHFS_ObjLoad(fs_id, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
} }
TEST_F(LogfsTestCooked, WriteVerifyMultiInstance) { TEST_F(LogfsTestCooked, WriteVerifyMultiInstance) {
@ -203,12 +235,12 @@ TEST_F(LogfsTestCooked, WriteVerifyMultiInstance) {
TEST_F(LogfsTestCooked, FillFilesystemAndGarbageCollect) { TEST_F(LogfsTestCooked, FillFilesystemAndGarbageCollect) {
/* Fill up the entire filesystem with multiple instances of obj1 */ /* Fill up the entire filesystem with multiple instances of obj1 */
for (uint32_t i = 0; i < (flashfs_config.arena_size / flashfs_config.slot_size) - 1; i++) { for (uint32_t i = 0; i < (flashfs_config_partition_a.arena_size / flashfs_config_partition_a.slot_size) - 1; i++) {
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, i, obj1, sizeof(obj1))); EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, i, obj1, sizeof(obj1)));
} }
/* Should fail to add a new object since the filesystem is full */ /* Should fail to add a new object since the filesystem is full */
EXPECT_EQ(-3, PIOS_FLASHFS_ObjSave(fs_id, OBJ2_ID, 0, obj2, sizeof(obj2))); EXPECT_EQ(-4, PIOS_FLASHFS_ObjSave(fs_id, OBJ2_ID, 0, obj2, sizeof(obj2)));
/* Now save a new version of an existing object which should trigger gc and succeed */ /* Now save a new version of an existing object which should trigger gc and succeed */
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 0, obj1_alt, sizeof(obj1_alt))); EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 0, obj1_alt, sizeof(obj1_alt)));
@ -257,3 +289,97 @@ TEST_F(LogfsTestCooked, WriteManyVerify) {
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ3_ID, 0, obj3_check, sizeof(obj3_check))); EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ3_ID, 0, obj3_check, sizeof(obj3_check)));
EXPECT_EQ(0, memcmp(obj3, obj3_check, sizeof(obj3))); EXPECT_EQ(0, memcmp(obj3, obj3_check, sizeof(obj3)));
} }
class LogfsTestCookedMultiPart : public LogfsTestRaw {
protected:
virtual void SetUp() {
/* First, we need to set up the super fixture (LogfsTestRaw) */
LogfsTestRaw::SetUp();
/* Init the flash and the flashfs so we don't need to repeat this in every test */
EXPECT_EQ(0, PIOS_Flash_UT_Init(&flash_id, &flash_config));
EXPECT_EQ(0, PIOS_FLASHFS_Logfs_Init(&fs_id_a, &flashfs_config_partition_a, &pios_ut_flash_driver, flash_id));
EXPECT_EQ(0, PIOS_FLASHFS_Logfs_Init(&fs_id_b, &flashfs_config_partition_b, &pios_ut_flash_driver, flash_id));
}
virtual void TearDown() {
PIOS_FLASHFS_Logfs_Destroy(fs_id_b);
PIOS_FLASHFS_Logfs_Destroy(fs_id_a);
PIOS_Flash_UT_Destroy(flash_id);
}
uintptr_t flash_id;
uintptr_t fs_id_a;
uintptr_t fs_id_b;
};
TEST_F(LogfsTestCookedMultiPart, WriteOneWriteOneVerify) {
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_a, OBJ1_ID, 0, obj1, sizeof(obj1)));
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_b, OBJ2_ID, 0, obj2, sizeof(obj2)));
/* OBJ1 found in A */
unsigned char obj1_check[OBJ1_SIZE];
memset(obj1_check, 0, sizeof(obj1_check));
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id_a, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
EXPECT_EQ(0, memcmp(obj1, obj1_check, sizeof(obj1)));
/* OBJ2 found in B */
unsigned char obj2_check[OBJ2_SIZE];
memset(obj2_check, 0, sizeof(obj2_check));
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id_b, OBJ2_ID, 0, obj2_check, sizeof(obj2_check)));
EXPECT_EQ(0, memcmp(obj2, obj2_check, sizeof(obj2)));
}
TEST_F(LogfsTestCookedMultiPart, WriteOneWriteOneFormatOneVerify) {
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_a, OBJ1_ID, 0, obj1, sizeof(obj1)));
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_b, OBJ2_ID, 0, obj2, sizeof(obj2)));
EXPECT_EQ(0, PIOS_FLASHFS_Format(fs_id_a));
/* OBJ2 still found in B */
unsigned char obj2_check[OBJ2_SIZE];
memset(obj2_check, 0, sizeof(obj2_check));
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id_b, OBJ2_ID, 0, obj2_check, sizeof(obj2_check)));
EXPECT_EQ(0, memcmp(obj2, obj2_check, sizeof(obj2)));
}
TEST_F(LogfsTestCookedMultiPart, WriteOneWriteOneNoCross) {
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_a, OBJ1_ID, 0, obj1, sizeof(obj1)));
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_b, OBJ2_ID, 0, obj2, sizeof(obj2)));
/* OBJ1 not found in B */
unsigned char obj1_check[OBJ1_SIZE];
memset(obj1_check, 0, sizeof(obj1_check));
EXPECT_EQ(-3, PIOS_FLASHFS_ObjLoad(fs_id_b, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
/* OBJ2 not found in A */
unsigned char obj2_check[OBJ2_SIZE];
memset(obj2_check, 0, sizeof(obj2_check));
EXPECT_EQ(-3, PIOS_FLASHFS_ObjLoad(fs_id_a, OBJ2_ID, 0, obj2_check, sizeof(obj2_check)));
}
TEST_F(LogfsTestCookedMultiPart, WriteOneWriteOneDeleteOne) {
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_a, OBJ1_ID, 0, obj1, sizeof(obj1)));
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_b, OBJ2_ID, 0, obj2, sizeof(obj2)));
EXPECT_EQ(0, PIOS_FLASHFS_ObjDelete(fs_id_a, OBJ1_ID, 0));
/* OBJ1 not found in A */
unsigned char obj1_check[OBJ1_SIZE];
memset(obj1_check, 0, sizeof(obj1_check));
EXPECT_EQ(-3, PIOS_FLASHFS_ObjLoad(fs_id_a, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
/* OBJ2 still found in B */
unsigned char obj2_check[OBJ2_SIZE];
memset(obj2_check, 0, sizeof(obj2_check));
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id_b, OBJ2_ID, 0, obj2_check, sizeof(obj2_check)));
}
TEST_F(LogfsTestCookedMultiPart, WriteLarge) {
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_b, OBJ4_ID, 0, obj4, sizeof(obj4)));
/* OBJ4 found in B */
unsigned char obj4_check[OBJ4_SIZE];
memset(obj4_check, 0, sizeof(obj4_check));
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id_b, OBJ4_ID, 0, obj4_check, sizeof(obj4_check)));
}

View File

@ -7,15 +7,15 @@
const struct pios_flash_ut_cfg flash_config = { const struct pios_flash_ut_cfg flash_config = {
.size_of_flash = 0x00200000, .size_of_flash = 0x00300000,
.size_of_sector = 0x00010000, .size_of_sector = 0x00010000,
}; };
#include "pios_flashfs_logfs_priv.h" #include "pios_flashfs_logfs_priv.h"
const struct flashfs_logfs_cfg flashfs_config = { const struct flashfs_logfs_cfg flashfs_config_partition_a = {
.fs_magic = 0x89abceef, .fs_magic = 0x89abceef,
.total_fs_size = 0x00200000, /* 2M bytes (32 sectors = entire chip) */ .total_fs_size = 0x00200000, /* 2M bytes (32 sectors) */
.arena_size = 0x00010000, /* 256 * slot size */ .arena_size = 0x00010000, /* 256 * slot size */
.slot_size = 0x00000100, /* 256 bytes */ .slot_size = 0x00000100, /* 256 bytes */
@ -24,3 +24,14 @@ const struct flashfs_logfs_cfg flashfs_config = {
.page_size = 0x00000100, /* 256 bytes */ .page_size = 0x00000100, /* 256 bytes */
}; };
const struct flashfs_logfs_cfg flashfs_config_partition_b = {
.fs_magic = 0x89abceef,
.total_fs_size = 0x00100000, /* 1M bytes (16 sectors) */
.arena_size = 0x00010000, /* 64 * slot size */
.slot_size = 0x00000400, /* 256 bytes */
.start_offset = 0x00200000, /* start after partition a */
.sector_size = 0x00010000, /* 64K bytes */
.page_size = 0x00000100, /* 256 bytes */
};

View File

@ -34,6 +34,8 @@
#include "openpilot.h" #include "openpilot.h"
#include "pios_struct_helper.h" #include "pios_struct_helper.h"
extern uintptr_t pios_uavo_settings_fs_id;
#if (defined(__MACH__) && defined(__APPLE__)) #if (defined(__MACH__) && defined(__APPLE__))
#include <mach-o/getsect.h> #include <mach-o/getsect.h>
#endif #endif
@ -182,8 +184,8 @@ static int32_t connectObj(UAVObjHandle obj_handle, xQueueHandle queue,
static int32_t disconnectObj(UAVObjHandle obj_handle, xQueueHandle queue, static int32_t disconnectObj(UAVObjHandle obj_handle, xQueueHandle queue,
UAVObjEventCallback cb); UAVObjEventCallback cb);
#if defined(PIOS_USE_SETTINGS_ON_SDCARD) && defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) #if defined(PIOS_USE_SETTINGS_ON_SDCARD) && defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
#error Both PIOS_USE_SETTINGS_ON_SDCARD and PIOS_INCLUDE_FLASH_SECTOR_SETTINGS. Only one settings storage allowed. #error Both PIOS_USE_SETTINGS_ON_SDCARD and PIOS_INCLUDE_FLASH_LOGFS_SETTINGS. Only one settings storage allowed.
#endif #endif
#if defined(PIOS_USE_SETTINGS_ON_SDCARD) #if defined(PIOS_USE_SETTINGS_ON_SDCARD)
@ -792,12 +794,12 @@ int32_t UAVObjSave(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins
{ {
PIOS_Assert(obj_handle); PIOS_Assert(obj_handle);
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) #if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
if (UAVObjIsMetaobject(obj_handle)) { if (UAVObjIsMetaobject(obj_handle)) {
if (instId != 0) if (instId != 0)
return -1; return -1;
if (PIOS_FLASHFS_ObjSave(0, UAVObjGetID(obj_handle), instId, (uint8_t*) MetaDataPtr((struct UAVOMeta *)obj_handle), UAVObjGetNumBytes(obj_handle)) != 0) if (PIOS_FLASHFS_ObjSave(pios_uavo_settings_fs_id, UAVObjGetID(obj_handle), instId, (uint8_t*) MetaDataPtr((struct UAVOMeta *)obj_handle), UAVObjGetNumBytes(obj_handle)) != 0)
return -1; return -1;
} else { } else {
InstanceHandle instEntry = getInstance( (struct UAVOData *)obj_handle, instId); InstanceHandle instEntry = getInstance( (struct UAVOData *)obj_handle, instId);
@ -808,7 +810,7 @@ int32_t UAVObjSave(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins
if (InstanceData(instEntry) == NULL) if (InstanceData(instEntry) == NULL)
return -1; return -1;
if (PIOS_FLASHFS_ObjSave(0, UAVObjGetID(obj_handle), instId, InstanceData(instEntry), UAVObjGetNumBytes(obj_handle)) != 0) if (PIOS_FLASHFS_ObjSave(pios_uavo_settings_fs_id, UAVObjGetID(obj_handle), instId, InstanceData(instEntry), UAVObjGetNumBytes(obj_handle)) != 0)
return -1; return -1;
} }
#endif #endif
@ -946,13 +948,13 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins
{ {
PIOS_Assert(obj_handle); PIOS_Assert(obj_handle);
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) #if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
if (UAVObjIsMetaobject(obj_handle)) { if (UAVObjIsMetaobject(obj_handle)) {
if (instId != 0) if (instId != 0)
return -1; return -1;
// Fire event on success // Fire event on success
if (PIOS_FLASHFS_ObjLoad(0, UAVObjGetID(obj_handle), instId, (uint8_t*) MetaDataPtr((struct UAVOMeta *)obj_handle), UAVObjGetNumBytes(obj_handle)) == 0) if (PIOS_FLASHFS_ObjLoad(pios_uavo_settings_fs_id, UAVObjGetID(obj_handle), instId, (uint8_t*) MetaDataPtr((struct UAVOMeta *)obj_handle), UAVObjGetNumBytes(obj_handle)) == 0)
sendEvent((struct UAVOBase*)obj_handle, instId, EV_UNPACKED); sendEvent((struct UAVOBase*)obj_handle, instId, EV_UNPACKED);
else else
return -1; return -1;
@ -964,7 +966,7 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins
return -1; return -1;
// Fire event on success // Fire event on success
if (PIOS_FLASHFS_ObjLoad(0, UAVObjGetID(obj_handle), instId, InstanceData(instEntry), UAVObjGetNumBytes(obj_handle)) == 0) if (PIOS_FLASHFS_ObjLoad(pios_uavo_settings_fs_id, UAVObjGetID(obj_handle), instId, InstanceData(instEntry), UAVObjGetNumBytes(obj_handle)) == 0)
sendEvent((struct UAVOBase*)obj_handle, instId, EV_UNPACKED); sendEvent((struct UAVOBase*)obj_handle, instId, EV_UNPACKED);
else else
return -1; return -1;
@ -1021,8 +1023,8 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins
int32_t UAVObjDelete(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t instId) int32_t UAVObjDelete(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t instId)
{ {
PIOS_Assert(obj_handle); PIOS_Assert(obj_handle);
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) #if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
PIOS_FLASHFS_ObjDelete(0, UAVObjGetID(obj_handle), instId); PIOS_FLASHFS_ObjDelete(pios_uavo_settings_fs_id, UAVObjGetID(obj_handle), instId);
#endif #endif
#if defined(PIOS_USE_SETTINGS_ON_SDCARD) #if defined(PIOS_USE_SETTINGS_ON_SDCARD)
uint8_t filename[14]; uint8_t filename[14];

View File

@ -137,7 +137,10 @@ BOARD_CDEFS += -DFW_DESC_SIZE=$(FW_DESC_SIZE)
BOARD_CDEFS += -DBL_BANK_BASE=$(BL_BANK_BASE) BOARD_CDEFS += -DBL_BANK_BASE=$(BL_BANK_BASE)
BOARD_CDEFS += -DBL_BANK_SIZE=$(BL_BANK_SIZE) BOARD_CDEFS += -DBL_BANK_SIZE=$(BL_BANK_SIZE)
BOARD_CDEFS += -DBL_DESC_SIZE=$(BL_DESC_SIZE) BOARD_CDEFS += -DBL_DESC_SIZE=$(BL_DESC_SIZE)
ifdef EE_BANK_BASE
BOARD_CDEFS += -DEE_BANK_BASE=$(EE_BANK_BASE)
BOARD_CDEFS += -DEE_BANK_SIZE=$(EE_BANK_SIZE)
endif
CDEFS += $(BOARD_CDEFS) CDEFS += $(BOARD_CDEFS)
ifeq ($(DEBUG), YES) ifeq ($(DEBUG), YES)