1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-01 09:24:10 +01:00

Modified uavobjectmanager to only use logfs calls for UAVObject flash transactions, abstracted dosfs calls to use logfs wrapper class for simpiosix and SD-card access

This commit is contained in:
Corvus Corax 2013-11-16 17:30:40 +01:00
parent 6aa63c6e96
commit 00321b09dc
6 changed files with 560 additions and 281 deletions

View File

@ -0,0 +1,273 @@
/**
******************************************************************************
* @file pios_dosfs_logfs.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @brief Log Structured Filesystem wrapper implemented using dosfs
*****************************************************************************/
/*
* 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_USE_SETTINGS_ON_SDCARD
#include <openpilot.h>
#if defined(PIOS_INCLUDE_FREERTOS)
static xSemaphoreHandle mutex;
#endif
struct flashfs_logfs_cfg;
/**
* Wrapper for the unimplemented sprintf function
* warning, no buffer length boundary checks, use with caution!
*/
static void customSPrintf(uint8_t *buffer, uint8_t *format, ...)
{
va_list args;
va_start(args, format);
vsprintf((char *)buffer, (char *)format, args);
}
/**
* Get an 8 character (plus extension) filename for the object.
* @param[in] obj The object handle.
* @param[in] instId The instance ID
* @param[in] file Filename string pointer WARNING, must be 14 bytes long and allocated, no checks!
*/
static void objectFilename(uint32_t obj_id, uint16_t obj_inst_id, uint8_t *filename)
{
uint32_t prefix = obj_id + (obj_inst_id / 256);
uint8_t suffix = obj_inst_id & 0xff;
customSPrintf(filename, (uint8_t *)"%08X.o%02X", prefix, suffix);
}
/**
* @brief Initialize the flash object setting FS
* @return 0 if success, -1 if failure
*/
int32_t PIOS_FLASHFS_Logfs_Init(__attribute__((unused)) uintptr_t *fs_id, __attribute__((unused)) const struct flashfs_logfs_cfg *cfg, __attribute__((unused)) const struct pios_flash_driver *driver, __attribute__((unused)) uintptr_t flash_id)
{
#if defined(PIOS_INCLUDE_FREERTOS)
if (!mutex) {
mutex = xSemaphoreCreateRecursiveMutex();
}
#endif
return 0;
}
int32_t PIOS_FLASHFS_Logfs_Destroy(__attribute__((unused)) uintptr_t fs_id)
{
// stub, only wrapper for dosfs, does not need destroying
return 0;
}
/**********************************
*
* Provide a PIOS_FLASHFS_* driver
*
*********************************/
#include "pios_flashfs.h" /* API for flash filesystem */
/**
* @brief Saves one object instance to the filesystem
* @param[in] fs_id The filesystem to use for this action
* @param[in] obj UAVObject ID of the object to save
* @param[in] obj_inst_id The instance number of the object being saved
* @param[in] obj_data Contents of the object being saved
* @param[in] obj_size Size of the object being saved
* @return 0 if success or error code
* @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)) uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t *obj_data, uint16_t obj_size)
{
FILEINFO file;
uint8_t filename[14];
if (PIOS_SDCARD_IsMounted() == 0) {
return -1;
}
// Lock
#if defined(PIOS_INCLUDE_FREERTOS)
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
#endif
// Get filename
objectFilename(obj_id, obj_inst_id, filename);
// Open file
if (PIOS_FOPEN_WRITE(filename, file)) {
#if defined(PIOS_INCLUDE_FREERTOS)
xSemaphoreGiveRecursive(mutex);
#endif
return -2;
}
// Append object
uint32_t bytes_written = 0;
PIOS_FWRITE(&file, obj_data, obj_size, &bytes_written);
// Done, close file and unlock
PIOS_FCLOSE(file);
#if defined(PIOS_INCLUDE_FREERTOS)
xSemaphoreGiveRecursive(mutex);
#endif
if (bytes_written != obj_size) {
return -7;
}
return 0;
}
/**
* @brief Load one object instance from the filesystem
* @param[in] fs_id The filesystem to use for this action
* @param[in] obj UAVObject ID of the object to load
* @param[in] obj_inst_id The instance of the object to load
* @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 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)) uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t *obj_data, uint16_t obj_size)
{
FILEINFO file;
uint8_t filename[14];
// Check for file system availability
if (PIOS_SDCARD_IsMounted() == 0) {
return -1;
}
#if defined(PIOS_INCLUDE_FREERTOS)
// Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
#endif
// Get filename
objectFilename(obj_id, obj_inst_id, filename);
// Open file
if (PIOS_FOPEN_READ(filename, file)) {
#if defined(PIOS_INCLUDE_FREERTOS)
xSemaphoreGiveRecursive(mutex);
#endif
return -1;
}
// Load object
uint32_t bytes_read = 0;
uint32_t result = PIOS_FREAD(&file, obj_data, obj_size, &bytes_read);
// Done, close file and unlock
PIOS_FCLOSE(file);
#if defined(PIOS_INCLUDE_FREERTOS)
xSemaphoreGiveRecursive(mutex);
#endif
if (result != 0) {
return -1;
}
return 0;
}
/**
* @brief Delete one instance of an object from the filesystem
* @param[in] fs_id The filesystem to use for this action
* @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 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)) uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id)
{
uint8_t filename[14];
// Check for file system availability
if (PIOS_SDCARD_IsMounted() == 0) {
return -1;
}
#if defined(PIOS_INCLUDE_FREERTOS)
// Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
#endif
// Get filename
objectFilename(obj_id, obj_inst_id, filename);
// Delete file
PIOS_FUNLINK(filename);
// Done
#if defined(PIOS_INCLUDE_FREERTOS)
xSemaphoreGiveRecursive(mutex);
#endif
return 0;
}
/**
* @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 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)) uintptr_t fs_id)
{
/* stub - not implemented */
return -1;
}
/**
* @brief Returs stats for the filesystems
* @param[in] fs_id The filesystem to use for this action
* @return 0 if success or error code
* @retval -1 if fs_id is not a valid filesystem instance
*/
int32_t PIOS_FLASHFS_GetStats(__attribute__((unused)) uintptr_t fs_id, __attribute__((unused)) struct PIOS_FLASHFS_Stats *stats)
{
/* stub - not implemented */
return 0;
}
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
/**
* @}
* @}
*/

