From 99e61dd617f98b54de6493cdd840cbf89fcc24b3 Mon Sep 17 00:00:00 2001 From: Stacey Sheldon Date: Tue, 16 Apr 2013 21:15:06 -0400 Subject: [PATCH 01/16] logfs: support multiple instances of logfs Conflicts: flight/pios/common/pios_flashfs_logfs.c flight/pios/inc/pios_flashfs_logfs_priv.h flight/tests/logfs/pios.h flight/tests/logfs/pios_config.h flight/tests/logfs/unittest.cpp --- flight/pios/common/pios_flashfs_logfs.c | 450 ++++++++++++++-------- flight/pios/inc/pios_flashfs_logfs_priv.h | 2 + flight/tests/logfs/FreeRTOS.h | 3 + flight/tests/logfs/pios.h | 7 +- flight/tests/logfs/pios_config.h | 1 + flight/tests/logfs/unittest.cpp | 31 +- 6 files changed, 320 insertions(+), 174 deletions(-) create mode 100644 flight/tests/logfs/FreeRTOS.h diff --git a/flight/pios/common/pios_flashfs_logfs.c b/flight/pios/common/pios_flashfs_logfs.c index bff3279a8..d681c406b 100644 --- a/flight/pios/common/pios_flashfs_logfs.c +++ b/flight/pios/common/pios_flashfs_logfs.c @@ -34,6 +34,7 @@ #include "pios_flashfs_logfs_priv.h" #include +#include /* NULL */ #define MIN(x,y) ((x) < (y) ? (x) : (y)) @@ -41,7 +42,12 @@ * Filesystem state data tracked in RAM */ +enum pios_flashfs_logfs_dev_magic { + PIOS_FLASHFS_LOGFS_DEV_MAGIC = 0x94938201, +}; + struct logfs_state { + enum pios_flashfs_logfs_dev_magic magic; const struct flashfs_logfs_cfg * cfg; bool mounted; uint8_t active_arena_id; @@ -58,8 +64,6 @@ struct logfs_state { uintptr_t flash_id; }; -static struct logfs_state logfs; - /* * Internal Utility functions */ @@ -68,14 +72,14 @@ static struct logfs_state logfs; * @brief Return the offset in flash of a particular slot within an arena * @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(slot_id < (logfs.cfg->arena_size / logfs.cfg->slot_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)); - return (logfs.cfg->start_offset + - (arena_id * logfs.cfg->arena_size) + - (slot_id * logfs.cfg->slot_size)); + return (logfs->cfg->start_offset + + (arena_id * logfs->cfg->arena_size) + + (slot_id * logfs->cfg->slot_size)); } /* @@ -114,27 +118,27 @@ struct arena_header { * @return 0 if success, < 0 on failure * @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 */ 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++) { - if (logfs.driver->erase_sector(logfs.flash_id, - arena_addr + (sector_id * logfs.cfg->sector_size))) { + if (logfs->driver->erase_sector(logfs->flash_id, + arena_addr + (sector_id * logfs->cfg->sector_size))) { return -1; } } /* Mark this arena as fully erased */ struct arena_header arena_hdr = { - .magic = logfs.cfg->fs_magic, + .magic = logfs->cfg->fs_magic, .state = ARENA_STATE_ERASED, }; - if (logfs.driver->write_data(logfs.flash_id, + if (logfs->driver->write_data(logfs->flash_id, arena_addr, (uint8_t *)&arena_hdr, sizeof(arena_hdr)) != 0) { @@ -151,13 +155,13 @@ static int32_t logfs_erase_arena(uint8_t arena_id) * @note Arena must have been previously erased before calling this * @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 */ struct arena_header arena_hdr; - if (logfs.driver->read_data(logfs.flash_id, + if (logfs->driver->read_data(logfs->flash_id, arena_addr, (uint8_t *)&arena_hdr, sizeof(arena_hdr)) != 0) { @@ -172,7 +176,7 @@ static int32_t logfs_reserve_arena (uint8_t arena_id) arena_hdr.state = ARENA_STATE_RESERVED; /* 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, (uint8_t *)&arena_hdr, sizeof(arena_hdr)) != 0) { @@ -188,15 +192,15 @@ static int32_t logfs_reserve_arena (uint8_t arena_id) * @return 0 if success, < 0 on failure * @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++) { #ifdef PIOS_LED_HEARTBEAT PIOS_LED_Toggle(PIOS_LED_HEARTBEAT); #endif - if (logfs_erase_arena(arena) != 0) + if (logfs_erase_arena(logfs, arena) != 0) return -1; } @@ -209,13 +213,13 @@ static int32_t logfs_erase_all_arenas() * @note Arena must have been previously erased or reserved before calling this * @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 */ struct arena_header arena_hdr; - if (logfs.driver->read_data(logfs.flash_id, + if (logfs->driver->read_data(logfs->flash_id, arena_addr, (uint8_t *)&arena_hdr, sizeof (arena_hdr)) != 0) { @@ -230,7 +234,7 @@ static int32_t logfs_activate_arena(uint8_t arena_id) /* Mark this arena as 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, (uint8_t *)&arena_hdr, sizeof(arena_hdr)) != 0) { @@ -247,16 +251,16 @@ static int32_t logfs_activate_arena(uint8_t arena_id) * @note Arena must have been previously active before calling this * @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 */ - PIOS_Assert(!logfs.mounted); + PIOS_Assert(!logfs->mounted); /* Make sure this arena was previously active */ struct arena_header arena_hdr; - if (logfs.driver->read_data(logfs.flash_id, + if (logfs->driver->read_data(logfs->flash_id, arena_addr, (uint8_t *)&arena_hdr, sizeof (arena_hdr)) != 0) { @@ -271,7 +275,7 @@ static int32_t logfs_obsolete_arena(uint8_t arena_id) /* Mark this arena as 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, (uint8_t *)&arena_hdr, sizeof(arena_hdr)) != 0) { @@ -289,23 +293,23 @@ static int32_t logfs_obsolete_arena(uint8_t arena_id) * @return -2 if failed to read arena header * @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 */ 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++) { - 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 */ struct arena_header arena_hdr; - if (logfs.driver->read_data(logfs.flash_id, + if (logfs->driver->read_data(logfs->flash_id, arena_addr, (uint8_t *)&arena_hdr, sizeof (arena_hdr)) != 0) { return -2; } 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 */ return arena_id; } @@ -344,7 +348,7 @@ struct slot_header { } __attribute__((packed)); /* 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 uint8_t data_block[RAW_COPY_BLOCK_SIZE]; @@ -360,7 +364,7 @@ static int32_t logfs_raw_copy_bytes (uintptr_t src_addr, uint16_t src_size, uint } /* 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, data_block, blk_size) != 0) { @@ -369,7 +373,7 @@ static int32_t logfs_raw_copy_bytes (uintptr_t src_addr, uint16_t src_size, uint } /* 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, data_block, blk_size) != 0) { @@ -391,9 +395,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) * 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); } /* @@ -401,37 +405,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) * 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_free_slots = 0; - logfs.mounted = false; + logfs->num_active_slots = 0; + logfs->num_free_slots = 0; + logfs->mounted = false; 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_free_slots = 0; - logfs.active_arena_id = arena_id; + logfs->num_active_slots = 0; + logfs->num_free_slots = 0; + logfs->active_arena_id = arena_id; /* Scan the log to find out how full it is */ 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++) { struct slot_header slot_hdr; - uintptr_t slot_addr = logfs_get_addr (logfs.active_arena_id, slot_id); - if (logfs.driver->read_data(logfs.flash_id, + uintptr_t slot_addr = logfs_get_addr (logfs, logfs->active_arena_id, slot_id); + if (logfs->driver->read_data(logfs->flash_id, slot_addr, (uint8_t *)&slot_hdr, sizeof (slot_hdr)) != 0) { @@ -443,14 +447,14 @@ static int32_t logfs_mount_log(uint8_t arena_id) * end of the arena. */ PIOS_Assert (slot_hdr.state == SLOT_STATE_EMPTY || - logfs.num_free_slots == 0); + logfs->num_free_slots == 0); switch (slot_hdr.state) { case SLOT_STATE_EMPTY: - logfs.num_free_slots++; + logfs->num_free_slots++; break; case SLOT_STATE_ACTIVE: - logfs.num_active_slots++; + logfs->num_active_slots++; break; case SLOT_STATE_RESERVED: case SLOT_STATE_OBSOLETE: @@ -459,12 +463,59 @@ static int32_t logfs_mount_log(uint8_t arena_id) } /* Scan is complete, mark the arena mounted */ - logfs.active_arena_id = arena_id; - logfs.mounted = true; + logfs->active_arena_id = arena_id; + logfs->mounted = true; 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 * @return 0 if success, -1 if failure @@ -485,15 +536,23 @@ int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t * fs_id, const struct flashfs_logfs_cf PIOS_Assert(driver->write_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; - 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; goto out_exit; } @@ -502,16 +561,16 @@ int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t * fs_id, const struct flashfs_logfs_cf int32_t arena_id; for (uint8_t try = 0; !found && try < 2; try++) { /* Find the active arena */ - arena_id = logfs_find_active_arena(); + arena_id = logfs_find_active_arena(logfs); if (arena_id >= 0) { /* Found the active arena */ found = true; break; } else { /* No active arena found, erase and activate arena 0 */ - if (logfs_erase_arena(0) != 0) + if (logfs_erase_arena(logfs, 0) != 0) break; - if (logfs_activate_arena(0) != 0) + if (logfs_activate_arena(logfs, 0) != 0) break; } } @@ -523,7 +582,7 @@ int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t * fs_id, const struct flashfs_logfs_cf } /* 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 */ rc = -3; goto out_end_trans; @@ -532,32 +591,50 @@ int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t * fs_id, const struct flashfs_logfs_cf /* Log has been mounted */ rc = 0; - *fs_id = (uintptr_t) &logfs; + *fs_id = (uintptr_t) logfs; 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: return rc; } /* NOTE: Must be called while holding the flash transaction lock */ -static int32_t logfs_garbage_collect (void) { - PIOS_Assert (logfs.mounted); +static int32_t logfs_garbage_collect (struct logfs_state * logfs) { + PIOS_Assert (logfs->mounted); /* 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 */ - 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 */ - if (logfs_erase_arena (dst_arena_id) != 0) { + if (logfs_erase_arena (logfs, dst_arena_id) != 0) { return -1; } /* 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 */ return -2; } @@ -565,11 +642,11 @@ static int32_t logfs_garbage_collect (void) { /* Copy active slots from active arena to destination arena */ uint16_t dst_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++) { struct slot_header slot_hdr; - uintptr_t src_addr = logfs_get_addr (src_arena_id, src_slot_id); - if (logfs.driver->read_data(logfs.flash_id, + uintptr_t src_addr = logfs_get_addr (logfs, src_arena_id, src_slot_id); + if (logfs->driver->read_data(logfs->flash_id, src_addr, (uint8_t *)&slot_hdr, sizeof (slot_hdr)) != 0) { @@ -577,8 +654,9 @@ static int32_t logfs_garbage_collect (void) { } if (slot_hdr.state == SLOT_STATE_ACTIVE) { - uintptr_t dst_addr = logfs_get_addr (dst_arena_id, dst_slot_id); - if (logfs_raw_copy_bytes(src_addr, + uintptr_t dst_addr = logfs_get_addr (logfs, dst_arena_id, dst_slot_id); + if (logfs_raw_copy_bytes(logfs, + src_addr, sizeof(slot_hdr) + slot_hdr.obj_size, dst_addr) != 0) { /* Failed to copy all bytes */ @@ -589,22 +667,22 @@ static int32_t logfs_garbage_collect (void) { } /* Activate the destination arena */ - if (logfs_activate_arena (dst_arena_id) != 0) { + if (logfs_activate_arena (logfs, dst_arena_id) != 0) { return -5; } /* Unmount the source arena */ - if (logfs_unmount_log () != 0) { + if (logfs_unmount_log (logfs) != 0) { return -6; } /* Obsolete the source arena */ - if (logfs_obsolete_arena (src_arena_id) != 0) { + if (logfs_obsolete_arena (logfs, src_arena_id) != 0) { return -7; } /* Mount the new arena */ - if (logfs_mount_log (dst_arena_id) != 0) { + if (logfs_mount_log (logfs, dst_arena_id) != 0) { return -8; } @@ -612,7 +690,7 @@ static int32_t logfs_garbage_collect (void) { } /* 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(curr_slot); @@ -621,11 +699,11 @@ static int16_t logfs_object_find_next (struct slot_header * slot_hdr, uint16_t * if (*curr_slot == 0) *curr_slot = 1; 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++) { - 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, (uint8_t *)slot_hdr, sizeof (*slot_hdr)) != 0) { @@ -650,7 +728,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 */ /* 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; @@ -658,13 +736,13 @@ static int8_t logfs_delete_object (uint32_t obj_id, uint16_t obj_inst_id) uint16_t curr_slot_id = 0; do { 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: /* Found a matching slot. Obsolete it. */ 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, (uint8_t *)&slot_hdr, sizeof(slot_hdr)) != 0) { @@ -672,7 +750,7 @@ static int8_t logfs_delete_object (uint32_t obj_id, uint16_t obj_inst_id) goto out_exit; } /* Object has been successfully obsoleted and is no longer active */ - logfs.num_active_slots--; + logfs->num_active_slots--; break; case -1: /* Search completed, object not found */ @@ -691,27 +769,27 @@ out_exit: } /* 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_hdr); - if (logfs.num_free_slots < 1) { + if (logfs->num_free_slots < 1) { /* No free slots to allocate */ 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 */ 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); - 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, (uint8_t *)slot_hdr, sizeof (*slot_hdr)) != 0) { @@ -731,7 +809,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_size = obj_size; - if (logfs.driver->write_data(logfs.flash_id, + if (logfs->driver->write_data(logfs->flash_id, slot_addr, (uint8_t *)slot_hdr, sizeof(*slot_hdr)) != 0) { @@ -740,33 +818,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 */ - logfs.num_free_slots--; + logfs->num_free_slots--; *slot_id = candidate_slot_id; return 0; } /* 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 */ uint16_t free_slot_id; 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 */ return -1; } /* 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 */ uintptr_t slot_offset = sizeof(slot_hdr); while (obj_size > 0) { /* 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); - if (logfs.driver->write_data (logfs.flash_id, + if (logfs->driver->write_data (logfs->flash_id, slot_addr + slot_offset, obj_data, write_size) != 0) { @@ -782,7 +860,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 */ slot_hdr.state = SLOT_STATE_ACTIVE; - if (logfs.driver->write_data (logfs.flash_id, + if (logfs->driver->write_data (logfs->flash_id, slot_addr, (uint8_t *)&slot_hdr, sizeof(slot_hdr)) != 0) { @@ -791,7 +869,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 */ - logfs.num_active_slots++; + logfs->num_active_slots++; return 0; } @@ -811,26 +889,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_size Size of the object being saved * @return 0 if success or error code - * @retval -1 if failed to start transaction - * @retval -2 if failure to delete any previous versions of the object - * @retval -3 if filesystem is entirely full and garbage collection won't help - * @retval -4 if garbage collection failed - * @retval -5 if filesystem is full even after garbage collection should have freed space - * @retval -6 if writing the new object to the filesystem failed + * @retval -1 if fs_id is not a valid filesystem instance + * @retval -2 if failed to start transaction + * @retval -3 if failure to delete any previous versions of the object + * @retval -4 if filesystem is entirely full and garbage collection won't help + * @retval -5 if garbage collection 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(uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t * obj_data, uint16_t obj_size) { 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; 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; + goto out_exit; + } + + if (logfs_delete_object (logfs, obj_id, obj_inst_id) != 0) { + rc = -3; goto out_end_trans; } @@ -840,36 +926,36 @@ int32_t PIOS_FLASHFS_ObjSave(__attribute__((unused)) uint32_t fs_id, uint32_t ob */ /* 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. */ - rc = -3; + rc = -4; goto out_end_trans; } /* 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 */ - if (logfs_garbage_collect() != 0) { - rc = -4; + if (logfs_garbage_collect(logfs) != 0) { + rc = -5; goto out_end_trans; } /* 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! * NOTE: This should not happen since the filesystem wasn't full * when we checked above so gc should have helped. */ PIOS_DEBUG_Assert(0); - rc = -5; + rc = -6; goto out_end_trans; } } /* 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 */ - rc = -6; + rc = -7; goto out_end_trans; } @@ -877,7 +963,7 @@ int32_t PIOS_FLASHFS_ObjSave(__attribute__((unused)) uint32_t fs_id, uint32_t ob rc = 0; out_end_trans: - logfs.driver->end_transaction(logfs.flash_id); + logfs->driver->end_transaction(logfs->flash_id); out_exit: return rc; @@ -891,47 +977,55 @@ out_exit: * @param[in] obj_data Buffer to hold the contents of the loaded object * @param[in] obj_size Size of the object to be loaded * @return 0 if success or error code - * @retval -1 if failed to start transaction - * @retval -2 if object not found in filesystem - * @retval -3 if object size in filesystem does not exactly match buffer size - * @retval -4 if reading the object data from flash fails + * @retval -1 if fs_id is not a valid filesystem instance + * @retval -2 if failed to start transaction + * @retval -3 if object not found in filesystem + * @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(uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t * obj_data, uint16_t obj_size) { 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; 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 */ uint16_t slot_id = 0; 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 */ - rc = -2; + rc = -3; goto out_end_trans; } /* Sanity check what we've found */ if (slot_hdr.obj_size != obj_size) { /* Object sizes don't match. Not safe to copy contents. */ - rc = -3; + rc = -4; goto out_end_trans; } /* Read the contents of the object from the log */ if (obj_size > 0) { - uintptr_t slot_addr = logfs_get_addr (logfs.active_arena_id, slot_id); - if (logfs.driver->read_data(logfs.flash_id, + uintptr_t slot_addr = logfs_get_addr (logfs, logfs->active_arena_id, slot_id); + if (logfs->driver->read_data(logfs->flash_id, slot_addr + sizeof(slot_hdr), (uint8_t *)obj_data, obj_size) != 0) { /* Failed to read object data from the log */ - rc = -4; + rc = -5; goto out_end_trans; } } @@ -940,7 +1034,7 @@ int32_t PIOS_FLASHFS_ObjLoad(__attribute__((unused)) uint32_t fs_id, uint32_t ob rc = 0; out_end_trans: - logfs.driver->end_transaction(logfs.flash_id); + logfs->driver->end_transaction(logfs->flash_id); out_exit: return rc; @@ -952,20 +1046,28 @@ out_exit: * @param[in] obj UAVObject ID of the object to delete * @param[in] obj_inst_id The instance of the object to delete * @return 0 if success or error code - * @retval -1 if failed to start transaction - * @retval -2 if failed to delete the object from the filesystem + * @retval -1 if fs_id is not a valid filesystem instance + * @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(uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id) { 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; goto out_exit; } - if (logfs_delete_object (obj_id, obj_inst_id) != 0) { + if (logfs->driver->start_transaction(logfs->flash_id) != 0) { rc = -2; + goto out_exit; + } + + if (logfs_delete_object (logfs, obj_id, obj_inst_id) != 0) { + rc = -3; goto out_end_trans; } @@ -973,7 +1075,7 @@ int32_t PIOS_FLASHFS_ObjDelete(__attribute__((unused)) uint32_t fs_id, uint32_t rc = 0; out_end_trans: - logfs.driver->end_transaction(logfs.flash_id); + logfs->driver->end_transaction(logfs->flash_id); out_exit: return rc; @@ -983,46 +1085,54 @@ out_exit: * @brief Erases all filesystem arenas and activate the first arena * @param[in] fs_id The filesystem to use for this action * @return 0 if success or error code - * @retval -1 if failed to start transaction - * @retval -2 if failed to erase all arenas - * @retval -3 if failed to activate arena 0 - * @retval -4 if failed to mount arena 0 + * @retval -1 if fs_id is not a valid filesystem instance + * @retval -2 if failed to start transaction + * @retval -3 if failed to erase all arenas + * @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(uint32_t fs_id) { int32_t rc; - if (logfs.mounted) { - logfs_unmount_log(); - } + 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; goto out_exit; } - if (logfs_erase_all_arenas() != 0) { - rc = -2; - goto out_end_trans; + if (logfs->mounted) { + logfs_unmount_log(logfs); } - /* Reinitialize arena 0 */ - if (logfs_activate_arena(0) != 0) { + if (logfs->driver->start_transaction(logfs->flash_id) != 0) { + rc = -2; + goto out_exit; + } + + if (logfs_erase_all_arenas(logfs) != 0) { rc = -3; goto out_end_trans; } - /* Mount arena 0 */ - if (logfs_mount_log(0) != 0) { + /* Reinitialize arena 0 */ + if (logfs_activate_arena(logfs, 0) != 0) { rc = -4; 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 */ rc = 0; out_end_trans: - logfs.driver->end_transaction(logfs.flash_id); + logfs->driver->end_transaction(logfs->flash_id); out_exit: return rc; diff --git a/flight/pios/inc/pios_flashfs_logfs_priv.h b/flight/pios/inc/pios_flashfs_logfs_priv.h index 88ce65109..24212d7e9 100644 --- a/flight/pios/inc/pios_flashfs_logfs_priv.h +++ b/flight/pios/inc/pios_flashfs_logfs_priv.h @@ -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_Destroy(uintptr_t fs_id); + #endif /* PIOS_FLASHFS_LOGFS_PRIV_H */ diff --git a/flight/tests/logfs/FreeRTOS.h b/flight/tests/logfs/FreeRTOS.h new file mode 100644 index 000000000..7f174088c --- /dev/null +++ b/flight/tests/logfs/FreeRTOS.h @@ -0,0 +1,3 @@ +#include +#define pvPortMalloc(xSize) (malloc(xSize)) +#define vPortFree(pv) (free(pv)) diff --git a/flight/tests/logfs/pios.h b/flight/tests/logfs/pios.h index 88a4914dc..7a3381015 100644 --- a/flight/tests/logfs/pios.h +++ b/flight/tests/logfs/pios.h @@ -1,9 +1,14 @@ #ifndef PIOS_H #define PIOS_H -/* PIOS board specific feature selection */ +/* PIOS Feature Selection */ #include "pios_config.h" +#ifdef PIOS_INCLUDE_FREERTOS +/* FreeRTOS Includes */ +#include "FreeRTOS.h" +#endif + #ifdef PIOS_INCLUDE_FLASH #include #include diff --git a/flight/tests/logfs/pios_config.h b/flight/tests/logfs/pios_config.h index e473cd8ef..e6d4f180f 100644 --- a/flight/tests/logfs/pios_config.h +++ b/flight/tests/logfs/pios_config.h @@ -3,5 +3,6 @@ /* Enable/Disable PiOS modules */ #define PIOS_INCLUDE_FLASH +//#define PIOS_INCLUDE_FREERTOS #endif /* PIOS_CONFIG_H */ diff --git a/flight/tests/logfs/unittest.cpp b/flight/tests/logfs/unittest.cpp index c0c383e76..a8b902847 100644 --- a/flight/tests/logfs/unittest.cpp +++ b/flight/tests/logfs/unittest.cpp @@ -77,6 +77,8 @@ protected: TEST_F(LogfsTestRaw, FlashInit) { uintptr_t flash_id; EXPECT_EQ(0, PIOS_Flash_UT_Init(&flash_id, &flash_config)); + + PIOS_Flash_UT_Destroy(flash_id); } TEST_F(LogfsTestRaw, LogfsInit) { @@ -85,6 +87,9 @@ TEST_F(LogfsTestRaw, LogfsInit) { uintptr_t fs_id; EXPECT_EQ(0, PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_config, &pios_ut_flash_driver, flash_id)); + + PIOS_FLASHFS_Logfs_Destroy(fs_id); + PIOS_Flash_UT_Destroy(flash_id); } class LogfsTestCooked : public LogfsTestRaw { @@ -99,9 +104,29 @@ protected: EXPECT_EQ(0, PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_config, &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; }; +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) { EXPECT_EQ(0, PIOS_FLASHFS_Format(fs_id)); } @@ -129,7 +154,7 @@ TEST_F(LogfsTestCooked, WriteVerifyDeleteVerifyOne) { 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) { @@ -178,7 +203,7 @@ TEST_F(LogfsTestCooked, ReadNonexistent) { /* Read back a zero length object -- basically an existence check */ unsigned char obj1_check[OBJ1_SIZE]; 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) { @@ -208,7 +233,7 @@ TEST_F(LogfsTestCooked, FillFilesystemAndGarbageCollect) { } /* 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 */ EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id, OBJ1_ID, 0, obj1_alt, sizeof(obj1_alt))); From 8ab50bca13f0bea37ebd1084133c6fe781321a16 Mon Sep 17 00:00:00 2001 From: Stacey Sheldon Date: Thu, 18 Apr 2013 21:17:49 -0400 Subject: [PATCH 02/16] flashfs: use uintptr_t instead of uint32_t in flashfs API --- flight/pios/common/pios_flashfs_logfs.c | 8 ++++---- flight/pios/inc/pios_flashfs.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/flight/pios/common/pios_flashfs_logfs.c b/flight/pios/common/pios_flashfs_logfs.c index d681c406b..fca001c30 100644 --- a/flight/pios/common/pios_flashfs_logfs.c +++ b/flight/pios/common/pios_flashfs_logfs.c @@ -897,7 +897,7 @@ static int8_t logfs_append_to_log (struct logfs_state * logfs, uint32_t obj_id, * @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(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; @@ -983,7 +983,7 @@ out_exit: * @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(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; @@ -1050,7 +1050,7 @@ out_exit: * @retval -2 if failed to start transaction * @retval -3 if failed to delete the object from the filesystem */ -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) { int8_t rc; @@ -1091,7 +1091,7 @@ out_exit: * @retval -4 if failed to activate arena 0 * @retval -5 if failed to mount arena 0 */ -int32_t PIOS_FLASHFS_Format(uint32_t fs_id) +int32_t PIOS_FLASHFS_Format(uintptr_t fs_id) { int32_t rc; diff --git a/flight/pios/inc/pios_flashfs.h b/flight/pios/inc/pios_flashfs.h index 073cf9490..0ecb713fd 100644 --- a/flight/pios/inc/pios_flashfs.h +++ b/flight/pios/inc/pios_flashfs.h @@ -29,9 +29,9 @@ #include -int32_t PIOS_FLASHFS_Format(uint32_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_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_ObjDelete(uint32_t fs_id, uint32_t obj_id, uint16_t obj_inst_id); +int32_t PIOS_FLASHFS_Format(uintptr_t fs_id); +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(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(uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id); #endif /* PIOS_FLASHFS_H */ From 4f9ce609306d2c7a8bc8b40473177781a241e53a Mon Sep 17 00:00:00 2001 From: Stacey Sheldon Date: Thu, 18 Apr 2013 23:32:52 -0400 Subject: [PATCH 03/16] ut logfs: add support for testing a 2nd partition --- flight/tests/logfs/unittest.cpp | 114 +++++++++++++++++++++++++++-- flight/tests/logfs/unittest_init.c | 17 ++++- 2 files changed, 123 insertions(+), 8 deletions(-) diff --git a/flight/tests/logfs/unittest.cpp b/flight/tests/logfs/unittest.cpp index a8b902847..46d6683c1 100644 --- a/flight/tests/logfs/unittest.cpp +++ b/flight/tests/logfs/unittest.cpp @@ -13,7 +13,8 @@ extern struct pios_flash_ut_cfg flash_config; #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_* */ @@ -30,6 +31,9 @@ extern struct flashfs_logfs_cfg flashfs_config; #define OBJ3_ID 0x99999999 #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. class LogfsTestRaw : public testing::Test { protected: @@ -62,6 +66,11 @@ protected: for (uint32_t i = 0; i < sizeof(obj3); i++) { 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() { @@ -72,6 +81,7 @@ protected: unsigned char obj1_alt[OBJ1_SIZE]; unsigned char obj2[OBJ2_SIZE]; unsigned char obj3[OBJ3_SIZE]; + unsigned char obj4[OBJ4_SIZE]; }; TEST_F(LogfsTestRaw, FlashInit) { @@ -86,7 +96,7 @@ TEST_F(LogfsTestRaw, LogfsInit) { EXPECT_EQ(0, PIOS_Flash_UT_Init(&flash_id, &flash_config)); 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); @@ -101,7 +111,7 @@ protected: /* 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_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() { @@ -195,7 +205,7 @@ TEST_F(LogfsTestCooked, WriteVerifyZeroLength) { } 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))); } @@ -228,7 +238,7 @@ TEST_F(LogfsTestCooked, WriteVerifyMultiInstance) { TEST_F(LogfsTestCooked, FillFilesystemAndGarbageCollect) { /* 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))); } @@ -282,3 +292,97 @@ TEST_F(LogfsTestCooked, WriteManyVerify) { 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))); } + +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))); +} diff --git a/flight/tests/logfs/unittest_init.c b/flight/tests/logfs/unittest_init.c index b60570c38..9f6305839 100644 --- a/flight/tests/logfs/unittest_init.c +++ b/flight/tests/logfs/unittest_init.c @@ -7,15 +7,15 @@ const struct pios_flash_ut_cfg flash_config = { - .size_of_flash = 0x00200000, + .size_of_flash = 0x00300000, .size_of_sector = 0x00010000, }; #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, - .total_fs_size = 0x00200000, /* 2M bytes (32 sectors = entire chip) */ + .total_fs_size = 0x00200000, /* 2M bytes (32 sectors) */ .arena_size = 0x00010000, /* 256 * slot size */ .slot_size = 0x00000100, /* 256 bytes */ @@ -24,3 +24,14 @@ const struct flashfs_logfs_cfg flashfs_config = { .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 */ +}; + From c6485a134c6125b4d9803389a8a9bc5d8149a863 Mon Sep 17 00:00:00 2001 From: Stacey Sheldon Date: Fri, 19 Apr 2013 00:20:26 -0400 Subject: [PATCH 04/16] logfs: load/save UAVOs to specific logfs partition Now that multiple filesystem partitions are supported, the UAVO manager needs to be specific about which partition to load/save its objects to. Conflicts: flight/targets/CopterControl/System/pios_board.c flight/targets/DiscoveryF4/System/pios_board.c flight/targets/FlyingF3/System/pios_board.c flight/targets/FlyingF4/System/pios_board.c flight/targets/Freedom/System/pios_board.c flight/targets/Quanton/System/pios_board.c flight/targets/RevoMini/System/pios_board.c flight/targets/Revolution/System/pios_board.c flight/uavobjects/uavobjectmanager.c --- flight/uavobjects/uavobjectmanager.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/flight/uavobjects/uavobjectmanager.c b/flight/uavobjects/uavobjectmanager.c index d4a22ce10..49d684d2b 100644 --- a/flight/uavobjects/uavobjectmanager.c +++ b/flight/uavobjects/uavobjectmanager.c @@ -797,7 +797,7 @@ int32_t UAVObjSave(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins if (instId != 0) 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; } else { InstanceHandle instEntry = getInstance( (struct UAVOData *)obj_handle, instId); @@ -808,7 +808,7 @@ int32_t UAVObjSave(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins if (InstanceData(instEntry) == NULL) 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; } #endif @@ -952,7 +952,7 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins return -1; // 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); else return -1; @@ -1022,7 +1022,7 @@ int32_t UAVObjDelete(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t i { PIOS_Assert(obj_handle); #if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) - PIOS_FLASHFS_ObjDelete(0, UAVObjGetID(obj_handle), instId); + PIOS_FLASHFS_ObjDelete(pios_uavo_settings_fs_id, UAVObjGetID(obj_handle), instId); #endif #if defined(PIOS_USE_SETTINGS_ON_SDCARD) uint8_t filename[14]; From aefda3b5602dcd0a1405cd251a8708c6b72f03f4 Mon Sep 17 00:00:00 2001 From: Alessio Morale Date: Thu, 9 May 2013 23:59:27 +0200 Subject: [PATCH 05/16] Changes to UAVObjectManager to explicitly specify the logfs instance to be used --- flight/uavobjects/uavobjectmanager.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/flight/uavobjects/uavobjectmanager.c b/flight/uavobjects/uavobjectmanager.c index 49d684d2b..8cfd7c4a8 100644 --- a/flight/uavobjects/uavobjectmanager.c +++ b/flight/uavobjects/uavobjectmanager.c @@ -34,6 +34,8 @@ #include "openpilot.h" #include "pios_struct_helper.h" +extern uintptr_t pios_uavo_settings_fs_id; + #if (defined(__MACH__) && defined(__APPLE__)) #include #endif @@ -964,7 +966,7 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins return -1; // 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); else return -1; From 687e75b2e27988aa32861f54f64034923e12a339 Mon Sep 17 00:00:00 2001 From: Alessio Morale Date: Sat, 11 May 2013 17:15:07 +0200 Subject: [PATCH 06/16] Changes to board specific files to support UAVObject on a specific LogFS instance --- .../targets/boards/coptercontrol/firmware/pios_board.c | 9 +++++---- flight/targets/boards/osd/firmware/pios_board.c | 5 +++-- flight/targets/boards/revolution/firmware/pios_board.c | 7 ++++--- flight/targets/boards/revoproto/firmware/pios_board.c | 7 ++++--- flight/targets/boards/simposix/firmware/pios_board.c | 2 ++ 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/flight/targets/boards/coptercontrol/firmware/pios_board.c b/flight/targets/boards/coptercontrol/firmware/pios_board.c index da067b39c..a9fbad5b8 100644 --- a/flight/targets/boards/coptercontrol/firmware/pios_board.c +++ b/flight/targets/boards/coptercontrol/firmware/pios_board.c @@ -75,6 +75,8 @@ uint32_t pios_com_hkosd_id; uint32_t pios_usb_rctx_id; +uintptr_t pios_uavo_settings_fs_id; + /** * Configuration for MPU6000 chip */ @@ -168,13 +170,12 @@ void PIOS_Board_Init(void) { #endif uintptr_t flash_id; - uintptr_t fs_id; switch(bdinfo->board_rev) { case BOARD_REVISION_CC: if (PIOS_Flash_Jedec_Init(&flash_id, pios_spi_flash_accel_id, 1)) { 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); } break; @@ -182,7 +183,7 @@ void PIOS_Board_Init(void) { if (PIOS_Flash_Jedec_Init(&flash_id, pios_spi_flash_accel_id, 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); } break; @@ -204,7 +205,7 @@ void PIOS_Board_Init(void) { PIOS_IAP_ReadBootCmd(1) == PIOS_IAP_CLEAR_FLASH_CMD_1 && 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(1,0); PIOS_IAP_WriteBootCmd(2,0); diff --git a/flight/targets/boards/osd/firmware/pios_board.c b/flight/targets/boards/osd/firmware/pios_board.c index 93db87174..a6f299855 100644 --- a/flight/targets/boards/osd/firmware/pios_board.c +++ b/flight/targets/boards/osd/firmware/pios_board.c @@ -104,6 +104,8 @@ uint32_t pios_com_gps_id; uint32_t pios_com_telem_usb_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 * APB1_CLOCK to generate a pixel clock that is used by the SPI CLK lines. @@ -163,9 +165,8 @@ void PIOS_Board_Init(void) { #ifdef PIOS_INCLUDE_FLASH_SECTOR_SETTINGS uintptr_t flash_id; -uintptr_t fs_id; 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) #error No setting storage specified. (define PIOS_USE_SETTINGS_ON_SDCARD or INCLUDE_FLASH_SECTOR_SETTINGS) #endif diff --git a/flight/targets/boards/revolution/firmware/pios_board.c b/flight/targets/boards/revolution/firmware/pios_board.c index c1acafb7d..4d2171c75 100644 --- a/flight/targets/boards/revolution/firmware/pios_board.c +++ b/flight/targets/boards/revolution/firmware/pios_board.c @@ -235,6 +235,8 @@ uint32_t pios_com_hkosd_id = 0; uint32_t pios_rfm22b_id = 0; #endif +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 */ @@ -352,8 +354,7 @@ void PIOS_Board_Init(void) { PIOS_DEBUG_Assert(0); } - uintptr_t fs_id; - 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); } @@ -369,7 +370,7 @@ void PIOS_Board_Init(void) { PIOS_IAP_ReadBootCmd(1) == PIOS_IAP_CLEAR_FLASH_CMD_1 && 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(1,0); PIOS_IAP_WriteBootCmd(2,0); diff --git a/flight/targets/boards/revoproto/firmware/pios_board.c b/flight/targets/boards/revoproto/firmware/pios_board.c index 3fda1d1a6..fbb421bec 100644 --- a/flight/targets/boards/revoproto/firmware/pios_board.c +++ b/flight/targets/boards/revoproto/firmware/pios_board.c @@ -305,6 +305,8 @@ uint32_t pios_com_bridge_id = 0; uint32_t pios_com_overo_id = 0; uint32_t pios_com_hkosd_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 */ @@ -402,8 +404,7 @@ void PIOS_Board_Init(void) { PIOS_DEBUG_Assert(0); } #endif - uintptr_t fs_id; - 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); } @@ -418,7 +419,7 @@ void PIOS_Board_Init(void) { PIOS_IAP_ReadBootCmd(1) == PIOS_IAP_CLEAR_FLASH_CMD_1 && 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(1,0); PIOS_IAP_WriteBootCmd(2,0); diff --git a/flight/targets/boards/simposix/firmware/pios_board.c b/flight/targets/boards/simposix/firmware/pios_board.c index 194a3d907..60f8205d7 100644 --- a/flight/targets/boards/simposix/firmware/pios_board.c +++ b/flight/targets/boards/simposix/firmware/pios_board.c @@ -73,6 +73,8 @@ uint32_t pios_com_telem_usb_id = 0; uint32_t pios_com_telem_rf_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 */ From 511283c60894a8afd5d4139d317b6b04ee579e79 Mon Sep 17 00:00:00 2001 From: Alessio Morale Date: Sat, 11 May 2013 22:04:47 +0200 Subject: [PATCH 07/16] Flash internal: writes optimization using 4 bytes parallelism --- flight/pios/stm32f4xx/pios_flash_internal.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/flight/pios/stm32f4xx/pios_flash_internal.c b/flight/pios/stm32f4xx/pios_flash_internal.c index c106573b3..5342e464e 100644 --- a/flight/pios/stm32f4xx/pios_flash_internal.c +++ b/flight/pios/stm32f4xx/pios_flash_internal.c @@ -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 */ 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 */ - for (uint16_t i = 0; 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. - */ + for (uint16_t i = len - len % 4; i < len; i++) { + status = FLASH_ProgramByte(addr + i, data[i]); - PIOS_Assert(status == FLASH_COMPLETE); + if(status != FLASH_COMPLETE) + return -5; } return 0; From d555bd06739dc3324fe573f62f023794d81bec39 Mon Sep 17 00:00:00 2001 From: Alessio Morale Date: Sat, 11 May 2013 22:06:30 +0200 Subject: [PATCH 08/16] Uses Internal flash for system settings storage repourposing external flash for "User" storage --- flight/targets/boards/osd/board-info.mk | 3 +- flight/targets/boards/osd/firmware/Makefile | 2 -- .../targets/boards/revolution/board-info.mk | 22 ++++++++++++- .../targets/boards/revolution/board_hw_defs.c | 17 +++++++++- .../revolution/firmware/inc/pios_config.h | 1 + .../boards/revolution/firmware/pios_board.c | 16 ++++++++-- flight/targets/boards/revoproto/board-info.mk | 7 ++++- .../targets/boards/revoproto/board_hw_defs.c | 31 ++++++++++++++----- .../revoproto/firmware/inc/pios_config.h | 1 + .../boards/revoproto/firmware/pios_board.c | 23 +++++++++++--- make/common-defs.mk | 2 ++ 11 files changed, 104 insertions(+), 21 deletions(-) diff --git a/flight/targets/boards/osd/board-info.mk b/flight/targets/boards/osd/board-info.mk index f894dfc99..ddd93d3cf 100644 --- a/flight/targets/boards/osd/board-info.mk +++ b/flight/targets/boards/osd/board-info.mk @@ -24,7 +24,8 @@ OPENOCD_CONFIG := stm32f4xx.stlink.cfg # 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 diff --git a/flight/targets/boards/osd/firmware/Makefile b/flight/targets/boards/osd/firmware/Makefile index fb2b56603..211fd65c8 100644 --- a/flight/targets/boards/osd/firmware/Makefile +++ b/flight/targets/boards/osd/firmware/Makefile @@ -100,8 +100,6 @@ else SRC += $(OPTESTS)/$(TESTAPP).c endif -CDEFS += -DEE_BANK_BASE=$(EE_BANK_BASE) -CDEFS += -DEE_BANK_SIZE=$(EE_BANK_SIZE) # Optional component libraries diff --git a/flight/targets/boards/revolution/board-info.mk b/flight/targets/boards/revolution/board-info.mk index e36dab087..049a8a4f8 100644 --- a/flight/targets/boards/revolution/board-info.mk +++ b/flight/targets/boards/revolution/board-info.mk @@ -12,11 +12,31 @@ MODEL_SUFFIX := OPENOCD_JTAG_CONFIG := stlink-v2.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 BL_BANK_BASE := 0x08000000 # Start of bootloader flash 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_SIZE := 0x00060000 # Should include FW_DESC_SIZE diff --git a/flight/targets/boards/revolution/board_hw_defs.c b/flight/targets/boards/revolution/board_hw_defs.c index 4ea6bbae8..220d0395d 100644 --- a/flight/targets/boards/revolution/board_hw_defs.c +++ b/flight/targets/boards/revolution/board_hw_defs.c @@ -665,8 +665,9 @@ const struct pios_rfm22b_cfg * PIOS_BOARD_HW_DEFS_GetRfm22Cfg (uint32_t board_re #if defined(PIOS_INCLUDE_FLASH) #include "pios_flashfs_logfs_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, .total_fs_size = 0x00200000, /* 2M bytes (32 sectors = entire chip) */ .arena_size = 0x00010000, /* 256 * slot size */ @@ -677,6 +678,20 @@ static const struct flashfs_logfs_cfg flashfs_m25p_cfg = { .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 */ #include diff --git a/flight/targets/boards/revolution/firmware/inc/pios_config.h b/flight/targets/boards/revolution/firmware/inc/pios_config.h index 1025db7e3..17112e081 100644 --- a/flight/targets/boards/revolution/firmware/inc/pios_config.h +++ b/flight/targets/boards/revolution/firmware/inc/pios_config.h @@ -106,6 +106,7 @@ /* #define PIOS_INCLUDE_SDCARD */ /* #define LOG_FILENAME "startup.log" */ #define PIOS_INCLUDE_FLASH +#define PIOS_INCLUDE_FLASH_INTERNAL #define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS #define FLASH_FREERTOS /* #define PIOS_INCLUDE_FLASH_EEPROM */ diff --git a/flight/targets/boards/revolution/firmware/pios_board.c b/flight/targets/boards/revolution/firmware/pios_board.c index 4d2171c75..5119cdcfd 100644 --- a/flight/targets/boards/revolution/firmware/pios_board.c +++ b/flight/targets/boards/revolution/firmware/pios_board.c @@ -236,6 +236,7 @@ uint32_t pios_rfm22b_id = 0; #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 @@ -350,12 +351,23 @@ void PIOS_Board_Init(void) { #if defined(PIOS_INCLUDE_FLASH) /* 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); + } + + // Initialize the external USER flash if (PIOS_Flash_Jedec_Init(&flash_id, pios_spi_telem_flash_id, 1)) { PIOS_DEBUG_Assert(0); } - if (PIOS_FLASHFS_Logfs_Init(&pios_uavo_settings_fs_id, &flashfs_m25p_cfg, &pios_jedec_flash_driver, flash_id)) { - PIOS_DEBUG_Assert(0); + if (PIOS_FLASHFS_Logfs_Init(&pios_user_fs_id, &flashfs_external_cfg, &pios_jedec_flash_driver, flash_id)) { + PIOS_DEBUG_Assert(0); } #endif diff --git a/flight/targets/boards/revoproto/board-info.mk b/flight/targets/boards/revoproto/board-info.mk index e95ecd360..1337952eb 100644 --- a/flight/targets/boards/revoproto/board-info.mk +++ b/flight/targets/boards/revoproto/board-info.mk @@ -16,7 +16,12 @@ OPENOCD_CONFIG := stm32f4xx.stlink.cfg BL_BANK_BASE := 0x08000000 # Start of bootloader flash 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_SIZE := 0x00060000 # Should include FW_DESC_SIZE diff --git a/flight/targets/boards/revoproto/board_hw_defs.c b/flight/targets/boards/revoproto/board_hw_defs.c index 0934a5a26..5286cc721 100644 --- a/flight/targets/boards/revoproto/board_hw_defs.c +++ b/flight/targets/boards/revoproto/board_hw_defs.c @@ -448,16 +448,31 @@ void PIOS_SPI_flash_irq_handler(void) #if defined(PIOS_INCLUDE_FLASH) #include "pios_flashfs_logfs_priv.h" #include "pios_flash_jedec_priv.h" +#include "pios_flash_internal_priv.h" -static const struct flashfs_logfs_cfg flashfs_m25p_cfg = { - .fs_magic = 0x99abceef, - .total_fs_size = 0x00200000, /* 2M bytes (32 sectors = entire chip) */ - .arena_size = 0x00010000, /* 256 * slot size */ - .slot_size = 0x00000100, /* 256 bytes */ +static const struct flashfs_logfs_cfg flashfs_external_cfg = { + .fs_magic = 0x99abceef, + .total_fs_size = 0x00200000, /* 2M bytes (32 sectors = entire chip) */ + .arena_size = 0x00010000, /* 256 * slot size */ + .slot_size = 0x00000100, /* 256 bytes */ - .start_offset = 0, /* start at the beginning of the chip */ - .sector_size = 0x00010000, /* 64K bytes */ - .page_size = 0x00000100, /* 256 bytes */ + .start_offset = 0, /* start at the beginning of the chip */ + .sector_size = 0x00010000, /* 64K 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 */ diff --git a/flight/targets/boards/revoproto/firmware/inc/pios_config.h b/flight/targets/boards/revoproto/firmware/inc/pios_config.h index 2e428bd01..27f076daf 100644 --- a/flight/targets/boards/revoproto/firmware/inc/pios_config.h +++ b/flight/targets/boards/revoproto/firmware/inc/pios_config.h @@ -106,6 +106,7 @@ /* #define PIOS_INCLUDE_SDCARD */ /* #define LOG_FILENAME "startup.log" */ #define PIOS_INCLUDE_FLASH +#define PIOS_INCLUDE_FLASH_INTERNAL #define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS #define FLASH_FREERTOS /* #define PIOS_INCLUDE_FLASH_EEPROM */ diff --git a/flight/targets/boards/revoproto/firmware/pios_board.c b/flight/targets/boards/revoproto/firmware/pios_board.c index fbb421bec..394ccf7c0 100644 --- a/flight/targets/boards/revoproto/firmware/pios_board.c +++ b/flight/targets/boards/revoproto/firmware/pios_board.c @@ -306,6 +306,8 @@ uint32_t pios_com_overo_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 @@ -378,6 +380,18 @@ void PIOS_Board_Init(void) { 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*/ if (PIOS_SPI_Init(&pios_spi_accel_id, &pios_spi_accel_cfg)) { PIOS_DEBUG_Assert(0); @@ -392,21 +406,20 @@ void PIOS_Board_Init(void) { if (PIOS_SPI_Init(&pios_spi_flash_id, &pios_spi_flash_cfg)) { PIOS_DEBUG_Assert(0); } + /* 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)) { PIOS_DEBUG_Assert(0); } #else /* 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)) { PIOS_DEBUG_Assert(0); } #endif - if (PIOS_FLASHFS_Logfs_Init(&pios_uavo_settings_fs_id, &flashfs_m25p_cfg, &pios_jedec_flash_driver, flash_id)) { - PIOS_DEBUG_Assert(0); - } + if (PIOS_FLASHFS_Logfs_Init(&pios_user_fs_id, &flashfs_external_cfg, &pios_jedec_flash_driver, flash_id)) { + PIOS_DEBUG_Assert(0); + } #if defined(PIOS_INCLUDE_RTC) PIOS_RTC_Init(&pios_rtc_main_cfg); diff --git a/make/common-defs.mk b/make/common-defs.mk index 76cb43746..4b136efff 100644 --- a/make/common-defs.mk +++ b/make/common-defs.mk @@ -137,6 +137,8 @@ BOARD_CDEFS += -DBL_BANK_BASE=$(BL_BANK_BASE) BOARD_CDEFS += -DBL_BANK_SIZE=$(BL_BANK_SIZE) BOARD_CDEFS += -DBL_DESC_SIZE=$(BL_DESC_SIZE) +BOARD_CDEFS += -DEE_BANK_BASE=$(EE_BANK_BASE) +BOARD_CDEFS += -DEE_BANK_SIZE=$(EE_BANK_SIZE) CDEFS += $(BOARD_CDEFS) ifeq ($(DEBUG), YES) From da23fd678445845b25f75623e9d5973505d41e1c Mon Sep 17 00:00:00 2001 From: sambas Date: Mon, 6 May 2013 18:04:17 +0300 Subject: [PATCH 09/16] Added F1 internal flash driver Conflicts: flight/pios/stm32f10x/pios_flash_internal.c Conflicts: flight/pios/stm32f10x/pios_flash_internal.c --- flight/pios/stm32f10x/pios_flash_internal.c | 291 ++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 flight/pios/stm32f10x/pios_flash_internal.c diff --git a/flight/pios/stm32f10x/pios_flash_internal.c b/flight/pios/stm32f10x/pios_flash_internal.c new file mode 100644 index 000000000..cbae0e068 --- /dev/null +++ b/flight/pios/stm32f10x/pios_flash_internal.c @@ -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 + +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, + §or_number, + §or_start, + §or_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, + §or_number, + §or_start, + §or_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, + §or_number, + §or_start, + §or_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 */ From 8d57d8ff761fb2f025cdd3892d08689890b14719 Mon Sep 17 00:00:00 2001 From: Alessio Morale Date: Sun, 5 May 2013 21:23:35 +0200 Subject: [PATCH 10/16] Internal flash settings for F1 Conflicts: flight/pios/stm32f10x/pios_flash_internal.c --- .../link_STM32103CB_OPLINKMINI_memory.ld | 4 ++-- .../targets/boards/oplinkmini/board-info.mk | 19 +++++++++++++-- .../targets/boards/oplinkmini/board_hw_defs.c | 23 +++++++++++++++++++ .../boards/oplinkmini/firmware/Makefile | 3 +++ .../oplinkmini/firmware/inc/pios_config.h | 5 ++-- .../boards/oplinkmini/firmware/pios_board.c | 9 ++++++++ 6 files changed, 57 insertions(+), 6 deletions(-) diff --git a/flight/pios/stm32f10x/link_STM32103CB_OPLINKMINI_memory.ld b/flight/pios/stm32f10x/link_STM32103CB_OPLINKMINI_memory.ld index 80b110bba..1429d5637 100644 --- a/flight/pios/stm32f10x/link_STM32103CB_OPLINKMINI_memory.ld +++ b/flight/pios/stm32f10x/link_STM32103CB_OPLINKMINI_memory.ld @@ -2,7 +2,7 @@ MEMORY { BL_FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x03000 - 0x00080 BD_INFO (r) : ORIGIN = 0x08003000 - 0x80, LENGTH = 0x00080 - FLASH (rx) : ORIGIN = 0x08003000, LENGTH = 0x20000 - 0x03000 - 0x00400 - EE_FLASH (rw) : ORIGIN = 0x0801FC00, LENGTH = 0x00400 + FLASH (rx) : ORIGIN = 0x08003000, LENGTH = 0x20000 - 0x03000 - 0x04000 + EE_FLASH (rw) : ORIGIN = 0x0801C000, LENGTH = 0x04000 SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x05000 } diff --git a/flight/targets/boards/oplinkmini/board-info.mk b/flight/targets/boards/oplinkmini/board-info.mk index b526c5fa1..d106c63f1 100644 --- a/flight/targets/boards/oplinkmini/board-info.mk +++ b/flight/targets/boards/oplinkmini/board-info.mk @@ -12,12 +12,27 @@ MODEL_SUFFIX := _PX OPENOCD_JTAG_CONFIG := stlink-v2.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 BL_BANK_BASE := 0x08000000 # Start of bootloader flash BL_BANK_SIZE := 0x00003000 # Should include BD_INFO region FW_BANK_BASE := 0x08003000 # Start of firmware flash FW_BANK_SIZE := 0x0001CC00 # Should include FW_DESC_SIZE -EE_BANK_BASE := 0x0801FC00 # EEPROM storage area -EE_BANK_SIZE := 0x00000400 # Size of EEPROM storage area +FW_BANK_SIZE := 0x00019000 # Should include FW_DESC_SIZE +EE_BANK_BASE := 0x0801C000 # EEPROM storage area +EE_BANK_SIZE := 0x00004000 # Size of EEPROM storage area FW_DESC_SIZE := 0x00000064 diff --git a/flight/targets/boards/oplinkmini/board_hw_defs.c b/flight/targets/boards/oplinkmini/board_hw_defs.c index ad8b4eacc..55399732d 100644 --- a/flight/targets/boards/oplinkmini/board_hw_defs.c +++ b/flight/targets/boards/oplinkmini/board_hw_defs.c @@ -99,6 +99,29 @@ const struct pios_led_cfg * PIOS_BOARD_HW_DEFS_GetLedCfg (__attribute__((unused) #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) #include diff --git a/flight/targets/boards/oplinkmini/firmware/Makefile b/flight/targets/boards/oplinkmini/firmware/Makefile index ffbbe8213..78fe7efb7 100644 --- a/flight/targets/boards/oplinkmini/firmware/Makefile +++ b/flight/targets/boards/oplinkmini/firmware/Makefile @@ -56,6 +56,9 @@ else SRC += $(OPTESTS)/$(TESTAPP).c endif +CDEFS += -DEE_BANK_BASE=$(EE_BANK_BASE) +CDEFS += -DEE_BANK_SIZE=$(EE_BANK_SIZE) + # Optional component libraries include $(FLIGHTLIB)/rscode/library.mk diff --git a/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h b/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h index 6d149e4f1..8e58eda34 100644 --- a/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h +++ b/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h @@ -105,8 +105,9 @@ /* #define PIOS_OVERO_SPI */ /* #define PIOS_INCLUDE_SDCARD */ /* #define LOG_FILENAME "startup.log" */ -/* #define PIOS_INCLUDE_FLASH */ -/* #define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS */ +#define PIOS_INCLUDE_FLASH +#define PIOS_INCLUDE_FLASH_INTERNAL +#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS /* #define FLASH_FREERTOS */ #define PIOS_INCLUDE_FLASH_EEPROM diff --git a/flight/targets/boards/oplinkmini/firmware/pios_board.c b/flight/targets/boards/oplinkmini/firmware/pios_board.c index ae2668a32..26675e7f5 100644 --- a/flight/targets/boards/oplinkmini/firmware/pios_board.c +++ b/flight/targets/boards/oplinkmini/firmware/pios_board.c @@ -82,6 +82,15 @@ void PIOS_Board_Init(void) { /* Delay system */ PIOS_DELAY_Init(); +#ifdef PIOS_INCLUDE_FLASH_SECTOR_SETTINGS + uintptr_t flash_id; + uintptr_t fs_id; + PIOS_Flash_Internal_Init(&flash_id, &flash_internal_cfg); + PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_internal_cfg, &pios_internal_flash_driver, flash_id); +#elif !defined(PIOS_USE_SETTINGS_ON_SDCARD) +#error No setting storage specified. (define PIOS_USE_SETTINGS_ON_SDCARD or INCLUDE_FLASH_SECTOR_SETTINGS) +#endif + /* Initialize UAVObject libraries */ EventDispatcherInitialize(); UAVObjInitialize(); From 07af6b5c8018b2c0f0a2802e361b570dc7b52f29 Mon Sep 17 00:00:00 2001 From: Alessio Morale Date: Tue, 7 May 2013 01:29:30 +0200 Subject: [PATCH 11/16] Added LogFS support for OPLinkMini with internal flash --- .../modules/RadioComBridge/RadioComBridge.c | 39 ++++++++++--------- .../oplinkmini/firmware/inc/pios_config.h | 2 +- .../boards/oplinkmini/firmware/pios_board.c | 16 +++----- 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/flight/modules/RadioComBridge/RadioComBridge.c b/flight/modules/RadioComBridge/RadioComBridge.c index 8e047b3b8..d31be7362 100644 --- a/flight/modules/RadioComBridge/RadioComBridge.c +++ b/flight/modules/RadioComBridge/RadioComBridge.c @@ -471,38 +471,41 @@ static void ProcessInputStream(UAVTalkConnection connectionHandle, uint8_t rxbyt switch (obj_per.Operation) { case OBJECTPERSISTENCE_OPERATION_LOAD: { -#if defined(PIOS_INCLUDE_FLASH_EEPROM) +#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) // Load the settings. - OPLinkSettingsData oplinkSettings; - if (PIOS_EEPROM_Load((uint8_t*)&oplinkSettings, sizeof(OPLinkSettingsData)) == 0) - OPLinkSettingsSet(&oplinkSettings); - else + void *obj = UAVObjGetByID(obj_per.ObjectID); + if (obj == 0) { success = false; + } else { + // Load selected instance + success = (UAVObjLoad(obj, obj_per.InstanceID) == 0); + } #endif break; } case OBJECTPERSISTENCE_OPERATION_SAVE: { -#if defined(PIOS_INCLUDE_FLASH_EEPROM) - // Save the settings. - OPLinkSettingsData oplinkSettings; - OPLinkSettingsGet(&oplinkSettings); - int32_t ret = PIOS_EEPROM_Save((uint8_t*)&oplinkSettings, sizeof(OPLinkSettingsData)); - if (ret != 0) +#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) + void *obj = UAVObjGetByID(obj_per.ObjectID); + if (obj == 0) { success = false; + } else { + // Save selected instance + success = UAVObjSave(obj, obj_per.InstanceID) == 0; + } #endif break; } case OBJECTPERSISTENCE_OPERATION_DELETE: { -#if defined(PIOS_INCLUDE_FLASH_EEPROM) - // Erase the settings. - OPLinkSettingsData oplinkSettings; - uint8_t *ptr = (uint8_t*)&oplinkSettings; - memset(ptr, 0, sizeof(OPLinkSettingsData)); - int32_t ret = PIOS_EEPROM_Save(ptr, sizeof(OPLinkSettingsData)); - if (ret != 0) +#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) + void *obj = UAVObjGetByID(obj_per.ObjectID); + if (obj == 0) { success = false; + } else { + // Save selected instance + success = UAVObjDelete(obj, obj_per.InstanceID) == 0; + } #endif break; } diff --git a/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h b/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h index 8e58eda34..b8e0a346e 100644 --- a/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h +++ b/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h @@ -109,7 +109,7 @@ #define PIOS_INCLUDE_FLASH_INTERNAL #define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS /* #define FLASH_FREERTOS */ -#define PIOS_INCLUDE_FLASH_EEPROM +//#define PIOS_INCLUDE_FLASH_EEPROM /* PIOS radio modules */ #define PIOS_INCLUDE_RFM22B diff --git a/flight/targets/boards/oplinkmini/firmware/pios_board.c b/flight/targets/boards/oplinkmini/firmware/pios_board.c index 26675e7f5..dcee1a2ee 100644 --- a/flight/targets/boards/oplinkmini/firmware/pios_board.c +++ b/flight/targets/boards/oplinkmini/firmware/pios_board.c @@ -117,8 +117,6 @@ void PIOS_Board_Init(void) { #endif /* PIOS_INCLUDE_LED */ OPLinkSettingsData oplinkSettings; -#if defined(PIOS_INCLUDE_FLASH_EEPROM) - PIOS_EEPROM_Init(&pios_eeprom_cfg); /* IAP System Setup */ PIOS_IAP_Init(); @@ -128,7 +126,8 @@ void PIOS_Board_Init(void) { PIOS_IAP_ReadBootCmd(2) == PIOS_IAP_CLEAR_FLASH_CMD_2) { OPLinkSettingsGet(&oplinkSettings); 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++) { PIOS_DELAY_WaitmS(100); PIOS_LED_Toggle(PIOS_LED_HEARTBEAT); @@ -137,15 +136,10 @@ void PIOS_Board_Init(void) { PIOS_IAP_WriteBootCmd(1,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); -#endif /* PIOS_INCLUDE_FLASH_EEPROM */ +//#else +// OPLinkSettingsGet(&oplinkSettings); +//#endif /* PIOS_INCLUDE_FLASH_EEPROM */ /* Initialize the task monitor library */ TaskMonitorInitialize(); From 280f537644c6e92f0dde3385dad15fb5adeb58fe Mon Sep 17 00:00:00 2001 From: Stacey Sheldon Date: Sun, 24 Mar 2013 20:41:05 -0400 Subject: [PATCH 12/16] f4 usb: ensure that we NAK on unused OUT endpoints The ST USB code will automatically receive on any endpoint that is opened but not in the NAK state. Make sure we set OUT endpoints to NAK initially. It also happily writes via a NULL pointer in ep->xfer_buff which writes to address 0x0000_0000. Since address 0x0 is aliased onto the internal flash by the BOOT0/1 pins and the internal flash is (normally) in the LOCKED state, this write puts the internal flash into an errored state. This errored state means that writes to internal flash are no longer allowed and all further writes fail. --- flight/pios/stm32f4xx/pios_usbhook.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/flight/pios/stm32f4xx/pios_usbhook.c b/flight/pios/stm32f4xx/pios_usbhook.c index df722b0c0..5f8b1dd0d 100644 --- a/flight/pios/stm32f4xx/pios_usbhook.c +++ b/flight/pios/stm32f4xx/pios_usbhook.c @@ -168,6 +168,20 @@ void PIOS_USBHOOK_RegisterEpOutCallback(uint8_t epnum, uint16_t max_len, pios_us /* * 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) From 71cae382aed45c78b75526688fb31c4fc17f4e39 Mon Sep 17 00:00:00 2001 From: Alessio Morale Date: Tue, 14 May 2013 23:54:50 +0200 Subject: [PATCH 13/16] OP-954 Update OPLink to support the "UAVObject on a specific LogFS instance" updates --- .../targets/boards/oplinkmini/firmware/pios_board.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/flight/targets/boards/oplinkmini/firmware/pios_board.c b/flight/targets/boards/oplinkmini/firmware/pios_board.c index dcee1a2ee..ffc1e78c5 100644 --- a/flight/targets/boards/oplinkmini/firmware/pios_board.c +++ b/flight/targets/boards/oplinkmini/firmware/pios_board.c @@ -72,6 +72,8 @@ uint32_t pios_com_radio_id = 0; uint8_t *pios_uart_rx_buffer; uint8_t *pios_uart_tx_buffer; +uintptr_t pios_uavo_settings_fs_id; + /** * PIOS_Board_Init() * initializes all the core subsystems on this specific hardware @@ -84,11 +86,8 @@ void PIOS_Board_Init(void) { #ifdef PIOS_INCLUDE_FLASH_SECTOR_SETTINGS uintptr_t flash_id; - uintptr_t fs_id; PIOS_Flash_Internal_Init(&flash_id, &flash_internal_cfg); - PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_internal_cfg, &pios_internal_flash_driver, flash_id); -#elif !defined(PIOS_USE_SETTINGS_ON_SDCARD) -#error No setting storage specified. (define PIOS_USE_SETTINGS_ON_SDCARD or INCLUDE_FLASH_SECTOR_SETTINGS) + PIOS_FLASHFS_Logfs_Init(&pios_uavo_settings_fs_id, &flashfs_internal_cfg, &pios_internal_flash_driver, flash_id); #endif /* Initialize UAVObject libraries */ @@ -137,9 +136,7 @@ void PIOS_Board_Init(void) { PIOS_IAP_WriteBootCmd(2,0); } OPLinkSettingsGet(&oplinkSettings); -//#else -// OPLinkSettingsGet(&oplinkSettings); -//#endif /* PIOS_INCLUDE_FLASH_EEPROM */ + /* Initialize the task monitor library */ TaskMonitorInitialize(); From c80f01dff9bbdc18c85cad99d11970d67ca64ee2 Mon Sep 17 00:00:00 2001 From: Alessio Morale Date: Wed, 15 May 2013 23:16:34 +0200 Subject: [PATCH 14/16] OP-954 Rename the legacy PIOS_INCLUDE_FLASH_SECTOR_SETTINGS to PIOS_INCLUDE_FLASH_LOGFS_SETTINGS +review OPReview-470 --- flight/modules/RadioComBridge/RadioComBridge.c | 6 +++--- flight/modules/System/systemmod.c | 2 +- flight/pios/pios.h | 5 ++++- .../boards/coptercontrol/firmware/inc/pios_config.h | 3 ++- .../boards/oplinkmini/firmware/inc/pios_config.h | 2 +- flight/targets/boards/oplinkmini/firmware/pios_board.c | 2 +- flight/targets/boards/osd/firmware/inc/pios_config.h | 2 +- flight/targets/boards/osd/firmware/pios_board.c | 2 +- .../boards/revolution/firmware/inc/pios_config.h | 2 +- .../boards/revoproto/firmware/inc/pios_config.h | 2 +- .../targets/boards/simposix/firmware/inc/pios_config.h | 2 +- flight/uavobjects/uavobjectmanager.c | 10 +++++----- 12 files changed, 22 insertions(+), 18 deletions(-) diff --git a/flight/modules/RadioComBridge/RadioComBridge.c b/flight/modules/RadioComBridge/RadioComBridge.c index d31be7362..6fa47a93f 100644 --- a/flight/modules/RadioComBridge/RadioComBridge.c +++ b/flight/modules/RadioComBridge/RadioComBridge.c @@ -471,7 +471,7 @@ static void ProcessInputStream(UAVTalkConnection connectionHandle, uint8_t rxbyt switch (obj_per.Operation) { case OBJECTPERSISTENCE_OPERATION_LOAD: { -#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) +#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS) // Load the settings. void *obj = UAVObjGetByID(obj_per.ObjectID); if (obj == 0) { @@ -485,7 +485,7 @@ static void ProcessInputStream(UAVTalkConnection connectionHandle, uint8_t rxbyt } case OBJECTPERSISTENCE_OPERATION_SAVE: { -#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) +#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS) void *obj = UAVObjGetByID(obj_per.ObjectID); if (obj == 0) { success = false; @@ -498,7 +498,7 @@ static void ProcessInputStream(UAVTalkConnection connectionHandle, uint8_t rxbyt } case OBJECTPERSISTENCE_OPERATION_DELETE: { -#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) +#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS) void *obj = UAVObjGetByID(obj_per.ObjectID); if (obj == 0) { success = false; diff --git a/flight/modules/System/systemmod.c b/flight/modules/System/systemmod.c index e561b46eb..815badc19 100644 --- a/flight/modules/System/systemmod.c +++ b/flight/modules/System/systemmod.c @@ -310,7 +310,7 @@ static void objectUpdatedCb(UAVObjEvent * ev) retval = UAVObjDeleteMetaobjects(); } } 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); #else retval = -1; diff --git a/flight/pios/pios.h b/flight/pios/pios.h index 3e60ec735..c16fa0f42 100644 --- a/flight/pios/pios.h +++ b/flight/pios/pios.h @@ -270,12 +270,15 @@ #endif #ifdef PIOS_INCLUDE_FLASH -/* #define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS */ +/* #define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS */ /* #define FLASH_FREERTOS */ #include #include #endif +/* driver for storage on internal flash */ +/* #define PIOS_INCLUDE_FLASH_INTERNAL */ + #ifdef PIOS_INCLUDE_FLASH_EEPROM #include #endif diff --git a/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h b/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h index 207920f98..8cb235466 100644 --- a/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h +++ b/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h @@ -106,9 +106,10 @@ /* #define PIOS_INCLUDE_SDCARD */ /* #define LOG_FILENAME "startup.log" */ #define PIOS_INCLUDE_FLASH -#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS +#define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS /* #define FLASH_FREERTOS */ /* #define PIOS_INCLUDE_FLASH_EEPROM */ +/* #define PIOS_INCLUDE_FLASH_INTERNAL */ /* PIOS radio modules */ /* #define PIOS_INCLUDE_RFM22B */ diff --git a/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h b/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h index b8e0a346e..c0a978d21 100644 --- a/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h +++ b/flight/targets/boards/oplinkmini/firmware/inc/pios_config.h @@ -107,7 +107,7 @@ /* #define LOG_FILENAME "startup.log" */ #define PIOS_INCLUDE_FLASH #define PIOS_INCLUDE_FLASH_INTERNAL -#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS +#define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS /* #define FLASH_FREERTOS */ //#define PIOS_INCLUDE_FLASH_EEPROM diff --git a/flight/targets/boards/oplinkmini/firmware/pios_board.c b/flight/targets/boards/oplinkmini/firmware/pios_board.c index ffc1e78c5..dd91756c8 100644 --- a/flight/targets/boards/oplinkmini/firmware/pios_board.c +++ b/flight/targets/boards/oplinkmini/firmware/pios_board.c @@ -84,7 +84,7 @@ void PIOS_Board_Init(void) { /* Delay system */ PIOS_DELAY_Init(); -#ifdef PIOS_INCLUDE_FLASH_SECTOR_SETTINGS +#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); diff --git a/flight/targets/boards/osd/firmware/inc/pios_config.h b/flight/targets/boards/osd/firmware/inc/pios_config.h index 628f6d326..b8caa794e 100644 --- a/flight/targets/boards/osd/firmware/inc/pios_config.h +++ b/flight/targets/boards/osd/firmware/inc/pios_config.h @@ -108,7 +108,7 @@ #define LOG_FILENAME "startup.log" #define PIOS_INCLUDE_FLASH #define PIOS_INCLUDE_FLASH_INTERNAL -#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS +#define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS /* #define FLASH_FREERTOS */ /* #define PIOS_INCLUDE_FLASH_EEPROM */ diff --git a/flight/targets/boards/osd/firmware/pios_board.c b/flight/targets/boards/osd/firmware/pios_board.c index a6f299855..618974472 100644 --- a/flight/targets/boards/osd/firmware/pios_board.c +++ b/flight/targets/boards/osd/firmware/pios_board.c @@ -163,7 +163,7 @@ void PIOS_Board_Init(void) { #endif #endif /* PIOS_INCLUDE_SPI */ -#ifdef PIOS_INCLUDE_FLASH_SECTOR_SETTINGS +#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); diff --git a/flight/targets/boards/revolution/firmware/inc/pios_config.h b/flight/targets/boards/revolution/firmware/inc/pios_config.h index 17112e081..1b75d71c7 100644 --- a/flight/targets/boards/revolution/firmware/inc/pios_config.h +++ b/flight/targets/boards/revolution/firmware/inc/pios_config.h @@ -107,7 +107,7 @@ /* #define LOG_FILENAME "startup.log" */ #define PIOS_INCLUDE_FLASH #define PIOS_INCLUDE_FLASH_INTERNAL -#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS +#define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS #define FLASH_FREERTOS /* #define PIOS_INCLUDE_FLASH_EEPROM */ diff --git a/flight/targets/boards/revoproto/firmware/inc/pios_config.h b/flight/targets/boards/revoproto/firmware/inc/pios_config.h index 27f076daf..ae362b2b1 100644 --- a/flight/targets/boards/revoproto/firmware/inc/pios_config.h +++ b/flight/targets/boards/revoproto/firmware/inc/pios_config.h @@ -107,7 +107,7 @@ /* #define LOG_FILENAME "startup.log" */ #define PIOS_INCLUDE_FLASH #define PIOS_INCLUDE_FLASH_INTERNAL -#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS +#define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS #define FLASH_FREERTOS /* #define PIOS_INCLUDE_FLASH_EEPROM */ diff --git a/flight/targets/boards/simposix/firmware/inc/pios_config.h b/flight/targets/boards/simposix/firmware/inc/pios_config.h index c2413f6c0..71c60bf9f 100644 --- a/flight/targets/boards/simposix/firmware/inc/pios_config.h +++ b/flight/targets/boards/simposix/firmware/inc/pios_config.h @@ -90,7 +90,7 @@ #define PIOS_INCLUDE_SETTINGS #define PIOS_INCLUDE_FLASH /* A really shitty setting saving implementation */ -//#define PIOS_INCLUDE_FLASH_SECTOR_SETTINGS +//#define PIOS_INCLUDE_FLASH_LOGFS_SETTINGS /* Other Interfaces */ //#define PIOS_INCLUDE_I2C_ESC diff --git a/flight/uavobjects/uavobjectmanager.c b/flight/uavobjects/uavobjectmanager.c index 8cfd7c4a8..f0044f951 100644 --- a/flight/uavobjects/uavobjectmanager.c +++ b/flight/uavobjects/uavobjectmanager.c @@ -184,8 +184,8 @@ static int32_t connectObj(UAVObjHandle obj_handle, xQueueHandle queue, static int32_t disconnectObj(UAVObjHandle obj_handle, xQueueHandle queue, UAVObjEventCallback cb); -#if defined(PIOS_USE_SETTINGS_ON_SDCARD) && defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) -#error Both PIOS_USE_SETTINGS_ON_SDCARD and PIOS_INCLUDE_FLASH_SECTOR_SETTINGS. Only one settings storage allowed. +#if defined(PIOS_USE_SETTINGS_ON_SDCARD) && defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS) +#error Both PIOS_USE_SETTINGS_ON_SDCARD and PIOS_INCLUDE_FLASH_LOGFS_SETTINGS. Only one settings storage allowed. #endif #if defined(PIOS_USE_SETTINGS_ON_SDCARD) @@ -794,7 +794,7 @@ int32_t UAVObjSave(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins { PIOS_Assert(obj_handle); -#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) +#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS) if (UAVObjIsMetaobject(obj_handle)) { if (instId != 0) return -1; @@ -948,7 +948,7 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins { PIOS_Assert(obj_handle); -#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) +#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS) if (UAVObjIsMetaobject(obj_handle)) { if (instId != 0) return -1; @@ -1023,7 +1023,7 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins int32_t UAVObjDelete(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t instId) { PIOS_Assert(obj_handle); -#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS) +#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS) PIOS_FLASHFS_ObjDelete(pios_uavo_settings_fs_id, UAVObjGetID(obj_handle), instId); #endif #if defined(PIOS_USE_SETTINGS_ON_SDCARD) From 6ba15ebc53b8115d5229409617712adad7c3af66 Mon Sep 17 00:00:00 2001 From: Alessio Morale Date: Wed, 15 May 2013 23:18:50 +0200 Subject: [PATCH 15/16] OP-954 Fixes from review: - CopterControl target fix - tabs in Nakefiles - Removed duplicate stale settings and clean empty lines in osd Makefile +review OPReview-470 --- .../targets/boards/oplinkmini/board-info.mk | 8 +++--- .../boards/oplinkmini/firmware/Makefile | 3 --- flight/targets/boards/osd/board-info.mk | 26 +++++++++---------- flight/targets/boards/osd/firmware/Makefile | 2 -- .../targets/boards/revolution/board-info.mk | 26 +++++++++---------- make/common-defs.mk | 3 ++- 6 files changed, 32 insertions(+), 36 deletions(-) diff --git a/flight/targets/boards/oplinkmini/board-info.mk b/flight/targets/boards/oplinkmini/board-info.mk index d106c63f1..b275d535e 100644 --- a/flight/targets/boards/oplinkmini/board-info.mk +++ b/flight/targets/boards/oplinkmini/board-info.mk @@ -14,13 +14,13 @@ OPENOCD_CONFIG := stm32f1x.stlink.cfg # Flash memory map for OPLM: # Sector start size use -# 0 0x0800 0000 1k BL -# 1 0x0800 0400 1k BL -# .. .. +# 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 diff --git a/flight/targets/boards/oplinkmini/firmware/Makefile b/flight/targets/boards/oplinkmini/firmware/Makefile index 78fe7efb7..ffbbe8213 100644 --- a/flight/targets/boards/oplinkmini/firmware/Makefile +++ b/flight/targets/boards/oplinkmini/firmware/Makefile @@ -56,9 +56,6 @@ else SRC += $(OPTESTS)/$(TESTAPP).c endif -CDEFS += -DEE_BANK_BASE=$(EE_BANK_BASE) -CDEFS += -DEE_BANK_SIZE=$(EE_BANK_SIZE) - # Optional component libraries include $(FLIGHTLIB)/rscode/library.mk diff --git a/flight/targets/boards/osd/board-info.mk b/flight/targets/boards/osd/board-info.mk index ddd93d3cf..8b9bd4e9d 100644 --- a/flight/targets/boards/osd/board-info.mk +++ b/flight/targets/boards/osd/board-info.mk @@ -14,19 +14,19 @@ OPENOCD_CONFIG := stm32f4xx.stlink.cfg #OPENOCD_CONFIG := stm32f4xx.cfg # Flash memory map for OSD: -# 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 +# 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 BL_BANK_BASE := 0x08000000 # Start of bootloader flash diff --git a/flight/targets/boards/osd/firmware/Makefile b/flight/targets/boards/osd/firmware/Makefile index 211fd65c8..77f7f22ae 100644 --- a/flight/targets/boards/osd/firmware/Makefile +++ b/flight/targets/boards/osd/firmware/Makefile @@ -99,8 +99,6 @@ else SRC += $(OPTESTS)/test_common.c SRC += $(OPTESTS)/$(TESTAPP).c endif - - # Optional component libraries include $(PIOS)/common/libraries/dosfs/library.mk diff --git a/flight/targets/boards/revolution/board-info.mk b/flight/targets/boards/revolution/board-info.mk index 049a8a4f8..f59f4e90f 100644 --- a/flight/targets/boards/revolution/board-info.mk +++ b/flight/targets/boards/revolution/board-info.mk @@ -13,19 +13,19 @@ OPENOCD_JTAG_CONFIG := stlink-v2.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 +# 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 BL_BANK_BASE := 0x08000000 # Start of bootloader flash diff --git a/make/common-defs.mk b/make/common-defs.mk index 4b136efff..80746d8cf 100644 --- a/make/common-defs.mk +++ b/make/common-defs.mk @@ -136,9 +136,10 @@ BOARD_CDEFS += -DFW_DESC_SIZE=$(FW_DESC_SIZE) BOARD_CDEFS += -DBL_BANK_BASE=$(BL_BANK_BASE) BOARD_CDEFS += -DBL_BANK_SIZE=$(BL_BANK_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) ifeq ($(DEBUG), YES) From a7460bfd3c40c9457136d7952d2895af3e0e533d Mon Sep 17 00:00:00 2001 From: Alessio Morale Date: Thu, 16 May 2013 01:18:02 +0200 Subject: [PATCH 16/16] OP-954 Fixes for UT +review OPReview-470 --- flight/tests/logfs/pios_config.h | 3 ++- flight/tests/logfs/pios_flash_ut.c | 21 ++++++++++++++++++++- flight/tests/logfs/pios_flash_ut_priv.h | 1 + flight/tests/logfs/unittest.cpp | 5 ++--- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/flight/tests/logfs/pios_config.h b/flight/tests/logfs/pios_config.h index e6d4f180f..f365e39f6 100644 --- a/flight/tests/logfs/pios_config.h +++ b/flight/tests/logfs/pios_config.h @@ -3,6 +3,7 @@ /* Enable/Disable PiOS modules */ #define PIOS_INCLUDE_FLASH -//#define PIOS_INCLUDE_FREERTOS +//#define PIOS_FLASHFS_LOGFS_MAX_DEVS 5 +#define PIOS_INCLUDE_FREERTOS #endif /* PIOS_CONFIG_H */ diff --git a/flight/tests/logfs/pios_flash_ut.c b/flight/tests/logfs/pios_flash_ut.c index 32a749783..b0d927fca 100644 --- a/flight/tests/logfs/pios_flash_ut.c +++ b/flight/tests/logfs/pios_flash_ut.c @@ -2,7 +2,7 @@ #include /* fopen/fread/fwrite/fseek */ #include /* assert */ #include /* memset */ - +#include #include #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; } +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 diff --git a/flight/tests/logfs/pios_flash_ut_priv.h b/flight/tests/logfs/pios_flash_ut_priv.h index 90a4aeba9..e6c87a800 100644 --- a/flight/tests/logfs/pios_flash_ut_priv.h +++ b/flight/tests/logfs/pios_flash_ut_priv.h @@ -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_Destroy(uintptr_t flash_id); extern const struct pios_flash_driver pios_ut_flash_driver; #if !defined(FLASH_IMAGE_FILE) diff --git a/flight/tests/logfs/unittest.cpp b/flight/tests/logfs/unittest.cpp index 46d6683c1..998280d9a 100644 --- a/flight/tests/logfs/unittest.cpp +++ b/flight/tests/logfs/unittest.cpp @@ -87,7 +87,6 @@ protected: TEST_F(LogfsTestRaw, FlashInit) { uintptr_t flash_id; EXPECT_EQ(0, PIOS_Flash_UT_Init(&flash_id, &flash_config)); - PIOS_Flash_UT_Destroy(flash_id); } @@ -97,11 +96,12 @@ TEST_F(LogfsTestRaw, LogfsInit) { uintptr_t fs_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 { protected: virtual void SetUp() { @@ -109,7 +109,6 @@ protected: LogfsTestRaw::SetUp(); /* 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_FLASHFS_Logfs_Init(&fs_id, &flashfs_config_partition_a, &pios_ut_flash_driver, flash_id)); }