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

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

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

View File

@ -471,38 +471,41 @@ static void ProcessInputStream(UAVTalkConnection connectionHandle, uint8_t rxbyt
switch (obj_per.Operation) {
case OBJECTPERSISTENCE_OPERATION_LOAD:
{
#if defined(PIOS_INCLUDE_FLASH_EEPROM)
#if defined(PIOS_INCLUDE_FLASH_LOGFS_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_LOGFS_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_LOGFS_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;
}

View File

@ -318,7 +318,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;

View File

@ -39,7 +39,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;
@ -56,8 +61,6 @@ struct logfs_state {
uintptr_t flash_id;
};
static struct logfs_state logfs;
/*
* Internal Utility functions
*/
@ -66,14 +69,14 @@ static struct logfs_state logfs;
* @brief Return the offset in flash of a particular slot within an arena
* @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));
}
/*
@ -112,27 +115,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) {
@ -149,13 +152,13 @@ static int32_t logfs_erase_arena(uint8_t arena_id)
* @note Arena must have been previously erased before calling this
* @note 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) {
@ -170,7 +173,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) {
@ -186,9 +189,9 @@ 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
@ -197,7 +200,7 @@ static int32_t logfs_erase_all_arenas()
#ifdef PIOS_INCLUDE_WDG
PIOS_WDG_Clear();
#endif
if (logfs_erase_arena(arena) != 0)
if (logfs_erase_arena(logfs, arena) != 0)
return -1;
}
@ -210,13 +213,13 @@ static int32_t logfs_erase_all_arenas()
* @note Arena must have been previously erased or reserved before calling this
* @note 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) {
@ -231,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) {
@ -248,16 +251,16 @@ static int32_t logfs_activate_arena(uint8_t arena_id)
* @note Arena must have been previously active before calling this
* @note 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) {
@ -272,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) {
@ -290,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;
}
@ -349,7 +352,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];
@ -365,7 +368,7 @@ static int32_t logfs_raw_copy_bytes (uintptr_t src_addr, uint16_t src_size, uint
}
/* Read a block of data from source */
if (logfs.driver->read_data(logfs.flash_id,
if (logfs->driver->read_data(logfs->flash_id,
src_addr,
data_block,
blk_size) != 0) {
@ -374,7 +377,7 @@ static int32_t logfs_raw_copy_bytes (uintptr_t src_addr, uint16_t src_size, uint
}
/* Write a block of data to destination */
if (logfs.driver->write_data(logfs.flash_id,
if (logfs->driver->write_data(logfs->flash_id,
dst_addr,
data_block,
blk_size) != 0) {
@ -396,9 +399,9 @@ static int32_t logfs_raw_copy_bytes (uintptr_t src_addr, uint16_t src_size, uint
* true = all slots in the arena are in the ACTIVE state (ie. garbage collection won't free anything)
* false = some slots in the arena are either currently free or could be free'd by garbage collection
*/
static bool logfs_fs_is_full(void)
static bool logfs_fs_is_full(const struct logfs_state * logfs)
{
return (logfs.num_active_slots == (logfs.cfg->arena_size / logfs.cfg->slot_size) - 1);
return (logfs->num_active_slots == (logfs->cfg->arena_size / logfs->cfg->slot_size) - 1);
}
/*
@ -406,37 +409,37 @@ static bool logfs_fs_is_full(void)
* true = there are no unwritten slots left in the log (garbage collection may or may not help)
* 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) {
@ -448,14 +451,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:
@ -464,12 +467,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
@ -490,15 +540,23 @@ int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t * fs_id, const struct flashfs_logfs_cf
PIOS_Assert(driver->write_data);
PIOS_Assert(driver->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;
}
@ -507,16 +565,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;
}
}
@ -528,7 +586,7 @@ int32_t PIOS_FLASHFS_Logfs_Init(uintptr_t * fs_id, const struct flashfs_logfs_cf
}
/* We've found an active arena, mount it */
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;
@ -537,32 +595,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;
}
@ -570,11 +646,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) {
@ -582,8 +658,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 */
@ -597,22 +674,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;
}
@ -620,7 +697,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);
@ -629,11 +706,11 @@ static int16_t logfs_object_find_next (struct slot_header * slot_hdr, uint16_t *
if (*curr_slot == 0) *curr_slot = 1;
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) {
@ -661,7 +738,7 @@ static int16_t logfs_object_find_next (struct slot_header * slot_hdr, uint16_t *
/* NOTE: Must be called while holding the flash transaction lock */
/* 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;
@ -669,13 +746,13 @@ static int8_t logfs_delete_object (uint32_t obj_id, uint16_t obj_inst_id)
uint16_t curr_slot_id = 0;
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) {
@ -683,7 +760,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 */
@ -702,27 +779,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) {
@ -742,7 +819,7 @@ static int8_t logfs_reserve_free_slot (uint16_t * slot_id, struct slot_header *
slot_hdr->obj_inst_id = obj_inst_id;
slot_hdr->obj_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) {
@ -751,33 +828,33 @@ static int8_t logfs_reserve_free_slot (uint16_t * slot_id, struct slot_header *
}
/* FIXME: If the header write (above) failed, may have partially written data, thus corrupting that slot but we would have missed decrementing this counter */
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) {
@ -793,7 +870,7 @@ static int8_t logfs_append_to_log (uint32_t obj_id, uint16_t obj_inst_id, uint8_
/* Mark this slot active in one atomic step */
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) {
@ -802,7 +879,7 @@ static int8_t logfs_append_to_log (uint32_t obj_id, uint16_t obj_inst_id, uint8_
}
/* Object has been successfully written to the slot */
logfs.num_active_slots++;
logfs->num_active_slots++;
return 0;
}
@ -822,26 +899,34 @@ static int8_t logfs_append_to_log (uint32_t obj_id, uint16_t obj_inst_id, uint8_
* @param[in] obj_data Contents of the object being saved
* @param[in] obj_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(uintptr_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;
}
@ -851,36 +936,36 @@ int32_t PIOS_FLASHFS_ObjSave(__attribute__((unused)) uint32_t fs_id, uint32_t ob
*/
/* Check if the arena is entirely full. */
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;
}
@ -888,7 +973,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;
@ -902,47 +987,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(uintptr_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;
}
}
@ -951,7 +1044,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;
@ -963,20 +1056,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(uintptr_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;
}
@ -984,7 +1085,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;
@ -994,46 +1095,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(uintptr_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;

View File

@ -29,9 +29,9 @@
#include <stdint.h>
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 */

View File

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

View File

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

View File

@ -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
}

View File

@ -0,0 +1,291 @@
/**
******************************************************************************
*
* @file pios_flash_internal.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
* @brief brief goes here.
* --
* @see The GNU Public License (GPL) Version 3
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "pios.h"
#ifdef PIOS_INCLUDE_FLASH_INTERNAL
#include "stm32f10x_flash.h"
#include "pios_flash_internal_priv.h"
#include "pios_flash.h"
#include <stdbool.h>
struct device_flash_sector {
uint32_t start;
uint32_t size;
uint16_t st_sector;
};
static bool PIOS_Flash_Internal_GetSectorInfo(uint32_t address, uint8_t * sector_number, uint32_t *sector_start, uint32_t *sector_size)
{
uint16_t sector = (address - 0x08000000) / 1024;
if(sector <= 127) {
/* address lies within this sector */
*sector_number = sector;
*sector_start = sector * 1024 + 0x08000000;
*sector_size = 1024;
return (true);
}
return (false);
}
enum pios_internal_flash_dev_magic {
PIOS_INTERNAL_FLASH_DEV_MAGIC = 0x33445902,
};
struct pios_internal_flash_dev {
enum pios_internal_flash_dev_magic magic;
#if defined(PIOS_INCLUDE_FREERTOS)
xSemaphoreHandle transaction_lock;
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
};
static bool PIOS_Flash_Internal_Validate(struct pios_internal_flash_dev * flash_dev) {
return (flash_dev && (flash_dev->magic == PIOS_INTERNAL_FLASH_DEV_MAGIC));
}
#if defined(PIOS_INCLUDE_FREERTOS)
static struct pios_internal_flash_dev * PIOS_Flash_Internal_alloc(void)
{
struct pios_internal_flash_dev * flash_dev;
flash_dev = (struct pios_internal_flash_dev *)pvPortMalloc(sizeof(* flash_dev));
if (!flash_dev) return (NULL);
flash_dev->magic = PIOS_INTERNAL_FLASH_DEV_MAGIC;
return(flash_dev);
}
#else
static struct pios_internal_flash_dev pios_internal_flash_devs[PIOS_INTERNAL_FLASH_MAX_DEVS];
static uint8_t pios_internal_flash_num_devs;
static struct pios_internal_flash_dev * PIOS_Flash_Internal_alloc(void)
{
struct pios_internal_flash_dev * flash_dev;
if (pios_internal_flash_num_devs >= PIOS_INTERNAL_FLASH_MAX_DEVS) {
return (NULL);
}
flash_dev = &pios_internal_flash_devs[pios_internal_flash_num_devs++];
flash_dev->magic = PIOS_INTERNAL_FLASH_DEV_MAGIC;
return (flash_dev);
}
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
int32_t PIOS_Flash_Internal_Init(uintptr_t * flash_id, __attribute__((unused)) const struct pios_flash_internal_cfg * cfg)
{
struct pios_internal_flash_dev * flash_dev;
flash_dev = PIOS_Flash_Internal_alloc();
if (flash_dev == NULL)
return -1;
#if defined(PIOS_INCLUDE_FREERTOS)
flash_dev->transaction_lock = xSemaphoreCreateMutex();
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
*flash_id = (uintptr_t) flash_dev;
return 0;
}
/**********************************
*
* Provide a PIOS flash driver API
*
*********************************/
#include "pios_flash.h"
static int32_t PIOS_Flash_Internal_StartTransaction(uintptr_t flash_id)
{
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
if (!PIOS_Flash_Internal_Validate(flash_dev))
return -1;
#if defined(PIOS_INCLUDE_FREERTOS)
if (xSemaphoreTake(flash_dev->transaction_lock, portMAX_DELAY) != pdTRUE)
return -2;
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
/* Unlock the internal flash so we can write to it */
FLASH_Unlock();
return 0;
}
static int32_t PIOS_Flash_Internal_EndTransaction(uintptr_t flash_id)
{
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
if (!PIOS_Flash_Internal_Validate(flash_dev))
return -1;
#if defined(PIOS_INCLUDE_FREERTOS)
if (xSemaphoreGive(flash_dev->transaction_lock) != pdTRUE)
return -2;
#endif /* defined(PIOS_INCLUDE_FREERTOS) */
/* Lock the internal flash again so we can no longer write to it */
FLASH_Lock();
return 0;
}
static int32_t PIOS_Flash_Internal_EraseSector(uintptr_t flash_id, uint32_t addr)
{
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
if (!PIOS_Flash_Internal_Validate(flash_dev))
return -1;
uint8_t sector_number;
uint32_t sector_start;
uint32_t sector_size;
if (!PIOS_Flash_Internal_GetSectorInfo(addr,
&sector_number,
&sector_start,
&sector_size)) {
/* We're asking for an invalid flash address */
return -2;
}
if (FLASH_ErasePage(sector_start) != FLASH_COMPLETE)
return -3;
return 0;
}
static int32_t PIOS_Flash_Internal_WriteData(uintptr_t flash_id, uint32_t addr, uint8_t * data, uint16_t len)
{
PIOS_Assert(data);
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
if (!PIOS_Flash_Internal_Validate(flash_dev))
return -1;
uint8_t sector_number;
uint32_t sector_start;
uint32_t sector_size;
uint32_t hword_data;
uint32_t offset;
/* Ensure that the base address is in a valid sector */
if (!PIOS_Flash_Internal_GetSectorInfo(addr,
&sector_number,
&sector_start,
&sector_size)) {
/* We're asking for an invalid flash address */
return -2;
}
/* Ensure that the entire write occurs within the same sector */
if ((uintptr_t)addr + len > sector_start + sector_size) {
/* Write crosses the end of the sector */
return -3;
}
/* Write the data */
uint32_t temp_addr = addr;
uint16_t numberOfhWords = len / 2;
uint16_t x = 0;
FLASH_Status status;
for ( x = 0; x < numberOfhWords; ++x) {
offset = 2 * x;
hword_data = (data[offset + 1] << 8) | data[offset];
if(hword_data != *(uint16_t *)(temp_addr + offset)) {
status = FLASH_ProgramHalfWord(temp_addr + offset, hword_data);
} else {
status = FLASH_COMPLETE;
}
PIOS_Assert(status == FLASH_COMPLETE);
}
uint16_t mod = len % 2;
if(mod == 1) {
offset = 2 * x;
hword_data = 0xFF00 | data[offset];
if(hword_data != *(uint16_t *)(temp_addr + offset)) {
status = FLASH_ProgramHalfWord(temp_addr + offset, hword_data);
} else {
status = FLASH_COMPLETE;
}
PIOS_Assert(status == FLASH_COMPLETE);
}
return 0;
}
static int32_t PIOS_Flash_Internal_ReadData(uintptr_t flash_id, uint32_t addr, uint8_t * data, uint16_t len)
{
PIOS_Assert(data);
struct pios_internal_flash_dev * flash_dev = (struct pios_internal_flash_dev *)flash_id;
if (!PIOS_Flash_Internal_Validate(flash_dev))
return -1;
uint8_t sector_number;
uint32_t sector_start;
uint32_t sector_size;
/* Ensure that the base address is in a valid sector */
if (!PIOS_Flash_Internal_GetSectorInfo(addr,
&sector_number,
&sector_start,
&sector_size)) {
/* We're asking for an invalid flash address */
return -2;
}
/* Ensure that the entire read occurs within the same sector */
if ((uintptr_t)addr + len > sector_start + sector_size) {
/* Read crosses the end of the sector */
return -3;
}
/* Read the data into the buffer directly */
memcpy(data, (void *)addr, len);
return 0;
}
/* Provide a flash driver to external drivers */
const struct pios_flash_driver pios_internal_flash_driver = {
.start_transaction = PIOS_Flash_Internal_StartTransaction,
.end_transaction = PIOS_Flash_Internal_EndTransaction,
.erase_sector = PIOS_Flash_Internal_EraseSector,
.write_data = PIOS_Flash_Internal_WriteData,
.read_data = PIOS_Flash_Internal_ReadData,
};
#endif /* PIOS_INCLUDE_FLASH_INTERNAL */

View File

@ -276,16 +276,20 @@ static int32_t PIOS_Flash_Internal_WriteData(uintptr_t flash_id, uint32_t addr,
/* Write crosses the end of the sector */
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;

View File

@ -168,6 +168,20 @@ void PIOS_USBHOOK_RegisterEpOutCallback(uint8_t epnum, uint16_t max_len, pios_us
/*
* FIXME do not hardcode endpoint type
*/
/*
* 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)

View File

@ -107,9 +107,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 */

View File

@ -76,6 +76,8 @@ uint32_t pios_com_hkosd_id;
uint32_t pios_usb_rctx_id;
uintptr_t pios_uavo_settings_fs_id;
/**
* Configuration for MPU6000 chip
*/
@ -169,13 +171,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;
@ -183,7 +184,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;
@ -205,7 +206,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);

View File

@ -12,13 +12,28 @@ 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

View File

@ -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 <pios_spi_priv.h>

View File

@ -106,10 +106,11 @@
/* #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_LOGFS_SETTINGS
/* #define FLASH_FREERTOS */
#define PIOS_INCLUDE_FLASH_EEPROM
//#define PIOS_INCLUDE_FLASH_EEPROM
/* PIOS radio modules */
#define PIOS_INCLUDE_RFM22B

View File

@ -73,6 +73,8 @@ uint32_t pios_com_radio_id = 0;
uint8_t *pios_uart_rx_buffer;
uint8_t *pios_uart_tx_buffer;
uintptr_t pios_uavo_settings_fs_id;
/**
* PIOS_Board_Init()
* initializes all the core subsystems on this specific hardware
@ -83,6 +85,12 @@ void PIOS_Board_Init(void) {
/* Delay system */
PIOS_DELAY_Init();
#ifdef PIOS_INCLUDE_FLASH_LOGFS_SETTINGS
uintptr_t flash_id;
PIOS_Flash_Internal_Init(&flash_id, &flash_internal_cfg);
PIOS_FLASHFS_Logfs_Init(&pios_uavo_settings_fs_id, &flashfs_internal_cfg, &pios_internal_flash_driver, flash_id);
#endif
/* Initialize UAVObject libraries */
EventDispatcherInitialize();
UAVObjInitialize();
@ -109,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();
@ -120,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);
@ -129,15 +136,8 @@ 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 */
/* Initialize the task monitor */
if (PIOS_TASK_MONITOR_Initialize(TASKINFO_RUNNING_NUMELEM)) {

View File

@ -14,18 +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
# .. ..
# 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

View File

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

View File

@ -109,7 +109,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 */

View File

@ -105,6 +105,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.
@ -162,11 +164,10 @@ 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;
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

View File

@ -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

View File

@ -665,8 +665,9 @@ const struct pios_rfm22b_cfg * PIOS_BOARD_HW_DEFS_GetRfm22Cfg (uint32_t board_re
#if defined(PIOS_INCLUDE_FLASH)
#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 <pios_usart_priv.h>

View File

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

View File

@ -236,6 +236,9 @@ uint32_t pios_com_hkosd_id = 0;
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
*/
@ -349,13 +352,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);
}
uintptr_t fs_id;
if (PIOS_FLASHFS_Logfs_Init(&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
@ -370,7 +383,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);

View File

@ -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

View File

@ -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 */

View File

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

View File

@ -306,6 +306,10 @@ uint32_t pios_com_bridge_id = 0;
uint32_t pios_com_overo_id = 0;
uint32_t pios_com_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
*/
@ -377,6 +381,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);
@ -391,22 +407,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
uintptr_t fs_id;
if (PIOS_FLASHFS_Logfs_Init(&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);
@ -419,7 +433,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);

View File

@ -91,7 +91,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

View File

@ -74,6 +74,8 @@ uint32_t pios_com_telem_usb_id = 0;
uint32_t pios_com_telem_rf_id = 0;
uint32_t pios_com_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
*/

View File

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

View File

@ -1,9 +1,14 @@
#ifndef PIOS_H
#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 <pios_flash.h>
#include <pios_flashfs.h>

View File

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

View File

@ -2,7 +2,7 @@
#include <stdio.h> /* fopen/fread/fwrite/fseek */
#include <assert.h> /* assert */
#include <string.h> /* memset */
#include <unistd.h>
#include <stdbool.h>
#include "pios_flash_ut_priv.h"
@ -55,6 +55,25 @@ int32_t PIOS_Flash_UT_Init(uintptr_t * flash_id, const struct pios_flash_ut_cfg
return 0;
}
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

View File

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

View File

@ -13,7 +13,8 @@ extern struct pios_flash_ut_cfg flash_config;
#include "pios_flashfs_logfs_priv.h"
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,11 +81,13 @@ 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) {
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) {
@ -84,7 +95,9 @@ 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);
}
class LogfsTestCooked : public LogfsTestRaw {
@ -94,14 +107,33 @@ 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, &pios_ut_flash_driver, flash_id));
EXPECT_EQ(0, PIOS_FLASHFS_Logfs_Init(&fs_id, &flashfs_config_partition_a, &pios_ut_flash_driver, flash_id));
}
virtual void TearDown() {
PIOS_FLASHFS_Logfs_Destroy(fs_id);
PIOS_Flash_UT_Destroy(flash_id);
}
uintptr_t flash_id;
uintptr_t fs_id;
};
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 +161,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) {
@ -170,7 +202,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)));
}
@ -178,7 +210,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) {
@ -203,12 +235,12 @@ 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)));
}
/* 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)));
@ -257,3 +289,97 @@ TEST_F(LogfsTestCooked, WriteManyVerify) {
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id, OBJ3_ID, 0, obj3_check, sizeof(obj3_check)));
EXPECT_EQ(0, memcmp(obj3, obj3_check, sizeof(obj3)));
}
class LogfsTestCookedMultiPart : public LogfsTestRaw {
protected:
virtual void SetUp() {
/* First, we need to set up the super fixture (LogfsTestRaw) */
LogfsTestRaw::SetUp();
/* Init the flash and the flashfs so we don't need to repeat this in every test */
EXPECT_EQ(0, PIOS_Flash_UT_Init(&flash_id, &flash_config));
EXPECT_EQ(0, PIOS_FLASHFS_Logfs_Init(&fs_id_a, &flashfs_config_partition_a, &pios_ut_flash_driver, flash_id));
EXPECT_EQ(0, PIOS_FLASHFS_Logfs_Init(&fs_id_b, &flashfs_config_partition_b, &pios_ut_flash_driver, flash_id));
}
virtual void TearDown() {
PIOS_FLASHFS_Logfs_Destroy(fs_id_b);
PIOS_FLASHFS_Logfs_Destroy(fs_id_a);
PIOS_Flash_UT_Destroy(flash_id);
}
uintptr_t flash_id;
uintptr_t fs_id_a;
uintptr_t fs_id_b;
};
TEST_F(LogfsTestCookedMultiPart, WriteOneWriteOneVerify) {
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_a, OBJ1_ID, 0, obj1, sizeof(obj1)));
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_b, OBJ2_ID, 0, obj2, sizeof(obj2)));
/* OBJ1 found in A */
unsigned char obj1_check[OBJ1_SIZE];
memset(obj1_check, 0, sizeof(obj1_check));
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id_a, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
EXPECT_EQ(0, memcmp(obj1, obj1_check, sizeof(obj1)));
/* OBJ2 found in B */
unsigned char obj2_check[OBJ2_SIZE];
memset(obj2_check, 0, sizeof(obj2_check));
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id_b, OBJ2_ID, 0, obj2_check, sizeof(obj2_check)));
EXPECT_EQ(0, memcmp(obj2, obj2_check, sizeof(obj2)));
}
TEST_F(LogfsTestCookedMultiPart, WriteOneWriteOneFormatOneVerify) {
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_a, OBJ1_ID, 0, obj1, sizeof(obj1)));
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_b, OBJ2_ID, 0, obj2, sizeof(obj2)));
EXPECT_EQ(0, PIOS_FLASHFS_Format(fs_id_a));
/* OBJ2 still found in B */
unsigned char obj2_check[OBJ2_SIZE];
memset(obj2_check, 0, sizeof(obj2_check));
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id_b, OBJ2_ID, 0, obj2_check, sizeof(obj2_check)));
EXPECT_EQ(0, memcmp(obj2, obj2_check, sizeof(obj2)));
}
TEST_F(LogfsTestCookedMultiPart, WriteOneWriteOneNoCross) {
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_a, OBJ1_ID, 0, obj1, sizeof(obj1)));
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_b, OBJ2_ID, 0, obj2, sizeof(obj2)));
/* OBJ1 not found in B */
unsigned char obj1_check[OBJ1_SIZE];
memset(obj1_check, 0, sizeof(obj1_check));
EXPECT_EQ(-3, PIOS_FLASHFS_ObjLoad(fs_id_b, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
/* OBJ2 not found in A */
unsigned char obj2_check[OBJ2_SIZE];
memset(obj2_check, 0, sizeof(obj2_check));
EXPECT_EQ(-3, PIOS_FLASHFS_ObjLoad(fs_id_a, OBJ2_ID, 0, obj2_check, sizeof(obj2_check)));
}
TEST_F(LogfsTestCookedMultiPart, WriteOneWriteOneDeleteOne) {
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_a, OBJ1_ID, 0, obj1, sizeof(obj1)));
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_b, OBJ2_ID, 0, obj2, sizeof(obj2)));
EXPECT_EQ(0, PIOS_FLASHFS_ObjDelete(fs_id_a, OBJ1_ID, 0));
/* OBJ1 not found in A */
unsigned char obj1_check[OBJ1_SIZE];
memset(obj1_check, 0, sizeof(obj1_check));
EXPECT_EQ(-3, PIOS_FLASHFS_ObjLoad(fs_id_a, OBJ1_ID, 0, obj1_check, sizeof(obj1_check)));
/* OBJ2 still found in B */
unsigned char obj2_check[OBJ2_SIZE];
memset(obj2_check, 0, sizeof(obj2_check));
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id_b, OBJ2_ID, 0, obj2_check, sizeof(obj2_check)));
}
TEST_F(LogfsTestCookedMultiPart, WriteLarge) {
EXPECT_EQ(0, PIOS_FLASHFS_ObjSave(fs_id_b, OBJ4_ID, 0, obj4, sizeof(obj4)));
/* OBJ4 found in B */
unsigned char obj4_check[OBJ4_SIZE];
memset(obj4_check, 0, sizeof(obj4_check));
EXPECT_EQ(0, PIOS_FLASHFS_ObjLoad(fs_id_b, OBJ4_ID, 0, obj4_check, sizeof(obj4_check)));
}

View File

@ -7,15 +7,15 @@
const struct pios_flash_ut_cfg flash_config = {
.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 */
};

View File

@ -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 <mach-o/getsect.h>
#endif
@ -182,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)
@ -792,12 +794,12 @@ 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;
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 +810,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
@ -946,13 +948,13 @@ 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;
// 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;
@ -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;
@ -1021,8 +1023,8 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins
int32_t UAVObjDelete(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t instId)
{
PIOS_Assert(obj_handle);
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
PIOS_FLASHFS_ObjDelete(0, UAVObjGetID(obj_handle), instId);
#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)
uint8_t filename[14];

View File

@ -137,7 +137,10 @@ BOARD_CDEFS += -DFW_DESC_SIZE=$(FW_DESC_SIZE)
BOARD_CDEFS += -DBL_BANK_BASE=$(BL_BANK_BASE)
BOARD_CDEFS += -DBL_BANK_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)