View File

@ -80,6 +80,8 @@ extern void PIOS_LED_Init(void);
#include <pios_debug.h>
#include <pios_crc.h>
#include <pios_rcvr.h>
#include <pios_flash.h>
#include <pios_flashfs.h>
#if defined(PIOS_INCLUDE_IAP)
#include <pios_iap.h>

View File

@ -0,0 +1,273 @@
/**
******************************************************************************
* @file pios_dosfs_logfs.c
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
* @addtogroup PIOS PIOS Core hardware abstraction layer
* @{
* @brief Log Structured Filesystem wrapper implemented using dosfs
*****************************************************************************/
/*
* 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_USE_SETTINGS_ON_SDCARD
#include <openpilot.h>
#if defined(PIOS_INCLUDE_FREERTOS)
static xSemaphoreHandle mutex;
#endif
struct flashfs_logfs_cfg;
/**
* Wrapper for the unimplemented sprintf function
* warning, no buffer length boundary checks, use with caution!
*/
static void customSPrintf(uint8_t *buffer, uint8_t *format, ...)
{
va_list args;
va_start(args, format);
vsprintf((char *)buffer, (char *)format, args);
}
/**
* Get an 8 character (plus extension) filename for the object.
* @param[in] obj The object handle.
* @param[in] instId The instance ID
* @param[in] file Filename string pointer WARNING, must be 14 bytes long and allocated, no checks!
*/
static void objectFilename(uint32_t obj_id, uint16_t obj_inst_id, uint8_t *filename)
{
uint32_t prefix = obj_id + (obj_inst_id / 256);
uint8_t suffix = obj_inst_id & 0xff;
customSPrintf(filename, (uint8_t *)"%08X.o%02X", prefix, suffix);
}
/**
* @brief Initialize the flash object setting FS
* @return 0 if success, -1 if failure
*/
int32_t PIOS_FLASHFS_Logfs_Init(__attribute__((unused)) uintptr_t *fs_id, __attribute__((unused)) const struct flashfs_logfs_cfg *cfg, __attribute__((unused)) const struct pios_flash_driver *driver, __attribute__((unused)) uintptr_t flash_id)
{
#if defined(PIOS_INCLUDE_FREERTOS)
if (!mutex) {
mutex = xSemaphoreCreateRecursiveMutex();
}
#endif
return 0;
}
int32_t PIOS_FLASHFS_Logfs_Destroy(__attribute__((unused)) uintptr_t fs_id)
{
// stub, only wrapper for dosfs, does not need destroying
return 0;
}
/**********************************
*
* Provide a PIOS_FLASHFS_* driver
*
*********************************/
#include "pios_flashfs.h" /* API for flash filesystem */
/**
* @brief Saves one object instance to the filesystem
* @param[in] fs_id The filesystem to use for this action
* @param[in] obj UAVObject ID of the object to save
* @param[in] obj_inst_id The instance number of the object being saved
* @param[in] obj_data Contents of the object being saved
* @param[in] obj_size Size of the object being saved
* @return 0 if success or error code
* @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)) uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t *obj_data, uint16_t obj_size)
{
FILEINFO file;
uint8_t filename[14];
if (PIOS_SDCARD_IsMounted() == 0) {
return -1;
}
// Lock
#if defined(PIOS_INCLUDE_FREERTOS)
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
#endif
// Get filename
objectFilename(obj_id, obj_inst_id, filename);
// Open file
if (PIOS_FOPEN_WRITE(filename, file)) {
#if defined(PIOS_INCLUDE_FREERTOS)
xSemaphoreGiveRecursive(mutex);
#endif
return -2;
}
// Append object
uint32_t bytes_written = 0;
PIOS_FWRITE(&file, obj_data, obj_size, &bytes_written);
// Done, close file and unlock
PIOS_FCLOSE(file);
#if defined(PIOS_INCLUDE_FREERTOS)
xSemaphoreGiveRecursive(mutex);
#endif
if (bytes_written != obj_size) {
return -7;
}
return 0;
}
/**
* @brief Load one object instance from the filesystem
* @param[in] fs_id The filesystem to use for this action
* @param[in] obj UAVObject ID of the object to load
* @param[in] obj_inst_id The instance of the object to load
* @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 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)) uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id, uint8_t *obj_data, uint16_t obj_size)
{
FILEINFO file;
uint8_t filename[14];
// Check for file system availability
if (PIOS_SDCARD_IsMounted() == 0) {
return -1;
}
#if defined(PIOS_INCLUDE_FREERTOS)
// Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
#endif
// Get filename
objectFilename(obj_id, obj_inst_id, filename);
// Open file
if (PIOS_FOPEN_READ(filename, file)) {
#if defined(PIOS_INCLUDE_FREERTOS)
xSemaphoreGiveRecursive(mutex);
#endif
return -1;
}
// Load object
uint32_t bytes_read = 0;
uint32_t result = PIOS_FREAD(&file, obj_data, obj_size, &bytes_read);
// Done, close file and unlock
PIOS_FCLOSE(file);
#if defined(PIOS_INCLUDE_FREERTOS)
xSemaphoreGiveRecursive(mutex);
#endif
if (result != 0) {
return -1;
}
return 0;
}
/**
* @brief Delete one instance of an object from the filesystem
* @param[in] fs_id The filesystem to use for this action
* @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 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)) uintptr_t fs_id, uint32_t obj_id, uint16_t obj_inst_id)
{
uint8_t filename[14];
// Check for file system availability
if (PIOS_SDCARD_IsMounted() == 0) {
return -1;
}
#if defined(PIOS_INCLUDE_FREERTOS)
// Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
#endif
// Get filename
objectFilename(obj_id, obj_inst_id, filename);
// Delete file
PIOS_FUNLINK(filename);
// Done
#if defined(PIOS_INCLUDE_FREERTOS)
xSemaphoreGiveRecursive(mutex);
#endif
return 0;
}
/**
* @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 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)) uintptr_t fs_id)
{
/* stub - not implemented */
return -1;
}
/**
* @brief Returs stats for the filesystems
* @param[in] fs_id The filesystem to use for this action
* @return 0 if success or error code
* @retval -1 if fs_id is not a valid filesystem instance
*/
int32_t PIOS_FLASHFS_GetStats(__attribute__((unused)) uintptr_t fs_id, __attribute__((unused)) struct PIOS_FLASHFS_Stats *stats)
{
/* stub - not implemented */
return 0;
}
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
/**
* @}
* @}
*/

View File

@ -69,3 +69,7 @@ const struct pios_udp_cfg pios_udp_aux_cfg = {
#include <pios_com_priv.h>
#endif /* PIOS_INCLUDE_COM */
#if defined(PIOS_INCLUDE_FLASH)
#include "pios_flashfs_logfs_priv.h"
#endif

View File

@ -75,6 +75,7 @@ uint32_t pios_com_telem_rf_id = 0;
uint32_t pios_com_bridge_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
@ -118,6 +119,13 @@ void PIOS_Board_Init(void)
/* Delay system */
PIOS_DELAY_Init();
// Initialize dosfs fake flash logfs
if (PIOS_FLASHFS_Logfs_Init(&pios_uavo_settings_fs_id, NULL, NULL, 0)) {
PIOS_DEBUG_Assert(0);
}
pios_user_fs_id = pios_uavo_settings_fs_id;
/* Initialize the task monitor */
if (PIOS_TASK_MONITOR_Initialize(TASKINFO_RUNNING_NUMELEM)) {
PIOS_Assert(0);

View File

@ -184,15 +184,6 @@ 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_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)
static void objectFilename(UAVObjHandle obj_handle, uint8_t *filename);
static void customSPrintf(uint8_t *buffer, uint8_t *format, ...);
#endif
// Private variables
static xSemaphoreHandle mutex;
static const UAVObjMetadata defMetadata = {
@ -713,82 +704,6 @@ unlock_exit:
return rc;
}
#if defined(PIOS_USE_SETTINGS_ON_SDCARD)
/**
* Save the data of the specified object instance to the file system (SD card).
* The object will be appended and the file will not be closed.
* The object data can be restored using the UAVObjLoad function.
* @param[in] obj The object handle.
* @param[in] instId The instance ID
* @param[in] file File to append to
* @return 0 if success or -1 if failure
*/
int32_t UAVObjSaveToFile(UAVObjHandle obj_handle, uint16_t instId,
FILEINFO *file)
{
PIOS_Assert(obj_handle);
uint32_t bytesWritten;
// Check for file system availability
if (PIOS_SDCARD_IsMounted() == 0) {
return -1;
}
// Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
if (UAVObjIsMetaobject(obj_handle)) {
// Get the instance information
if (instId != 0) {
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Write the object ID
uint32_t objId = UAVObjGetID(obj_handle);
PIOS_FWRITE(file, &objId, sizeof(objId),
&bytesWritten);
// Write the data and check that the write was successful
PIOS_FWRITE(file, MetaDataPtr((struct UAVOMeta *)obj_handle), MetaNumBytes,
&bytesWritten);
if (bytesWritten != MetaNumBytes) {
xSemaphoreGiveRecursive(mutex);
return -1;
}
} else {
struct UAVOData *uavo;
InstanceHandle instEntry;
// Cast to object
uavo = (struct UAVOData *)obj_handle;
// Get the instance information
instEntry = getInstance(uavo, instId);
if (instEntry == NULL) {
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Write the object ID
PIOS_FWRITE(file, &uavo->id, sizeof(uavo->id),
&bytesWritten);
// Write the instance ID
if (!UAVObjIsSingleInstance(obj_handle)) {
PIOS_FWRITE(file, &instId,
sizeof(instId), &bytesWritten);
}
// Write the data and check that the write was successful
PIOS_FWRITE(file, InstanceData(instEntry), uavo->instance_size,
&bytesWritten);
if (bytesWritten != uavo->instance_size) {
xSemaphoreGiveRecursive(mutex);
return -1;
}
}
// Done
xSemaphoreGiveRecursive(mutex);
return 0;
}
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
/**
* Save the data of the specified object to the file system (SD card).
@ -804,7 +719,6 @@ int32_t UAVObjSave(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins
{
PIOS_Assert(obj_handle);
#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
if (UAVObjIsMetaobject(obj_handle)) {
if (instId != 0) {
return -1;
@ -828,131 +742,9 @@ int32_t UAVObjSave(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins
return -1;
}
}
#endif /* if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS) */
#if defined(PIOS_USE_SETTINGS_ON_SDCARD)
FILEINFO file;
uint8_t filename[14];
// Check for file system availability
if (PIOS_SDCARD_IsMounted() == 0) {
return -1;
}
// Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Get filename
objectFilename(obj_handle, filename);
// Open file
if (PIOS_FOPEN_WRITE(filename, file)) {
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Append object
if (UAVObjSaveToFile(obj_handle, instId, &file) == -1) {
PIOS_FCLOSE(file);
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Done, close file and unlock
PIOS_FCLOSE(file);
xSemaphoreGiveRecursive(mutex);
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
return 0;
}
#if defined(PIOS_USE_SETTINGS_ON_SDCARD)
/**
* Load an object from the file system (SD card).
* @param[in] obj The object handle.
* @param[in] file File to read from
* @return 0 if success or -1 if failure
*/
int32_t UAVObjLoadFromFile(UAVObjHandle obj_handle, FILEINFO *file)
{
uint32_t bytesRead;
struct UAVOBase *objEntry;
InstanceHandle instEntry;
uint32_t objId;
uint16_t instId;
// Check for file system availability
if (PIOS_SDCARD_IsMounted() == 0) {
return -1;
}
// Get the object
if (obj_handle == 0) {
return -1;
}
objEntry = (struct UAVOBase *)obj_handle;
// Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Read the object ID
if (PIOS_FREAD(file, &objId, sizeof(objId), &bytesRead)) {
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Check that the IDs match
if (objId != UAVObjGetID(obj_handle)) {
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Get the instance ID
instId = 0;
if (!UAVObjIsSingleInstance(obj_handle)) {
if (PIOS_FREAD
(file, &instId, sizeof(instId), &bytesRead)) {
xSemaphoreGiveRecursive(mutex);
return -1;
}
}
if (UAVObjIsMetaobject(obj_handle)) {
// If the instance does not exist create it and any other instances before it
if (instId != 0) {
// Error, unlock and return
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Read the instance data
if (PIOS_FREAD
(file, MetaDataPtr((struct UAVOMeta *)obj_handle), MetaNumBytes, &bytesRead)) {
xSemaphoreGiveRecursive(mutex);
return -1;
}
} else {
// Get the instance information
instEntry = getInstance((struct UAVOData *)objEntry, instId);
// If the instance does not exist create it and any other instances before it
if (instEntry == NULL) {
instEntry = createInstance((struct UAVOData *)objEntry, instId);
if (instEntry == NULL) {
// Error, unlock and return
xSemaphoreGiveRecursive(mutex);
return -1;
}
}
// Read the instance data
if (PIOS_FREAD
(file, InstanceData(instEntry), ((struct UAVOData *)objEntry)->instance_size, &bytesRead)) {
xSemaphoreGiveRecursive(mutex);
return -1;
}
}
// Fire event
sendEvent(objEntry, instId, EV_UNPACKED);
// Unlock
xSemaphoreGiveRecursive(mutex);
return 0;
}
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
/**
* Load an object from the file system (SD card).
@ -966,7 +758,6 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins
{
PIOS_Assert(obj_handle);
#if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS)
if (UAVObjIsMetaobject(obj_handle)) {
if (instId != 0) {
return -1;
@ -993,37 +784,7 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, __attribute__((unused)) uint16_t ins
}
}
#endif /* if defined(PIOS_INCLUDE_FLASH_LOGFS_SETTINGS) */
#if defined(PIOS_USE_SETTINGS_ON_SDCARD)
FILEINFO file;
uint8_t filename[14];
// Check for file system availability
if (PIOS_SDCARD_IsMounted() == 0) {
return -1;
}
// Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Get filename
objectFilename(obj_handle, filename);
// Open file
if (PIOS_FOPEN_READ(filename, file)) {
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Load object
if (UAVObjLoadFromFile(obj_handle, &file) != 0) {
PIOS_FCLOSE(file);
xSemaphoreGiveRecursive(mutex);
return -1;
}
// Done, close file and unlock
PIOS_FCLOSE(file);
xSemaphoreGiveRecursive(mutex);
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
return 0;
}
@ -1036,28 +797,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_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];
// Check for file system availability
if (PIOS_SDCARD_IsMounted() == 0) {
return -1;
}
// Lock
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
// Get filename
objectFilename(obj_handle, filename);
// Delete file
PIOS_FUNLINK(filename);
// Done
xSemaphoreGiveRecursive(mutex);
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */
return 0;
}
@ -2043,24 +1783,3 @@ static int32_t disconnectObj(UAVObjHandle obj_handle, xQueueHandle queue,
// If this point is reached the queue was not found
return -1;
}
#if defined(PIOS_USE_SETTINGS_ON_SDCARD)
/**
* Wrapper for the sprintf function
*/
static void customSPrintf(uint8_t *buffer, uint8_t *format, ...)
{
va_list args;
va_start(args, format);
vsprintf((char *)buffer, (char *)format, args);
}
/**
* Get an 8 character (plus extension) filename for the object.
*/
static void objectFilename(UAVObjHandle obj_handle, uint8_t *filename)
{
customSPrintf(filename, (uint8_t *)"%X.obj", UAVObjGetID(obj_handle));
}
#endif /* PIOS_USE_SETTINGS_ON_SDCARD */