mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-27 16:54:15 +01:00
Merge branch 'OP-499_216_Saving'
This commit is contained in:
commit
eb2d094a66
@ -205,6 +205,7 @@ SRC += $(PIOSSTM32F10X)/pios_usb_hid_prop.c
|
|||||||
SRC += $(PIOSSTM32F10X)/pios_usb_hid_pwr.c
|
SRC += $(PIOSSTM32F10X)/pios_usb_hid_pwr.c
|
||||||
|
|
||||||
## PIOS Hardware (Common)
|
## PIOS Hardware (Common)
|
||||||
|
SRC += $(PIOSCOMMON)/pios_flashfs_objlist.c
|
||||||
SRC += $(PIOSCOMMON)/pios_flash_w25x.c
|
SRC += $(PIOSCOMMON)/pios_flash_w25x.c
|
||||||
SRC += $(PIOSCOMMON)/pios_adxl345.c
|
SRC += $(PIOSCOMMON)/pios_adxl345.c
|
||||||
SRC += $(PIOSCOMMON)/pios_com.c
|
SRC += $(PIOSCOMMON)/pios_com.c
|
||||||
|
@ -681,6 +681,8 @@ void PIOS_Board_Init(void) {
|
|||||||
PIOS_Flash_W25X_Init(pios_spi_flash_accel_id);
|
PIOS_Flash_W25X_Init(pios_spi_flash_accel_id);
|
||||||
PIOS_ADXL345_Attach(pios_spi_flash_accel_id);
|
PIOS_ADXL345_Attach(pios_spi_flash_accel_id);
|
||||||
|
|
||||||
|
PIOS_FLASHFS_Init();
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_SPEKTRUM)
|
#if defined(PIOS_INCLUDE_SPEKTRUM)
|
||||||
/* SPEKTRUM init must come before comms */
|
/* SPEKTRUM init must come before comms */
|
||||||
PIOS_SPEKTRUM_Init();
|
PIOS_SPEKTRUM_Init();
|
||||||
|
@ -222,6 +222,14 @@ int8_t PIOS_Flash_W25X_WriteData(uint32_t addr, uint8_t * data, uint16_t len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read data from a location in flash memory
|
||||||
|
* @param[in] addr Address in flash to write to
|
||||||
|
* @param[in] data Pointer to data to write from flash
|
||||||
|
* @param[in] len Length of data to write (max 256 bytes)
|
||||||
|
* @return Zero if success or error code
|
||||||
|
* @retval -1 Unable to claim SPI bus
|
||||||
|
*/
|
||||||
int8_t PIOS_Flash_W25X_ReadData(uint32_t addr, uint8_t * data, uint16_t len)
|
int8_t PIOS_Flash_W25X_ReadData(uint32_t addr, uint8_t * data, uint16_t len)
|
||||||
{
|
{
|
||||||
if(PIOS_Flash_W25X_ClaimBus() == -1)
|
if(PIOS_Flash_W25X_ClaimBus() == -1)
|
||||||
|
294
flight/PiOS/Common/pios_flashfs_objlist.c
Normal file
294
flight/PiOS/Common/pios_flashfs_objlist.c
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||||
|
* @{
|
||||||
|
* @addtogroup PIOS_FLASHFS_OBJLIST Object list based flash filesystem (low ram)
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file pios_flashfs_objlist.c
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @brief A file system for storing UAVObject in flash chip
|
||||||
|
* @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 "openpilot.h"
|
||||||
|
#include "uavobjectmanager.h"
|
||||||
|
|
||||||
|
// Private functions
|
||||||
|
static int32_t PIOS_FLASHFS_CleabObjectTableHeader();
|
||||||
|
static int32_t PIOS_FLASHFS_GetObjAddress(uint32_t objId, uint16_t instId);
|
||||||
|
static int32_t PIOS_FLASHFS_GetNewAddress(uint32_t objId, uint16_t instId);
|
||||||
|
|
||||||
|
// Private variables
|
||||||
|
static int32_t numObjects = -1;
|
||||||
|
|
||||||
|
// Private structures
|
||||||
|
// Header for objects in the file system table
|
||||||
|
struct objectHeader {
|
||||||
|
uint32_t objMagic;
|
||||||
|
uint32_t objId;
|
||||||
|
uint32_t instId;
|
||||||
|
uint32_t address;
|
||||||
|
} __attribute__((packed));;
|
||||||
|
|
||||||
|
struct fileHeader {
|
||||||
|
uint32_t id;
|
||||||
|
uint16_t instId;
|
||||||
|
uint16_t size;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
|
#define OBJECT_TABLE_MAGIC 0x85FB3C33
|
||||||
|
#define OBJ_MAGIC 0x3015AE71
|
||||||
|
#define OBJECT_TABLE_START 0x00000010
|
||||||
|
#define OBJECT_TABLE_END 0x00001000
|
||||||
|
#define SECTOR_SIZE 0x00001000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the flash object setting FS
|
||||||
|
* @return 0 if success, -1 if failure
|
||||||
|
*/
|
||||||
|
int32_t PIOS_FLASHFS_Init()
|
||||||
|
{
|
||||||
|
|
||||||
|
// Check for valid object table or create one
|
||||||
|
uint32_t object_table_magic;
|
||||||
|
if (PIOS_Flash_W25X_ReadData(0, (uint8_t *)&object_table_magic, sizeof(object_table_magic)) != 0)
|
||||||
|
return -1;
|
||||||
|
if(object_table_magic != OBJECT_TABLE_MAGIC) {
|
||||||
|
if(PIOS_FLASHFS_CleabObjectTableHeader() < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t addr = OBJECT_TABLE_START;
|
||||||
|
struct objectHeader header;
|
||||||
|
numObjects = 0;
|
||||||
|
|
||||||
|
// Loop through header area while objects detect to count how many saved
|
||||||
|
while(addr < OBJECT_TABLE_END) {
|
||||||
|
// Read the instance data
|
||||||
|
if (PIOS_Flash_W25X_ReadData(addr, (uint8_t *)&header, sizeof(header)) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// Counting number of valid headers
|
||||||
|
if(header.objMagic != OBJ_MAGIC)
|
||||||
|
break;
|
||||||
|
|
||||||
|
numObjects++;
|
||||||
|
addr += sizeof(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase the headers for all objects in the flash chip
|
||||||
|
* @return 0 if successful, -1 if not
|
||||||
|
*/
|
||||||
|
static int32_t PIOS_FLASHFS_CleabObjectTableHeader()
|
||||||
|
{
|
||||||
|
if(PIOS_Flash_W25X_EraseSector(OBJECT_TABLE_START) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
uint32_t object_table_magic = OBJECT_TABLE_MAGIC;
|
||||||
|
if (PIOS_Flash_W25X_WriteData(0, (uint8_t *)&object_table_magic, sizeof(object_table_magic)) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the address of an object
|
||||||
|
* @param obj UAVObjHandle for that object
|
||||||
|
* @parma instId Instance id for that object
|
||||||
|
* @return address if successful, -1 if not found
|
||||||
|
*/
|
||||||
|
static int32_t PIOS_FLASHFS_GetObjAddress(uint32_t objId, uint16_t instId)
|
||||||
|
{
|
||||||
|
int32_t addr = OBJECT_TABLE_START;
|
||||||
|
struct objectHeader header;
|
||||||
|
|
||||||
|
// Loop through header area while objects detect to count how many saved
|
||||||
|
while(addr < OBJECT_TABLE_END) {
|
||||||
|
// Read the instance data
|
||||||
|
if (PIOS_Flash_W25X_ReadData(addr, (uint8_t *) &header, sizeof(header)) != 0)
|
||||||
|
return -1;
|
||||||
|
if(header.objMagic != OBJ_MAGIC)
|
||||||
|
break; // stop searching once hit first non-object header
|
||||||
|
else if (header.objId == objId && header.instId == instId)
|
||||||
|
break;
|
||||||
|
addr += sizeof(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.objId == objId && header.instId == instId)
|
||||||
|
return header.address;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns an address for a new object and creates entry into object table
|
||||||
|
* @param[in] obj Object handle for object to be saved
|
||||||
|
* @param[in] instId The instance id of object to be saved
|
||||||
|
* @return 0 if success or error code
|
||||||
|
* @retval -1 Object not found
|
||||||
|
* @retval -2 No room in object table
|
||||||
|
* @retval -3 Unable to write entry into object table
|
||||||
|
* @retval -4 FS not initialized
|
||||||
|
*/
|
||||||
|
int32_t PIOS_FLASHFS_GetNewAddress(uint32_t objId, uint16_t instId)
|
||||||
|
{
|
||||||
|
struct objectHeader header;
|
||||||
|
|
||||||
|
if(numObjects < 0)
|
||||||
|
return -4;
|
||||||
|
|
||||||
|
// Don't worry about max size of flash chip here, other code will catch that
|
||||||
|
header.objMagic = OBJ_MAGIC;
|
||||||
|
header.objId = objId;
|
||||||
|
header.instId = instId;
|
||||||
|
header.address = OBJECT_TABLE_END + SECTOR_SIZE * numObjects;
|
||||||
|
|
||||||
|
int32_t addr = OBJECT_TABLE_START + sizeof(header) * numObjects;
|
||||||
|
|
||||||
|
// No room for this header in object table
|
||||||
|
if((addr + sizeof(header)) > OBJECT_TABLE_END)
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
if(PIOS_Flash_W25X_WriteData(addr, (uint8_t *) &header, sizeof(header)) != 0)
|
||||||
|
return -3;
|
||||||
|
|
||||||
|
// This numObejcts value must stay consistent or there will be a break in the table
|
||||||
|
// and later the table will have bad values in it
|
||||||
|
numObjects++;
|
||||||
|
return header.address;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Saves one object instance per sector
|
||||||
|
* @param[in] obj UAVObjHandle the object to save
|
||||||
|
* @param[in] instId The instance of the object to save
|
||||||
|
* @return 0 if success or -1 if failure
|
||||||
|
* @note This uses one sector on the flash chip per object so that no buffering in ram
|
||||||
|
* must be done when erasing the sector before a save
|
||||||
|
*/
|
||||||
|
int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data)
|
||||||
|
{
|
||||||
|
uint32_t objId = UAVObjGetID(obj);
|
||||||
|
|
||||||
|
int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId);
|
||||||
|
|
||||||
|
// Object currently not saved
|
||||||
|
if(addr < 0)
|
||||||
|
addr = PIOS_FLASHFS_GetNewAddress(objId, instId);
|
||||||
|
|
||||||
|
// Could not allocate a sector
|
||||||
|
if(addr < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct fileHeader header = {
|
||||||
|
.id = objId,
|
||||||
|
.instId = instId,
|
||||||
|
.size = UAVObjGetNumBytes(obj)
|
||||||
|
};
|
||||||
|
|
||||||
|
if(PIOS_Flash_W25X_EraseSector(addr) != 0)
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
// Save header
|
||||||
|
// This information IS redundant with the object table id. Oh well. Better safe than sorry.
|
||||||
|
|
||||||
|
if(PIOS_Flash_W25X_WriteData(addr, (uint8_t *) &header, sizeof(header)) != 0)
|
||||||
|
return -3;
|
||||||
|
|
||||||
|
// Save data
|
||||||
|
if(PIOS_Flash_W25X_WriteData(addr + sizeof(header), data, UAVObjGetNumBytes(obj)) != 0)
|
||||||
|
return -4;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load one object instance per sector
|
||||||
|
* @param[in] obj UAVObjHandle the object to save
|
||||||
|
* @param[in] instId The instance of the object to save
|
||||||
|
* @return 0 if success or error code
|
||||||
|
* @retval -1 if object not in file table
|
||||||
|
* @retval -2 if unable to retrieve object header
|
||||||
|
* @retval -3 if loaded data instId or objId don't match
|
||||||
|
* @retval -4 if unable to retrieve instance data
|
||||||
|
* @note This uses one sector on the flash chip per object so that no buffering in ram
|
||||||
|
* must be done when erasing the sector before a save
|
||||||
|
*/
|
||||||
|
int32_t PIOS_FLASHFS_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data)
|
||||||
|
{
|
||||||
|
uint32_t objId = UAVObjGetID(obj);
|
||||||
|
|
||||||
|
int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId);
|
||||||
|
|
||||||
|
// Object currently not saved
|
||||||
|
if(addr < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct fileHeader header;
|
||||||
|
|
||||||
|
// Load header
|
||||||
|
// This information IS redundant with the object table id. Oh well. Better safe than sorry.
|
||||||
|
if(PIOS_Flash_W25X_ReadData(addr, (uint8_t *) &header, sizeof(header)) != 0)
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
if((header.id != objId) || (header.instId != instId))
|
||||||
|
return -3;
|
||||||
|
|
||||||
|
// Read the instance data
|
||||||
|
if (PIOS_Flash_W25X_ReadData(addr + sizeof(header), data, UAVObjGetNumBytes(obj)) != 0)
|
||||||
|
return -4;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete object from flash
|
||||||
|
* @param[in] obj UAVObjHandle the object to save
|
||||||
|
* @param[in] instId The instance of the object to save
|
||||||
|
* @return 0 if success or error code
|
||||||
|
* @retval -1 if object not in file table
|
||||||
|
* @retval -2 Erase failed
|
||||||
|
* @note To avoid buffering the file table (1k ram!) the entry in the file table
|
||||||
|
* remains but destination sector is erased. This will make the load fail as the
|
||||||
|
* file header won't match the object. At next save it goes back there.
|
||||||
|
*/
|
||||||
|
int32_t PIOS_FLASHFS_ObjDelete(UAVObjHandle obj, uint16_t instId)
|
||||||
|
{
|
||||||
|
uint32_t objId = UAVObjGetID(obj);
|
||||||
|
|
||||||
|
int32_t addr = PIOS_FLASHFS_GetObjAddress(objId, instId);
|
||||||
|
|
||||||
|
// Object currently not saved
|
||||||
|
if(addr < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if(PIOS_Flash_W25X_EraseSector(addr) != 0)
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
37
flight/PiOS/inc/pios_flashfs_objlist.h
Normal file
37
flight/PiOS/inc/pios_flashfs_objlist.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||||||
|
* @{
|
||||||
|
* @addtogroup PIOS_FLASHFS_OBJLIST Object list based flash filesystem (low ram)
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file pios_flashfs_objlist.h
|
||||||
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||||
|
* @brief A file system for storing UAVObject in flash chip
|
||||||
|
* @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 "openpilot.h"
|
||||||
|
#include "uavobjectmanager.h"
|
||||||
|
|
||||||
|
int32_t PIOS_FLASHFS_Init();
|
||||||
|
int32_t PIOS_FLASHFS_ObjSave(UAVObjHandle obj, uint16_t instId, uint8_t * data);
|
||||||
|
int32_t PIOS_FLASHFS_ObjLoad(UAVObjHandle obj, uint16_t instId, uint8_t * data);
|
||||||
|
int32_t PIOS_FLASHFS_ObjDelete(UAVObjHandle obj, uint16_t instId);
|
@ -119,6 +119,7 @@
|
|||||||
|
|
||||||
#if defined(PIOS_INCLUDE_FLASH)
|
#if defined(PIOS_INCLUDE_FLASH)
|
||||||
#include <pios_flash_w25x.h>
|
#include <pios_flash_w25x.h>
|
||||||
|
#include <pios_flashfs_objlist.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_BL_HELPER)
|
#if defined(PIOS_INCLUDE_BL_HELPER)
|
||||||
|
@ -3171,6 +3171,8 @@
|
|||||||
65FF4BE913791C3300146BE4 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
|
65FF4BE913791C3300146BE4 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
|
||||||
65FF4BEA13791C3300146BE4 /* op_dfu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = op_dfu.c; sourceTree = "<group>"; };
|
65FF4BEA13791C3300146BE4 /* op_dfu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = op_dfu.c; sourceTree = "<group>"; };
|
||||||
65FF4BEB13791C3300146BE4 /* pios_board.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pios_board.c; sourceTree = "<group>"; };
|
65FF4BEB13791C3300146BE4 /* pios_board.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pios_board.c; sourceTree = "<group>"; };
|
||||||
|
65FF4D5E137EDEC100146BE4 /* pios_flashfs_objlist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pios_flashfs_objlist.c; sourceTree = "<group>"; };
|
||||||
|
65FF4D61137EFA4F00146BE4 /* pios_flashfs_objlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pios_flashfs_objlist.h; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
@ -7657,6 +7659,7 @@
|
|||||||
65E8F03711EFF25C00BBF654 /* printf-stdarg.c */,
|
65E8F03711EFF25C00BBF654 /* printf-stdarg.c */,
|
||||||
6528CCB412E406B800CF5144 /* pios_adxl345.c */,
|
6528CCB412E406B800CF5144 /* pios_adxl345.c */,
|
||||||
6512D60712ED4CB8008175E5 /* pios_flash_w25x.c */,
|
6512D60712ED4CB8008175E5 /* pios_flash_w25x.c */,
|
||||||
|
65FF4D5E137EDEC100146BE4 /* pios_flashfs_objlist.c */,
|
||||||
);
|
);
|
||||||
name = Common;
|
name = Common;
|
||||||
path = ../../PiOS/Common;
|
path = ../../PiOS/Common;
|
||||||
@ -7681,6 +7684,7 @@
|
|||||||
65E8F03E11EFF25C00BBF654 /* pios_debug.h */,
|
65E8F03E11EFF25C00BBF654 /* pios_debug.h */,
|
||||||
65E8F03F11EFF25C00BBF654 /* pios_delay.h */,
|
65E8F03F11EFF25C00BBF654 /* pios_delay.h */,
|
||||||
65E8F04011EFF25C00BBF654 /* pios_exti.h */,
|
65E8F04011EFF25C00BBF654 /* pios_exti.h */,
|
||||||
|
65FF4D61137EFA4F00146BE4 /* pios_flashfs_objlist.h */,
|
||||||
65E8F04111EFF25C00BBF654 /* pios_gpio.h */,
|
65E8F04111EFF25C00BBF654 /* pios_gpio.h */,
|
||||||
65E8F04211EFF25C00BBF654 /* pios_hmc5843.h */,
|
65E8F04211EFF25C00BBF654 /* pios_hmc5843.h */,
|
||||||
65E8F04311EFF25C00BBF654 /* pios_i2c.h */,
|
65E8F04311EFF25C00BBF654 /* pios_i2c.h */,
|
||||||
|
@ -44,7 +44,7 @@ struct ObjectEventListStruct {
|
|||||||
xQueueHandle queue;
|
xQueueHandle queue;
|
||||||
UAVObjEventCallback cb;
|
UAVObjEventCallback cb;
|
||||||
int32_t eventMask;
|
int32_t eventMask;
|
||||||
struct ObjectEventListStruct* next;
|
struct ObjectEventListStruct *next;
|
||||||
};
|
};
|
||||||
typedef struct ObjectEventListStruct ObjectEventList;
|
typedef struct ObjectEventListStruct ObjectEventList;
|
||||||
|
|
||||||
@ -52,9 +52,9 @@ typedef struct ObjectEventListStruct ObjectEventList;
|
|||||||
* List of object instances, holds the actual data structure and instance ID
|
* List of object instances, holds the actual data structure and instance ID
|
||||||
*/
|
*/
|
||||||
struct ObjectInstListStruct {
|
struct ObjectInstListStruct {
|
||||||
void* data;
|
void *data;
|
||||||
uint16_t instId;
|
uint16_t instId;
|
||||||
struct ObjectInstListStruct* next;
|
struct ObjectInstListStruct *next;
|
||||||
};
|
};
|
||||||
typedef struct ObjectInstListStruct ObjectInstList;
|
typedef struct ObjectInstListStruct ObjectInstList;
|
||||||
|
|
||||||
@ -62,34 +62,48 @@ typedef struct ObjectInstListStruct ObjectInstList;
|
|||||||
* List of objects registered in the object manager
|
* List of objects registered in the object manager
|
||||||
*/
|
*/
|
||||||
struct ObjectListStruct {
|
struct ObjectListStruct {
|
||||||
uint32_t id; /** The object ID */
|
uint32_t id;
|
||||||
const char* name; /** The object name */
|
/** The object ID */
|
||||||
int8_t isMetaobject; /** Set to 1 if this is a metaobject */
|
const char *name;
|
||||||
int8_t isSingleInstance; /** Set to 1 if this object has a single instance */
|
/** The object name */
|
||||||
int8_t isSettings; /** Set to 1 if this object is a settings object */
|
int8_t isMetaobject;
|
||||||
uint16_t numBytes; /** Number of data bytes contained in the object (for a single instance) */
|
/** Set to 1 if this is a metaobject */
|
||||||
uint16_t numInstances; /** Number of instances */
|
int8_t isSingleInstance;
|
||||||
struct ObjectListStruct* linkedObj; /** Linked object, for regular objects this is the metaobject and for metaobjects it is the parent object */
|
/** Set to 1 if this object has a single instance */
|
||||||
ObjectInstList instances; /** List of object instances, instance 0 always exists */
|
int8_t isSettings;
|
||||||
ObjectEventList* events; /** Event queues registered on the object */
|
/** Set to 1 if this object is a settings object */
|
||||||
struct ObjectListStruct* next; /** Needed by linked list library (utlist.h) */
|
uint16_t numBytes;
|
||||||
|
/** Number of data bytes contained in the object (for a single instance) */
|
||||||
|
uint16_t numInstances;
|
||||||
|
/** Number of instances */
|
||||||
|
struct ObjectListStruct *linkedObj;
|
||||||
|
/** Linked object, for regular objects this is the metaobject and for metaobjects it is the parent object */
|
||||||
|
ObjectInstList instances;
|
||||||
|
/** List of object instances, instance 0 always exists */
|
||||||
|
ObjectEventList *events;
|
||||||
|
/** Event queues registered on the object */
|
||||||
|
struct ObjectListStruct *next;
|
||||||
|
/** Needed by linked list library (utlist.h) */
|
||||||
};
|
};
|
||||||
typedef struct ObjectListStruct ObjectList;
|
typedef struct ObjectListStruct ObjectList;
|
||||||
|
|
||||||
// Private functions
|
// Private functions
|
||||||
static int32_t sendEvent(ObjectList* obj, uint16_t instId, UAVObjEventType event);
|
static int32_t sendEvent(ObjectList * obj, uint16_t instId,
|
||||||
static ObjectInstList* createInstance(ObjectList* obj, uint16_t instId);
|
UAVObjEventType event);
|
||||||
static ObjectInstList* getInstance(ObjectList* obj, uint16_t instId);
|
static ObjectInstList *createInstance(ObjectList * obj, uint16_t instId);
|
||||||
static int32_t connectObj(UAVObjHandle obj, xQueueHandle queue, UAVObjEventCallback cb, int32_t eventMask);
|
static ObjectInstList *getInstance(ObjectList * obj, uint16_t instId);
|
||||||
static int32_t disconnectObj(UAVObjHandle obj, xQueueHandle queue, UAVObjEventCallback cb);
|
static int32_t connectObj(UAVObjHandle obj, xQueueHandle queue,
|
||||||
|
UAVObjEventCallback cb, int32_t eventMask);
|
||||||
|
static int32_t disconnectObj(UAVObjHandle obj, xQueueHandle queue,
|
||||||
|
UAVObjEventCallback cb);
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_SDCARD)
|
#if defined(PIOS_INCLUDE_SDCARD)
|
||||||
static void objectFilename(ObjectList* obj, uint8_t* filename);
|
static void objectFilename(ObjectList * obj, uint8_t * filename);
|
||||||
static void customSPrintf(uint8_t* buffer, uint8_t* format, ...);
|
static void customSPrintf(uint8_t * buffer, uint8_t * format, ...);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Private variables
|
// Private variables
|
||||||
static ObjectList* objList;
|
static ObjectList *objList;
|
||||||
static xSemaphoreHandle mutex;
|
static xSemaphoreHandle mutex;
|
||||||
static UAVObjMetadata defMetadata;
|
static UAVObjMetadata defMetadata;
|
||||||
static UAVObjStats stats;
|
static UAVObjStats stats;
|
||||||
@ -130,7 +144,7 @@ int32_t UAVObjInitialize()
|
|||||||
* Get the statistics counters
|
* Get the statistics counters
|
||||||
* @param[out] statsOut The statistics counters will be copied there
|
* @param[out] statsOut The statistics counters will be copied there
|
||||||
*/
|
*/
|
||||||
void UAVObjGetStats(UAVObjStats* statsOut)
|
void UAVObjGetStats(UAVObjStats * statsOut)
|
||||||
{
|
{
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
memcpy(statsOut, &stats, sizeof(UAVObjStats));
|
memcpy(statsOut, &stats, sizeof(UAVObjStats));
|
||||||
@ -160,21 +174,22 @@ void UAVObjClearStats()
|
|||||||
* \return Object handle, or NULL if failure.
|
* \return Object handle, or NULL if failure.
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
UAVObjHandle UAVObjRegister(uint32_t id, const char* name, const char* metaName, int32_t isMetaobject,
|
UAVObjHandle UAVObjRegister(uint32_t id, const char *name,
|
||||||
int32_t isSingleInstance, int32_t isSettings, uint32_t numBytes, UAVObjInitializeCallback initCb)
|
const char *metaName, int32_t isMetaobject,
|
||||||
|
int32_t isSingleInstance, int32_t isSettings,
|
||||||
|
uint32_t numBytes,
|
||||||
|
UAVObjInitializeCallback initCb)
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
ObjectInstList* instEntry;
|
ObjectInstList *instEntry;
|
||||||
ObjectList* metaObj;
|
ObjectList *metaObj;
|
||||||
|
|
||||||
// Get lock
|
// Get lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Check that the object is not already registered
|
// Check that the object is not already registered
|
||||||
LL_FOREACH(objList, objEntry)
|
LL_FOREACH(objList, objEntry) {
|
||||||
{
|
if (objEntry->id == id) {
|
||||||
if (objEntry->id == id)
|
|
||||||
{
|
|
||||||
// Already registered, ignore
|
// Already registered, ignore
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -182,17 +197,16 @@ UAVObjHandle UAVObjRegister(uint32_t id, const char* name, const char* metaName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create and append entry
|
// Create and append entry
|
||||||
objEntry = (ObjectList*)pvPortMalloc(sizeof(ObjectList));
|
objEntry = (ObjectList *) pvPortMalloc(sizeof(ObjectList));
|
||||||
if (objEntry == NULL)
|
if (objEntry == NULL) {
|
||||||
{
|
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
objEntry->id = id;
|
objEntry->id = id;
|
||||||
objEntry->name = name;
|
objEntry->name = name;
|
||||||
objEntry->isMetaobject = (int8_t)isMetaobject;
|
objEntry->isMetaobject = (int8_t) isMetaobject;
|
||||||
objEntry->isSingleInstance = (int8_t)isSingleInstance;
|
objEntry->isSingleInstance = (int8_t) isSingleInstance;
|
||||||
objEntry->isSettings = (int8_t)isSettings;
|
objEntry->isSettings = (int8_t) isSettings;
|
||||||
objEntry->numBytes = numBytes;
|
objEntry->numBytes = numBytes;
|
||||||
objEntry->events = NULL;
|
objEntry->events = NULL;
|
||||||
objEntry->numInstances = 0;
|
objEntry->numInstances = 0;
|
||||||
@ -204,47 +218,41 @@ UAVObjHandle UAVObjRegister(uint32_t id, const char* name, const char* metaName,
|
|||||||
|
|
||||||
// Create instance zero
|
// Create instance zero
|
||||||
instEntry = createInstance(objEntry, 0);
|
instEntry = createInstance(objEntry, 0);
|
||||||
if ( instEntry == NULL )
|
if (instEntry == NULL) {
|
||||||
{
|
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create metaobject and update linkedObj
|
// Create metaobject and update linkedObj
|
||||||
if (isMetaobject)
|
if (isMetaobject) {
|
||||||
{
|
|
||||||
objEntry->linkedObj = NULL; // will be set later
|
objEntry->linkedObj = NULL; // will be set later
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Create metaobject
|
// Create metaobject
|
||||||
metaObj = (ObjectList*)UAVObjRegister(id+1, metaName, NULL, 1, 1, 0, sizeof(UAVObjMetadata), NULL);
|
metaObj =
|
||||||
|
(ObjectList *) UAVObjRegister(id + 1, metaName,
|
||||||
|
NULL, 1, 1, 0,
|
||||||
|
sizeof
|
||||||
|
(UAVObjMetadata),
|
||||||
|
NULL);
|
||||||
// Link two objects
|
// Link two objects
|
||||||
objEntry->linkedObj = metaObj;
|
objEntry->linkedObj = metaObj;
|
||||||
metaObj->linkedObj = objEntry;
|
metaObj->linkedObj = objEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize object fields and metadata to default values
|
// Initialize object fields and metadata to default values
|
||||||
if ( initCb != NULL )
|
if (initCb != NULL) {
|
||||||
{
|
initCb((UAVObjHandle) objEntry, 0);
|
||||||
initCb((UAVObjHandle)objEntry, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to load object's metadata from the SD card (not done directly on the metaobject, but through the object)
|
// Attempt to load object's metadata from the SD card (not done directly on the metaobject, but through the object)
|
||||||
if ( !objEntry->isMetaobject )
|
if (!objEntry->isMetaobject) {
|
||||||
{
|
UAVObjLoad((UAVObjHandle) objEntry->linkedObj, 0);
|
||||||
UAVObjLoad( (UAVObjHandle)objEntry->linkedObj, 0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a settings object, attempt to load from SD card
|
// If this is a settings object, attempt to load from SD card
|
||||||
if ( objEntry->isSettings )
|
if (objEntry->isSettings) {
|
||||||
{
|
UAVObjLoad((UAVObjHandle) objEntry, 0);
|
||||||
UAVObjLoad( (UAVObjHandle)objEntry, 0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release lock
|
// Release lock
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return (UAVObjHandle)objEntry;
|
return (UAVObjHandle) objEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -254,20 +262,18 @@ UAVObjHandle UAVObjRegister(uint32_t id, const char* name, const char* metaName,
|
|||||||
*/
|
*/
|
||||||
UAVObjHandle UAVObjGetByID(uint32_t id)
|
UAVObjHandle UAVObjGetByID(uint32_t id)
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
|
|
||||||
// Get lock
|
// Get lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Look for object
|
// Look for object
|
||||||
LL_FOREACH(objList, objEntry)
|
LL_FOREACH(objList, objEntry) {
|
||||||
{
|
if (objEntry->id == id) {
|
||||||
if (objEntry->id == id)
|
|
||||||
{
|
|
||||||
// Release lock
|
// Release lock
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
// Done, object found
|
// Done, object found
|
||||||
return (UAVObjHandle)objEntry;
|
return (UAVObjHandle) objEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,22 +287,21 @@ UAVObjHandle UAVObjGetByID(uint32_t id)
|
|||||||
* \param[in] name The name of the object
|
* \param[in] name The name of the object
|
||||||
* \return The object or NULL if not found.
|
* \return The object or NULL if not found.
|
||||||
*/
|
*/
|
||||||
UAVObjHandle UAVObjGetByName(char* name)
|
UAVObjHandle UAVObjGetByName(char *name)
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
|
|
||||||
// Get lock
|
// Get lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Look for object
|
// Look for object
|
||||||
LL_FOREACH(objList, objEntry)
|
LL_FOREACH(objList, objEntry) {
|
||||||
{
|
if (objEntry->name != NULL
|
||||||
if (objEntry->name != NULL && strcmp(objEntry->name, name) == 0)
|
&& strcmp(objEntry->name, name) == 0) {
|
||||||
{
|
|
||||||
// Release lock
|
// Release lock
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
// Done, object found
|
// Done, object found
|
||||||
return (UAVObjHandle)objEntry;
|
return (UAVObjHandle) objEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +317,7 @@ UAVObjHandle UAVObjGetByName(char* name)
|
|||||||
*/
|
*/
|
||||||
uint32_t UAVObjGetID(UAVObjHandle obj)
|
uint32_t UAVObjGetID(UAVObjHandle obj)
|
||||||
{
|
{
|
||||||
return ((ObjectList*)obj)->id;
|
return ((ObjectList *) obj)->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -320,9 +325,9 @@ uint32_t UAVObjGetID(UAVObjHandle obj)
|
|||||||
* \param[in] obj The object handle
|
* \param[in] obj The object handle
|
||||||
* \return The object's name
|
* \return The object's name
|
||||||
*/
|
*/
|
||||||
const char* UAVObjGetName(UAVObjHandle obj)
|
const char *UAVObjGetName(UAVObjHandle obj)
|
||||||
{
|
{
|
||||||
return ((ObjectList*)obj)->name;
|
return ((ObjectList *) obj)->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -332,7 +337,7 @@ const char* UAVObjGetName(UAVObjHandle obj)
|
|||||||
*/
|
*/
|
||||||
uint32_t UAVObjGetNumBytes(UAVObjHandle obj)
|
uint32_t UAVObjGetNumBytes(UAVObjHandle obj)
|
||||||
{
|
{
|
||||||
return ((ObjectList*)obj)->numBytes;
|
return ((ObjectList *) obj)->numBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -344,7 +349,7 @@ uint32_t UAVObjGetNumBytes(UAVObjHandle obj)
|
|||||||
*/
|
*/
|
||||||
UAVObjHandle UAVObjGetLinkedObj(UAVObjHandle obj)
|
UAVObjHandle UAVObjGetLinkedObj(UAVObjHandle obj)
|
||||||
{
|
{
|
||||||
return (UAVObjHandle)(((ObjectList*)obj)->linkedObj);
|
return (UAVObjHandle) (((ObjectList *) obj)->linkedObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -356,7 +361,7 @@ uint16_t UAVObjGetNumInstances(UAVObjHandle obj)
|
|||||||
{
|
{
|
||||||
uint32_t numInstances;
|
uint32_t numInstances;
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
numInstances = ((ObjectList*)obj)->numInstances;
|
numInstances = ((ObjectList *) obj)->numInstances;
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return numInstances;
|
return numInstances;
|
||||||
}
|
}
|
||||||
@ -366,29 +371,26 @@ uint16_t UAVObjGetNumInstances(UAVObjHandle obj)
|
|||||||
* \param[in] obj The object handle
|
* \param[in] obj The object handle
|
||||||
* \return The instance ID or 0 if an error
|
* \return The instance ID or 0 if an error
|
||||||
*/
|
*/
|
||||||
uint16_t UAVObjCreateInstance(UAVObjHandle obj, UAVObjInitializeCallback initCb)
|
uint16_t UAVObjCreateInstance(UAVObjHandle obj,
|
||||||
|
UAVObjInitializeCallback initCb)
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
ObjectInstList* instEntry;
|
ObjectInstList *instEntry;
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Create new instance
|
// Create new instance
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
instEntry = createInstance(objEntry, objEntry->numInstances);
|
instEntry = createInstance(objEntry, objEntry->numInstances);
|
||||||
if ( instEntry == NULL )
|
if (instEntry == NULL) {
|
||||||
{
|
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize instance data
|
// Initialize instance data
|
||||||
if ( initCb != NULL )
|
if (initCb != NULL) {
|
||||||
{
|
|
||||||
initCb(obj, instEntry->instId);
|
initCb(obj, instEntry->instId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock
|
// Unlock
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return instEntry->instId;
|
return instEntry->instId;
|
||||||
@ -401,7 +403,7 @@ uint16_t UAVObjCreateInstance(UAVObjHandle obj, UAVObjInitializeCallback initCb)
|
|||||||
*/
|
*/
|
||||||
int32_t UAVObjIsSingleInstance(UAVObjHandle obj)
|
int32_t UAVObjIsSingleInstance(UAVObjHandle obj)
|
||||||
{
|
{
|
||||||
return ((ObjectList*)obj)->isSingleInstance;
|
return ((ObjectList *) obj)->isSingleInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -411,7 +413,7 @@ int32_t UAVObjIsSingleInstance(UAVObjHandle obj)
|
|||||||
*/
|
*/
|
||||||
int32_t UAVObjIsMetaobject(UAVObjHandle obj)
|
int32_t UAVObjIsMetaobject(UAVObjHandle obj)
|
||||||
{
|
{
|
||||||
return ((ObjectList*)obj)->isMetaobject;
|
return ((ObjectList *) obj)->isMetaobject;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -421,7 +423,7 @@ int32_t UAVObjIsMetaobject(UAVObjHandle obj)
|
|||||||
*/
|
*/
|
||||||
int32_t UAVObjIsSettings(UAVObjHandle obj)
|
int32_t UAVObjIsSettings(UAVObjHandle obj)
|
||||||
{
|
{
|
||||||
return ((ObjectList*)obj)->isSettings;
|
return ((ObjectList *) obj)->isSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -431,32 +433,30 @@ int32_t UAVObjIsSettings(UAVObjHandle obj)
|
|||||||
* \param[in] dataIn The byte array
|
* \param[in] dataIn The byte array
|
||||||
* \return 0 if success or -1 if failure
|
* \return 0 if success or -1 if failure
|
||||||
*/
|
*/
|
||||||
int32_t UAVObjUnpack(UAVObjHandle obj, uint16_t instId, const uint8_t* dataIn)
|
int32_t UAVObjUnpack(UAVObjHandle obj, uint16_t instId,
|
||||||
|
const uint8_t * dataIn)
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
ObjectInstList* instEntry;
|
ObjectInstList *instEntry;
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Cast handle to object
|
// Cast handle to object
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
|
|
||||||
// Get the instance
|
// Get the instance
|
||||||
instEntry = getInstance(objEntry, instId);
|
instEntry = getInstance(objEntry, instId);
|
||||||
|
|
||||||
// If the instance does not exist create it and any other instances before it
|
// If the instance does not exist create it and any other instances before it
|
||||||
if ( instEntry == NULL )
|
if (instEntry == NULL) {
|
||||||
{
|
|
||||||
instEntry = createInstance(objEntry, instId);
|
instEntry = createInstance(objEntry, instId);
|
||||||
if ( instEntry == NULL )
|
if (instEntry == NULL) {
|
||||||
{
|
|
||||||
// Error, unlock and return
|
// Error, unlock and return
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the data
|
// Set the data
|
||||||
memcpy(instEntry->data, dataIn, objEntry->numBytes);
|
memcpy(instEntry->data, dataIn, objEntry->numBytes);
|
||||||
|
|
||||||
@ -475,26 +475,24 @@ int32_t UAVObjUnpack(UAVObjHandle obj, uint16_t instId, const uint8_t* dataIn)
|
|||||||
* \param[out] dataOut The byte array
|
* \param[out] dataOut The byte array
|
||||||
* \return 0 if success or -1 if failure
|
* \return 0 if success or -1 if failure
|
||||||
*/
|
*/
|
||||||
int32_t UAVObjPack(UAVObjHandle obj, uint16_t instId, uint8_t* dataOut)
|
int32_t UAVObjPack(UAVObjHandle obj, uint16_t instId, uint8_t * dataOut)
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
ObjectInstList* instEntry;
|
ObjectInstList *instEntry;
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Cast handle to object
|
// Cast handle to object
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
|
|
||||||
// Get the instance
|
// Get the instance
|
||||||
instEntry = getInstance(objEntry, instId);
|
instEntry = getInstance(objEntry, instId);
|
||||||
if ( instEntry == NULL )
|
if (instEntry == NULL) {
|
||||||
{
|
|
||||||
// Error, unlock and return
|
// Error, unlock and return
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pack data
|
// Pack data
|
||||||
memcpy(dataOut, instEntry->data, objEntry->numBytes);
|
memcpy(dataOut, instEntry->data, objEntry->numBytes);
|
||||||
|
|
||||||
@ -512,64 +510,52 @@ int32_t UAVObjPack(UAVObjHandle obj, uint16_t instId, uint8_t* dataOut)
|
|||||||
* @param[in] file File to append to
|
* @param[in] file File to append to
|
||||||
* @return 0 if success or -1 if failure
|
* @return 0 if success or -1 if failure
|
||||||
*/
|
*/
|
||||||
int32_t UAVObjSaveToFile(UAVObjHandle obj, uint16_t instId, FILEINFO* file)
|
int32_t UAVObjSaveToFile(UAVObjHandle obj, uint16_t instId,
|
||||||
|
FILEINFO * file)
|
||||||
{
|
{
|
||||||
#if defined(PIOS_INCLUDE_SDCARD)
|
#if defined(PIOS_INCLUDE_SDCARD)
|
||||||
uint32_t bytesWritten;
|
uint32_t bytesWritten;
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
ObjectInstList* instEntry;
|
ObjectInstList *instEntry;
|
||||||
|
|
||||||
// Check for file system availability
|
// Check for file system availability
|
||||||
if ( PIOS_SDCARD_IsMounted() == 0 )
|
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Cast to object
|
// Cast to object
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
|
|
||||||
// Get the instance information
|
// Get the instance information
|
||||||
instEntry = getInstance(objEntry, instId);
|
instEntry = getInstance(objEntry, instId);
|
||||||
if ( instEntry == NULL )
|
if (instEntry == NULL) {
|
||||||
{
|
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the object ID
|
// Write the object ID
|
||||||
PIOS_FWRITE(file,&objEntry->id,sizeof(objEntry->id),&bytesWritten);
|
PIOS_FWRITE(file, &objEntry->id, sizeof(objEntry->id),
|
||||||
|
&bytesWritten);
|
||||||
|
|
||||||
// Write the instance ID
|
// Write the instance ID
|
||||||
if (!objEntry->isSingleInstance)
|
if (!objEntry->isSingleInstance) {
|
||||||
{
|
PIOS_FWRITE(file, &instEntry->instId,
|
||||||
PIOS_FWRITE(file,&instEntry->instId,sizeof(instEntry->instId),&bytesWritten);
|
sizeof(instEntry->instId), &bytesWritten);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the data and check that the write was successful
|
// Write the data and check that the write was successful
|
||||||
PIOS_FWRITE(file,instEntry->data,objEntry->numBytes,&bytesWritten);
|
PIOS_FWRITE(file, instEntry->data, objEntry->numBytes,
|
||||||
if ( bytesWritten != objEntry->numBytes )
|
&bytesWritten);
|
||||||
{
|
if (bytesWritten != objEntry->numBytes) {
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
#endif /* PIOS_INCLUDE_SDCARD */
|
#endif /* PIOS_INCLUDE_SDCARD */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fileHeader {
|
|
||||||
uint32_t id;
|
|
||||||
uint16_t instId;
|
|
||||||
uint16_t size;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
#define FLASH_MASK 0x001ff000 /* Select a sector */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the data of the specified object to the file system (SD card).
|
* Save the data of the specified object to the file system (SD card).
|
||||||
* If the object contains multiple instances, all of them will be saved.
|
* If the object contains multiple instances, all of them will be saved.
|
||||||
@ -583,66 +569,51 @@ struct fileHeader {
|
|||||||
int32_t UAVObjSave(UAVObjHandle obj, uint16_t instId)
|
int32_t UAVObjSave(UAVObjHandle obj, uint16_t instId)
|
||||||
{
|
{
|
||||||
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
|
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
|
||||||
ObjectList* objEntry = (ObjectList*)obj;
|
ObjectList *objEntry = (ObjectList *) obj;
|
||||||
|
|
||||||
if(objEntry == NULL)
|
if (objEntry == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ObjectInstList* instEntry = getInstance(objEntry, instId);
|
ObjectInstList *instEntry = getInstance(objEntry, instId);
|
||||||
|
|
||||||
if(instEntry == NULL)
|
if (instEntry == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(instEntry->data == NULL)
|
if (instEntry->data == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (PIOS_FLASHFS_ObjSave(obj, instId, instEntry->data) != 0)
|
||||||
struct fileHeader header = {
|
return -1;
|
||||||
.id = objEntry->id,
|
|
||||||
.instId = instId,
|
|
||||||
.size = objEntry->numBytes
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t addr = (objEntry->id & FLASH_MASK);
|
|
||||||
PIOS_Flash_W25X_EraseSector(addr);
|
|
||||||
PIOS_Flash_W25X_WriteData(addr, (uint8_t *) &header, sizeof(header));
|
|
||||||
PIOS_Flash_W25X_WriteData(addr + sizeof(header), instEntry->data,objEntry->numBytes);
|
|
||||||
#endif
|
#endif
|
||||||
#if defined(PIOS_INCLUDE_SDCARD)
|
#if defined(PIOS_INCLUDE_SDCARD)
|
||||||
FILEINFO file;
|
FILEINFO file;
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
uint8_t filename[14];
|
uint8_t filename[14];
|
||||||
|
|
||||||
// Check for file system availability
|
// Check for file system availability
|
||||||
if ( PIOS_SDCARD_IsMounted() == 0 )
|
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Cast to object
|
// Cast to object
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
|
|
||||||
// Get filename
|
// Get filename
|
||||||
objectFilename(objEntry, filename);
|
objectFilename(objEntry, filename);
|
||||||
|
|
||||||
// Open file
|
// Open file
|
||||||
if ( PIOS_FOPEN_WRITE(filename,file) )
|
if (PIOS_FOPEN_WRITE(filename, file)) {
|
||||||
{
|
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append object
|
// Append object
|
||||||
if ( UAVObjSaveToFile(obj, instId, &file) == -1 )
|
if (UAVObjSaveToFile(obj, instId, &file) == -1) {
|
||||||
{
|
|
||||||
PIOS_FCLOSE(file);
|
PIOS_FCLOSE(file);
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done, close file and unlock
|
// Done, close file and unlock
|
||||||
PIOS_FCLOSE(file);
|
PIOS_FCLOSE(file);
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
@ -655,74 +626,63 @@ int32_t UAVObjSave(UAVObjHandle obj, uint16_t instId)
|
|||||||
* @param[in] file File to read from
|
* @param[in] file File to read from
|
||||||
* @return The handle of the object loaded or NULL if a failure
|
* @return The handle of the object loaded or NULL if a failure
|
||||||
*/
|
*/
|
||||||
UAVObjHandle UAVObjLoadFromFile(FILEINFO* file)
|
UAVObjHandle UAVObjLoadFromFile(FILEINFO * file)
|
||||||
{
|
{
|
||||||
#if defined(PIOS_INCLUDE_SDCARD)
|
#if defined(PIOS_INCLUDE_SDCARD)
|
||||||
uint32_t bytesRead;
|
uint32_t bytesRead;
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
ObjectInstList* instEntry;
|
ObjectInstList *instEntry;
|
||||||
uint32_t objId;
|
uint32_t objId;
|
||||||
uint16_t instId;
|
uint16_t instId;
|
||||||
UAVObjHandle obj;
|
UAVObjHandle obj;
|
||||||
|
|
||||||
// Check for file system availability
|
// Check for file system availability
|
||||||
if ( PIOS_SDCARD_IsMounted() == 0 )
|
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||||
{
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Read the object ID
|
// Read the object ID
|
||||||
if ( PIOS_FREAD(file,&objId,sizeof(objId),&bytesRead) )
|
if (PIOS_FREAD(file, &objId, sizeof(objId), &bytesRead)) {
|
||||||
{
|
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the object
|
// Get the object
|
||||||
obj = UAVObjGetByID(objId);
|
obj = UAVObjGetByID(objId);
|
||||||
if ( obj == 0 )
|
if (obj == 0) {
|
||||||
{
|
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
|
|
||||||
// Get the instance ID
|
// Get the instance ID
|
||||||
instId = 0;
|
instId = 0;
|
||||||
if ( !objEntry->isSingleInstance )
|
if (!objEntry->isSingleInstance) {
|
||||||
{
|
if (PIOS_FREAD
|
||||||
if ( PIOS_FREAD(file,&instId,sizeof(instId),&bytesRead) )
|
(file, &instId, sizeof(instId), &bytesRead)) {
|
||||||
{
|
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the instance information
|
// Get the instance information
|
||||||
instEntry = getInstance(objEntry, instId);
|
instEntry = getInstance(objEntry, instId);
|
||||||
|
|
||||||
// If the instance does not exist create it and any other instances before it
|
// If the instance does not exist create it and any other instances before it
|
||||||
if ( instEntry == NULL )
|
if (instEntry == NULL) {
|
||||||
{
|
|
||||||
instEntry = createInstance(objEntry, instId);
|
instEntry = createInstance(objEntry, instId);
|
||||||
if ( instEntry == NULL )
|
if (instEntry == NULL) {
|
||||||
{
|
|
||||||
// Error, unlock and return
|
// Error, unlock and return
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the instance data
|
// Read the instance data
|
||||||
if ( PIOS_FREAD(file,instEntry->data,objEntry->numBytes,&bytesRead) )
|
if (PIOS_FREAD
|
||||||
{
|
(file, instEntry->data, objEntry->numBytes, &bytesRead)) {
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fire event
|
// Fire event
|
||||||
sendEvent(objEntry, instId, EV_UNPACKED);
|
sendEvent(objEntry, instId, EV_UNPACKED);
|
||||||
|
|
||||||
@ -745,82 +705,65 @@ UAVObjHandle UAVObjLoadFromFile(FILEINFO* file)
|
|||||||
int32_t UAVObjLoad(UAVObjHandle obj, uint16_t instId)
|
int32_t UAVObjLoad(UAVObjHandle obj, uint16_t instId)
|
||||||
{
|
{
|
||||||
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
|
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
|
||||||
ObjectList* objEntry = (ObjectList*)obj;
|
ObjectList *objEntry = (ObjectList *) obj;
|
||||||
|
|
||||||
if(objEntry == NULL)
|
if (objEntry == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ObjectInstList* instEntry = getInstance(objEntry, instId);
|
ObjectInstList *instEntry = getInstance(objEntry, instId);
|
||||||
|
|
||||||
if(instEntry == NULL)
|
if (instEntry == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(instEntry->data == NULL)
|
if (instEntry->data == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
struct fileHeader header;
|
// Fire event on success
|
||||||
uint32_t addr = (objEntry->id & FLASH_MASK);
|
if (PIOS_FLASHFS_ObjLoad(obj, instId, instEntry->data) == 0)
|
||||||
|
|
||||||
PIOS_Flash_W25X_ReadData(addr, (uint8_t *) &header, sizeof(header));
|
|
||||||
|
|
||||||
if(header.id != objEntry->id)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// Read the instance data
|
|
||||||
if (PIOS_Flash_W25X_ReadData(addr + sizeof(header) ,instEntry->data, objEntry->numBytes) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// Fire event
|
|
||||||
sendEvent(objEntry, instId, EV_UNPACKED);
|
sendEvent(objEntry, instId, EV_UNPACKED);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PIOS_INCLUDE_SDCARD)
|
#if defined(PIOS_INCLUDE_SDCARD)
|
||||||
FILEINFO file;
|
FILEINFO file;
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
UAVObjHandle loadedObj;
|
UAVObjHandle loadedObj;
|
||||||
ObjectList* loadedObjEntry;
|
ObjectList *loadedObjEntry;
|
||||||
uint8_t filename[14];
|
uint8_t filename[14];
|
||||||
|
|
||||||
// Check for file system availability
|
// Check for file system availability
|
||||||
if ( PIOS_SDCARD_IsMounted() == 0 )
|
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Cast to object
|
// Cast to object
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
|
|
||||||
// Get filename
|
// Get filename
|
||||||
objectFilename(objEntry, filename);
|
objectFilename(objEntry, filename);
|
||||||
|
|
||||||
// Open file
|
// Open file
|
||||||
if ( PIOS_FOPEN_READ(filename,file) )
|
if (PIOS_FOPEN_READ(filename, file)) {
|
||||||
{
|
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load object
|
// Load object
|
||||||
loadedObj = UAVObjLoadFromFile(&file);
|
loadedObj = UAVObjLoadFromFile(&file);
|
||||||
if (loadedObj == 0)
|
if (loadedObj == 0) {
|
||||||
{
|
|
||||||
PIOS_FCLOSE(file);
|
PIOS_FCLOSE(file);
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the IDs match
|
// Check that the IDs match
|
||||||
loadedObjEntry = (ObjectList*)loadedObj;
|
loadedObjEntry = (ObjectList *) loadedObj;
|
||||||
if ( loadedObjEntry->id != objEntry->id )
|
if (loadedObjEntry->id != objEntry->id) {
|
||||||
{
|
|
||||||
PIOS_FCLOSE(file);
|
PIOS_FCLOSE(file);
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done, close file and unlock
|
// Done, close file and unlock
|
||||||
PIOS_FCLOSE(file);
|
PIOS_FCLOSE(file);
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
@ -837,29 +780,21 @@ int32_t UAVObjLoad(UAVObjHandle obj, uint16_t instId)
|
|||||||
int32_t UAVObjDelete(UAVObjHandle obj, uint16_t instId)
|
int32_t UAVObjDelete(UAVObjHandle obj, uint16_t instId)
|
||||||
{
|
{
|
||||||
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
|
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
|
||||||
ObjectList* objEntry = (ObjectList*)obj;
|
PIOS_FLASHFS_ObjDelete(obj, instId);
|
||||||
|
|
||||||
if(objEntry == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
uint32_t addr = (objEntry->id & FLASH_MASK);
|
|
||||||
PIOS_Flash_W25X_EraseSector(addr);
|
|
||||||
#endif
|
#endif
|
||||||
#if defined(PIOS_INCLUDE_SDCARD)
|
#if defined(PIOS_INCLUDE_SDCARD)
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
uint8_t filename[14];
|
uint8_t filename[14];
|
||||||
|
|
||||||
// Check for file system availability
|
// Check for file system availability
|
||||||
if ( PIOS_SDCARD_IsMounted() == 0 )
|
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Cast to object
|
// Cast to object
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
|
|
||||||
// Get filename
|
// Get filename
|
||||||
objectFilename(objEntry, filename);
|
objectFilename(objEntry, filename);
|
||||||
@ -879,20 +814,18 @@ int32_t UAVObjDelete(UAVObjHandle obj, uint16_t instId)
|
|||||||
*/
|
*/
|
||||||
int32_t UAVObjSaveSettings()
|
int32_t UAVObjSaveSettings()
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
|
|
||||||
// Get lock
|
// Get lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Save all settings objects
|
// Save all settings objects
|
||||||
LL_FOREACH(objList, objEntry)
|
LL_FOREACH(objList, objEntry) {
|
||||||
{
|
|
||||||
// Check if this is a settings object
|
// Check if this is a settings object
|
||||||
if ( objEntry->isSettings )
|
if (objEntry->isSettings) {
|
||||||
{
|
|
||||||
// Save object
|
// Save object
|
||||||
if ( UAVObjSave( (UAVObjHandle)objEntry, 0 ) == -1 )
|
if (UAVObjSave((UAVObjHandle) objEntry, 0) ==
|
||||||
{
|
-1) {
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -910,20 +843,18 @@ int32_t UAVObjSaveSettings()
|
|||||||
*/
|
*/
|
||||||
int32_t UAVObjLoadSettings()
|
int32_t UAVObjLoadSettings()
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
|
|
||||||
// Get lock
|
// Get lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Load all settings objects
|
// Load all settings objects
|
||||||
LL_FOREACH(objList, objEntry)
|
LL_FOREACH(objList, objEntry) {
|
||||||
{
|
|
||||||
// Check if this is a settings object
|
// Check if this is a settings object
|
||||||
if ( objEntry->isSettings )
|
if (objEntry->isSettings) {
|
||||||
{
|
|
||||||
// Load object
|
// Load object
|
||||||
if ( UAVObjLoad( (UAVObjHandle)objEntry, 0 ) == -1 )
|
if (UAVObjLoad((UAVObjHandle) objEntry, 0) ==
|
||||||
{
|
-1) {
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -941,20 +872,18 @@ int32_t UAVObjLoadSettings()
|
|||||||
*/
|
*/
|
||||||
int32_t UAVObjDeleteSettings()
|
int32_t UAVObjDeleteSettings()
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
|
|
||||||
// Get lock
|
// Get lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Save all settings objects
|
// Save all settings objects
|
||||||
LL_FOREACH(objList, objEntry)
|
LL_FOREACH(objList, objEntry) {
|
||||||
{
|
|
||||||
// Check if this is a settings object
|
// Check if this is a settings object
|
||||||
if ( objEntry->isSettings )
|
if (objEntry->isSettings) {
|
||||||
{
|
|
||||||
// Save object
|
// Save object
|
||||||
if ( UAVObjDelete( (UAVObjHandle)objEntry, 0 ) == -1 )
|
if (UAVObjDelete((UAVObjHandle) objEntry, 0)
|
||||||
{
|
== -1) {
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -972,20 +901,18 @@ int32_t UAVObjDeleteSettings()
|
|||||||
*/
|
*/
|
||||||
int32_t UAVObjSaveMetaobjects()
|
int32_t UAVObjSaveMetaobjects()
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
|
|
||||||
// Get lock
|
// Get lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Save all settings objects
|
// Save all settings objects
|
||||||
LL_FOREACH(objList, objEntry)
|
LL_FOREACH(objList, objEntry) {
|
||||||
{
|
|
||||||
// Check if this is a settings object
|
// Check if this is a settings object
|
||||||
if ( objEntry->isMetaobject )
|
if (objEntry->isMetaobject) {
|
||||||
{
|
|
||||||
// Save object
|
// Save object
|
||||||
if ( UAVObjSave( (UAVObjHandle)objEntry, 0 ) == -1 )
|
if (UAVObjSave((UAVObjHandle) objEntry, 0) ==
|
||||||
{
|
-1) {
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1003,20 +930,18 @@ int32_t UAVObjSaveMetaobjects()
|
|||||||
*/
|
*/
|
||||||
int32_t UAVObjLoadMetaobjects()
|
int32_t UAVObjLoadMetaobjects()
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
|
|
||||||
// Get lock
|
// Get lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Load all settings objects
|
// Load all settings objects
|
||||||
LL_FOREACH(objList, objEntry)
|
LL_FOREACH(objList, objEntry) {
|
||||||
{
|
|
||||||
// Check if this is a settings object
|
// Check if this is a settings object
|
||||||
if ( objEntry->isMetaobject )
|
if (objEntry->isMetaobject) {
|
||||||
{
|
|
||||||
// Load object
|
// Load object
|
||||||
if ( UAVObjLoad( (UAVObjHandle)objEntry, 0 ) == -1 )
|
if (UAVObjLoad((UAVObjHandle) objEntry, 0) ==
|
||||||
{
|
-1) {
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1034,20 +959,18 @@ int32_t UAVObjLoadMetaobjects()
|
|||||||
*/
|
*/
|
||||||
int32_t UAVObjDeleteMetaobjects()
|
int32_t UAVObjDeleteMetaobjects()
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
|
|
||||||
// Get lock
|
// Get lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Load all settings objects
|
// Load all settings objects
|
||||||
LL_FOREACH(objList, objEntry)
|
LL_FOREACH(objList, objEntry) {
|
||||||
{
|
|
||||||
// Check if this is a settings object
|
// Check if this is a settings object
|
||||||
if ( objEntry->isMetaobject )
|
if (objEntry->isMetaobject) {
|
||||||
{
|
|
||||||
// Load object
|
// Load object
|
||||||
if ( UAVObjDelete( (UAVObjHandle)objEntry, 0 ) == -1 )
|
if (UAVObjDelete((UAVObjHandle) objEntry, 0)
|
||||||
{
|
== -1) {
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1065,7 +988,7 @@ int32_t UAVObjDeleteMetaobjects()
|
|||||||
* \param[in] dataIn The object's data structure
|
* \param[in] dataIn The object's data structure
|
||||||
* \return 0 if success or -1 if failure
|
* \return 0 if success or -1 if failure
|
||||||
*/
|
*/
|
||||||
int32_t UAVObjSetData(UAVObjHandle obj, const void* dataIn)
|
int32_t UAVObjSetData(UAVObjHandle obj, const void *dataIn)
|
||||||
{
|
{
|
||||||
return UAVObjSetInstanceData(obj, 0, dataIn);
|
return UAVObjSetInstanceData(obj, 0, dataIn);
|
||||||
}
|
}
|
||||||
@ -1076,7 +999,7 @@ int32_t UAVObjSetData(UAVObjHandle obj, const void* dataIn)
|
|||||||
* \param[out] dataOut The object's data structure
|
* \param[out] dataOut The object's data structure
|
||||||
* \return 0 if success or -1 if failure
|
* \return 0 if success or -1 if failure
|
||||||
*/
|
*/
|
||||||
int32_t UAVObjGetData(UAVObjHandle obj, void* dataOut)
|
int32_t UAVObjGetData(UAVObjHandle obj, void *dataOut)
|
||||||
{
|
{
|
||||||
return UAVObjGetInstanceData(obj, 0, dataOut);
|
return UAVObjGetInstanceData(obj, 0, dataOut);
|
||||||
}
|
}
|
||||||
@ -1088,38 +1011,36 @@ int32_t UAVObjGetData(UAVObjHandle obj, void* dataOut)
|
|||||||
* \param[in] dataIn The object's data structure
|
* \param[in] dataIn The object's data structure
|
||||||
* \return 0 if success or -1 if failure
|
* \return 0 if success or -1 if failure
|
||||||
*/
|
*/
|
||||||
int32_t UAVObjSetInstanceData(UAVObjHandle obj, uint16_t instId, const void* dataIn)
|
int32_t UAVObjSetInstanceData(UAVObjHandle obj, uint16_t instId,
|
||||||
|
const void *dataIn)
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
ObjectInstList* instEntry;
|
ObjectInstList *instEntry;
|
||||||
UAVObjMetadata* mdata;
|
UAVObjMetadata *mdata;
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Cast to object info
|
// Cast to object info
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
|
|
||||||
// Check access level
|
// Check access level
|
||||||
if ( !objEntry->isMetaobject )
|
if (!objEntry->isMetaobject) {
|
||||||
{
|
mdata =
|
||||||
mdata = (UAVObjMetadata*)(objEntry->linkedObj->instances.data);
|
(UAVObjMetadata *) (objEntry->linkedObj->instances.
|
||||||
if ( mdata->access == ACCESS_READONLY )
|
data);
|
||||||
{
|
if (mdata->access == ACCESS_READONLY) {
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get instance information
|
// Get instance information
|
||||||
instEntry = getInstance(objEntry, instId);
|
instEntry = getInstance(objEntry, instId);
|
||||||
if ( instEntry == NULL )
|
if (instEntry == NULL) {
|
||||||
{
|
|
||||||
// Error, unlock and return
|
// Error, unlock and return
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set data
|
// Set data
|
||||||
memcpy(instEntry->data, dataIn, objEntry->numBytes);
|
memcpy(instEntry->data, dataIn, objEntry->numBytes);
|
||||||
|
|
||||||
@ -1138,26 +1059,25 @@ int32_t UAVObjSetInstanceData(UAVObjHandle obj, uint16_t instId, const void* dat
|
|||||||
* \param[out] dataOut The object's data structure
|
* \param[out] dataOut The object's data structure
|
||||||
* \return 0 if success or -1 if failure
|
* \return 0 if success or -1 if failure
|
||||||
*/
|
*/
|
||||||
int32_t UAVObjGetInstanceData(UAVObjHandle obj, uint16_t instId, void* dataOut)
|
int32_t UAVObjGetInstanceData(UAVObjHandle obj, uint16_t instId,
|
||||||
|
void *dataOut)
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
ObjectInstList* instEntry;
|
ObjectInstList *instEntry;
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Cast to object info
|
// Cast to object info
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
|
|
||||||
// Get instance information
|
// Get instance information
|
||||||
instEntry = getInstance(objEntry, instId);
|
instEntry = getInstance(objEntry, instId);
|
||||||
if ( instEntry == NULL )
|
if (instEntry == NULL) {
|
||||||
{
|
|
||||||
// Error, unlock and return
|
// Error, unlock and return
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set data
|
// Set data
|
||||||
memcpy(dataOut, instEntry->data, objEntry->numBytes);
|
memcpy(dataOut, instEntry->data, objEntry->numBytes);
|
||||||
|
|
||||||
@ -1172,21 +1092,19 @@ int32_t UAVObjGetInstanceData(UAVObjHandle obj, uint16_t instId, void* dataOut)
|
|||||||
* \param[in] dataIn The object's metadata structure
|
* \param[in] dataIn The object's metadata structure
|
||||||
* \return 0 if success or -1 if failure
|
* \return 0 if success or -1 if failure
|
||||||
*/
|
*/
|
||||||
int32_t UAVObjSetMetadata(UAVObjHandle obj, const UAVObjMetadata* dataIn)
|
int32_t UAVObjSetMetadata(UAVObjHandle obj, const UAVObjMetadata * dataIn)
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Set metadata (metadata of metaobjects can not be modified)
|
// Set metadata (metadata of metaobjects can not be modified)
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
if (!objEntry->isMetaobject)
|
if (!objEntry->isMetaobject) {
|
||||||
{
|
UAVObjSetData((UAVObjHandle) objEntry->linkedObj,
|
||||||
UAVObjSetData((UAVObjHandle)objEntry->linkedObj, dataIn);
|
dataIn);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1201,22 +1119,20 @@ int32_t UAVObjSetMetadata(UAVObjHandle obj, const UAVObjMetadata* dataIn)
|
|||||||
* \param[out] dataOut The object's metadata structure
|
* \param[out] dataOut The object's metadata structure
|
||||||
* \return 0 if success or -1 if failure
|
* \return 0 if success or -1 if failure
|
||||||
*/
|
*/
|
||||||
int32_t UAVObjGetMetadata(UAVObjHandle obj, UAVObjMetadata* dataOut)
|
int32_t UAVObjGetMetadata(UAVObjHandle obj, UAVObjMetadata * dataOut)
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Get metadata
|
// Get metadata
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
if (objEntry->isMetaobject)
|
if (objEntry->isMetaobject) {
|
||||||
{
|
|
||||||
memcpy(dataOut, &defMetadata, sizeof(UAVObjMetadata));
|
memcpy(dataOut, &defMetadata, sizeof(UAVObjMetadata));
|
||||||
}
|
} else {
|
||||||
else
|
UAVObjGetData((UAVObjHandle) objEntry->linkedObj,
|
||||||
{
|
dataOut);
|
||||||
UAVObjGetData((UAVObjHandle)objEntry->linkedObj, dataOut);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock
|
// Unlock
|
||||||
@ -1234,16 +1150,17 @@ int32_t UAVObjGetMetadata(UAVObjHandle obj, UAVObjMetadata* dataOut)
|
|||||||
*/
|
*/
|
||||||
int8_t UAVObjReadOnly(UAVObjHandle obj)
|
int8_t UAVObjReadOnly(UAVObjHandle obj)
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
UAVObjMetadata* mdata;
|
UAVObjMetadata *mdata;
|
||||||
|
|
||||||
// Cast to object info
|
// Cast to object info
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
|
|
||||||
// Check access level
|
// Check access level
|
||||||
if ( !objEntry->isMetaobject )
|
if (!objEntry->isMetaobject) {
|
||||||
{
|
mdata =
|
||||||
mdata = (UAVObjMetadata*)(objEntry->linkedObj->instances.data);
|
(UAVObjMetadata *) (objEntry->linkedObj->instances.
|
||||||
|
data);
|
||||||
return mdata->access == ACCESS_READONLY;
|
return mdata->access == ACCESS_READONLY;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -1257,7 +1174,8 @@ int8_t UAVObjReadOnly(UAVObjHandle obj)
|
|||||||
* \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL)
|
* \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL)
|
||||||
* \return 0 if success or -1 if failure
|
* \return 0 if success or -1 if failure
|
||||||
*/
|
*/
|
||||||
int32_t UAVObjConnectQueue(UAVObjHandle obj, xQueueHandle queue, int32_t eventMask)
|
int32_t UAVObjConnectQueue(UAVObjHandle obj, xQueueHandle queue,
|
||||||
|
int32_t eventMask)
|
||||||
{
|
{
|
||||||
int32_t res;
|
int32_t res;
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
@ -1289,7 +1207,8 @@ int32_t UAVObjDisconnectQueue(UAVObjHandle obj, xQueueHandle queue)
|
|||||||
* \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL)
|
* \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL)
|
||||||
* \return 0 if success or -1 if failure
|
* \return 0 if success or -1 if failure
|
||||||
*/
|
*/
|
||||||
int32_t UAVObjConnectCallback(UAVObjHandle obj, UAVObjEventCallback cb, int32_t eventMask)
|
int32_t UAVObjConnectCallback(UAVObjHandle obj, UAVObjEventCallback cb,
|
||||||
|
int32_t eventMask)
|
||||||
{
|
{
|
||||||
int32_t res;
|
int32_t res;
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
@ -1313,7 +1232,6 @@ int32_t UAVObjDisconnectCallback(UAVObjHandle obj, UAVObjEventCallback cb)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request an update of the object's data from the GCS. The call will not wait for the response, a EV_UPDATED event
|
* Request an update of the object's data from the GCS. The call will not wait for the response, a EV_UPDATED event
|
||||||
* will be generated as soon as the object is updated.
|
* will be generated as soon as the object is updated.
|
||||||
@ -1333,7 +1251,7 @@ void UAVObjRequestUpdate(UAVObjHandle obj)
|
|||||||
void UAVObjRequestInstanceUpdate(UAVObjHandle obj, uint16_t instId)
|
void UAVObjRequestInstanceUpdate(UAVObjHandle obj, uint16_t instId)
|
||||||
{
|
{
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
sendEvent((ObjectList*)obj, instId, EV_UPDATE_REQ);
|
sendEvent((ObjectList *) obj, instId, EV_UPDATE_REQ);
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1354,7 +1272,7 @@ void UAVObjUpdated(UAVObjHandle obj)
|
|||||||
void UAVObjInstanceUpdated(UAVObjHandle obj, uint16_t instId)
|
void UAVObjInstanceUpdated(UAVObjHandle obj, uint16_t instId)
|
||||||
{
|
{
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
sendEvent((ObjectList*)obj, instId, EV_UPDATED_MANUAL);
|
sendEvent((ObjectList *) obj, instId, EV_UPDATED_MANUAL);
|
||||||
xSemaphoreGiveRecursive(mutex);
|
xSemaphoreGiveRecursive(mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1363,17 +1281,16 @@ void UAVObjInstanceUpdated(UAVObjHandle obj, uint16_t instId)
|
|||||||
* \param iterator This function will be called once for each object,
|
* \param iterator This function will be called once for each object,
|
||||||
* the object will be passed as a parameter
|
* the object will be passed as a parameter
|
||||||
*/
|
*/
|
||||||
void UAVObjIterate(void (*iterator)(UAVObjHandle obj))
|
void UAVObjIterate(void (*iterator) (UAVObjHandle obj))
|
||||||
{
|
{
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
|
|
||||||
// Get lock
|
// Get lock
|
||||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||||
|
|
||||||
// Iterate through the list and invoke iterator for each object
|
// Iterate through the list and invoke iterator for each object
|
||||||
LL_FOREACH(objList, objEntry)
|
LL_FOREACH(objList, objEntry) {
|
||||||
{
|
(*iterator) ((UAVObjHandle) objEntry);
|
||||||
(*iterator)((UAVObjHandle)objEntry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release lock
|
// Release lock
|
||||||
@ -1383,33 +1300,31 @@ void UAVObjIterate(void (*iterator)(UAVObjHandle obj))
|
|||||||
/**
|
/**
|
||||||
* Send an event to all event queues registered on the object.
|
* Send an event to all event queues registered on the object.
|
||||||
*/
|
*/
|
||||||
static int32_t sendEvent(ObjectList* obj, uint16_t instId, UAVObjEventType event)
|
static int32_t sendEvent(ObjectList * obj, uint16_t instId,
|
||||||
|
UAVObjEventType event)
|
||||||
{
|
{
|
||||||
ObjectEventList* eventEntry;
|
ObjectEventList *eventEntry;
|
||||||
UAVObjEvent msg;
|
UAVObjEvent msg;
|
||||||
|
|
||||||
// Setup event
|
// Setup event
|
||||||
msg.obj = (UAVObjHandle)obj;
|
msg.obj = (UAVObjHandle) obj;
|
||||||
msg.event = event;
|
msg.event = event;
|
||||||
msg.instId = instId;
|
msg.instId = instId;
|
||||||
|
|
||||||
// Go through each object and push the event message in the queue (if event is activated for the queue)
|
// Go through each object and push the event message in the queue (if event is activated for the queue)
|
||||||
LL_FOREACH(obj->events, eventEntry)
|
LL_FOREACH(obj->events, eventEntry) {
|
||||||
{
|
if (eventEntry->eventMask == 0
|
||||||
if ( eventEntry->eventMask == 0 || (eventEntry->eventMask & event) != 0 )
|
|| (eventEntry->eventMask & event) != 0) {
|
||||||
{
|
|
||||||
// Send to queue if a valid queue is registered
|
// Send to queue if a valid queue is registered
|
||||||
if (eventEntry->queue != 0)
|
if (eventEntry->queue != 0) {
|
||||||
{
|
if (xQueueSend(eventEntry->queue, &msg, 0) != pdTRUE) // will not block
|
||||||
if ( xQueueSend(eventEntry->queue, &msg, 0) != pdTRUE ) // will not block
|
|
||||||
{
|
{
|
||||||
++stats.eventErrors;
|
++stats.eventErrors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Invoke callback (from event task) if a valid one is registered
|
// Invoke callback (from event task) if a valid one is registered
|
||||||
if (eventEntry->cb != 0)
|
if (eventEntry->cb != 0) {
|
||||||
{
|
if (EventCallbackDispatch(&msg, eventEntry->cb) != pdTRUE) // invoke callback from the event task, will not block
|
||||||
if ( EventCallbackDispatch(&msg, eventEntry->cb) != pdTRUE ) // invoke callback from the event task, will not block
|
|
||||||
{
|
{
|
||||||
++stats.eventErrors;
|
++stats.eventErrors;
|
||||||
}
|
}
|
||||||
@ -1424,52 +1339,47 @@ static int32_t sendEvent(ObjectList* obj, uint16_t instId, UAVObjEventType event
|
|||||||
/**
|
/**
|
||||||
* Create a new object instance, return the instance info or NULL if failure.
|
* Create a new object instance, return the instance info or NULL if failure.
|
||||||
*/
|
*/
|
||||||
static ObjectInstList* createInstance(ObjectList* obj, uint16_t instId)
|
static ObjectInstList *createInstance(ObjectList * obj, uint16_t instId)
|
||||||
{
|
{
|
||||||
ObjectInstList* instEntry;
|
ObjectInstList *instEntry;
|
||||||
int32_t n;
|
int32_t n;
|
||||||
|
|
||||||
// For single instance objects, only instance zero is allowed
|
// For single instance objects, only instance zero is allowed
|
||||||
if (obj->isSingleInstance && instId != 0)
|
if (obj->isSingleInstance && instId != 0) {
|
||||||
{
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that the instance ID is within limits
|
// Make sure that the instance ID is within limits
|
||||||
if (instId >= UAVOBJ_MAX_INSTANCES)
|
if (instId >= UAVOBJ_MAX_INSTANCES) {
|
||||||
{
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the instance already exists
|
// Check if the instance already exists
|
||||||
if ( getInstance(obj, instId) != NULL )
|
if (getInstance(obj, instId) != NULL) {
|
||||||
{
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create any missing instances (all instance IDs must be sequential)
|
// Create any missing instances (all instance IDs must be sequential)
|
||||||
for (n = obj->numInstances; n < instId; ++n)
|
for (n = obj->numInstances; n < instId; ++n) {
|
||||||
{
|
if (createInstance(obj, n) == NULL) {
|
||||||
if ( createInstance(obj, n) == NULL )
|
|
||||||
{
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(instId == 0) /* Instance 0 ObjectInstList allocated with ObjectList element */
|
if (instId == 0) { /* Instance 0 ObjectInstList allocated with ObjectList element */
|
||||||
{
|
|
||||||
instEntry = &obj->instances;
|
instEntry = &obj->instances;
|
||||||
instEntry->data = pvPortMalloc(obj->numBytes);
|
instEntry->data = pvPortMalloc(obj->numBytes);
|
||||||
if (instEntry->data == NULL) return NULL;
|
if (instEntry->data == NULL)
|
||||||
|
return NULL;
|
||||||
memset(instEntry->data, 0, obj->numBytes);
|
memset(instEntry->data, 0, obj->numBytes);
|
||||||
instEntry->instId = instId;
|
instEntry->instId = instId;
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
// Create the actual instance
|
// Create the actual instance
|
||||||
instEntry = (ObjectInstList*)pvPortMalloc(sizeof(ObjectInstList));
|
instEntry =
|
||||||
if (instEntry == NULL) return NULL;
|
(ObjectInstList *)
|
||||||
|
pvPortMalloc(sizeof(ObjectInstList));
|
||||||
|
if (instEntry == NULL)
|
||||||
|
return NULL;
|
||||||
instEntry->data = pvPortMalloc(obj->numBytes);
|
instEntry->data = pvPortMalloc(obj->numBytes);
|
||||||
if (instEntry->data == NULL) return NULL;
|
if (instEntry->data == NULL)
|
||||||
|
return NULL;
|
||||||
memset(instEntry->data, 0, obj->numBytes);
|
memset(instEntry->data, 0, obj->numBytes);
|
||||||
instEntry->instId = instId;
|
instEntry->instId = instId;
|
||||||
LL_APPEND(obj->instances.next, instEntry);
|
LL_APPEND(obj->instances.next, instEntry);
|
||||||
@ -1477,7 +1387,7 @@ static ObjectInstList* createInstance(ObjectList* obj, uint16_t instId)
|
|||||||
++obj->numInstances;
|
++obj->numInstances;
|
||||||
|
|
||||||
// Fire event
|
// Fire event
|
||||||
UAVObjInstanceUpdated((UAVObjHandle)obj, instId);
|
UAVObjInstanceUpdated((UAVObjHandle) obj, instId);
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
return instEntry;
|
return instEntry;
|
||||||
@ -1486,15 +1396,13 @@ static ObjectInstList* createInstance(ObjectList* obj, uint16_t instId)
|
|||||||
/**
|
/**
|
||||||
* Get the instance information or NULL if the instance does not exist
|
* Get the instance information or NULL if the instance does not exist
|
||||||
*/
|
*/
|
||||||
static ObjectInstList* getInstance(ObjectList* obj, uint16_t instId)
|
static ObjectInstList *getInstance(ObjectList * obj, uint16_t instId)
|
||||||
{
|
{
|
||||||
ObjectInstList* instEntry;
|
ObjectInstList *instEntry;
|
||||||
|
|
||||||
// Look for specified instance ID
|
// Look for specified instance ID
|
||||||
LL_FOREACH(&(obj->instances), instEntry)
|
LL_FOREACH(&(obj->instances), instEntry) {
|
||||||
{
|
if (instEntry->instId == instId) {
|
||||||
if (instEntry->instId == instId)
|
|
||||||
{
|
|
||||||
return instEntry;
|
return instEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1510,17 +1418,16 @@ static ObjectInstList* getInstance(ObjectList* obj, uint16_t instId)
|
|||||||
* \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL)
|
* \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL)
|
||||||
* \return 0 if success or -1 if failure
|
* \return 0 if success or -1 if failure
|
||||||
*/
|
*/
|
||||||
static int32_t connectObj(UAVObjHandle obj, xQueueHandle queue, UAVObjEventCallback cb, int32_t eventMask)
|
static int32_t connectObj(UAVObjHandle obj, xQueueHandle queue,
|
||||||
|
UAVObjEventCallback cb, int32_t eventMask)
|
||||||
{
|
{
|
||||||
ObjectEventList* eventEntry;
|
ObjectEventList *eventEntry;
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
|
|
||||||
// Check that the queue is not already connected, if it is simply update event mask
|
// Check that the queue is not already connected, if it is simply update event mask
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
LL_FOREACH(objEntry->events, eventEntry)
|
LL_FOREACH(objEntry->events, eventEntry) {
|
||||||
{
|
if (eventEntry->queue == queue && eventEntry->cb == cb) {
|
||||||
if ( eventEntry->queue == queue && eventEntry->cb == cb )
|
|
||||||
{
|
|
||||||
// Already connected, update event mask and return
|
// Already connected, update event mask and return
|
||||||
eventEntry->eventMask = eventMask;
|
eventEntry->eventMask = eventMask;
|
||||||
return 0;
|
return 0;
|
||||||
@ -1528,9 +1435,9 @@ static int32_t connectObj(UAVObjHandle obj, xQueueHandle queue, UAVObjEventCallb
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add queue to list
|
// Add queue to list
|
||||||
eventEntry = (ObjectEventList*)pvPortMalloc(sizeof(ObjectEventList));
|
eventEntry =
|
||||||
if (eventEntry == NULL)
|
(ObjectEventList *) pvPortMalloc(sizeof(ObjectEventList));
|
||||||
{
|
if (eventEntry == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
eventEntry->queue = queue;
|
eventEntry->queue = queue;
|
||||||
@ -1549,17 +1456,17 @@ static int32_t connectObj(UAVObjHandle obj, xQueueHandle queue, UAVObjEventCallb
|
|||||||
* \param[in] cb The event callback
|
* \param[in] cb The event callback
|
||||||
* \return 0 if success or -1 if failure
|
* \return 0 if success or -1 if failure
|
||||||
*/
|
*/
|
||||||
static int32_t disconnectObj(UAVObjHandle obj, xQueueHandle queue, UAVObjEventCallback cb)
|
static int32_t disconnectObj(UAVObjHandle obj, xQueueHandle queue,
|
||||||
|
UAVObjEventCallback cb)
|
||||||
{
|
{
|
||||||
ObjectEventList* eventEntry;
|
ObjectEventList *eventEntry;
|
||||||
ObjectList* objEntry;
|
ObjectList *objEntry;
|
||||||
|
|
||||||
// Find queue and remove it
|
// Find queue and remove it
|
||||||
objEntry = (ObjectList*)obj;
|
objEntry = (ObjectList *) obj;
|
||||||
LL_FOREACH(objEntry->events, eventEntry)
|
LL_FOREACH(objEntry->events, eventEntry) {
|
||||||
{
|
if ((eventEntry->queue == queue
|
||||||
if ( ( eventEntry->queue == queue && eventEntry->cb == cb ) )
|
&& eventEntry->cb == cb)) {
|
||||||
{
|
|
||||||
LL_DELETE(objEntry->events, eventEntry);
|
LL_DELETE(objEntry->events, eventEntry);
|
||||||
vPortFree(eventEntry);
|
vPortFree(eventEntry);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1574,7 +1481,7 @@ static int32_t disconnectObj(UAVObjHandle obj, xQueueHandle queue, UAVObjEventCa
|
|||||||
/**
|
/**
|
||||||
* Wrapper for the sprintf function
|
* Wrapper for the sprintf function
|
||||||
*/
|
*/
|
||||||
static void customSPrintf(uint8_t* buffer, uint8_t* format, ...)
|
static void customSPrintf(uint8_t * buffer, uint8_t * format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
@ -1584,24 +1491,8 @@ static void customSPrintf(uint8_t* buffer, uint8_t* format, ...)
|
|||||||
/**
|
/**
|
||||||
* Get an 8 character (plus extension) filename for the object.
|
* Get an 8 character (plus extension) filename for the object.
|
||||||
*/
|
*/
|
||||||
static void objectFilename(ObjectList* obj, uint8_t* filename)
|
static void objectFilename(ObjectList * obj, uint8_t * filename)
|
||||||
{
|
{
|
||||||
customSPrintf(filename, (uint8_t*)"%X.obj", obj->id);
|
customSPrintf(filename, (uint8_t *) "%X.obj", obj->id);
|
||||||
}
|
}
|
||||||
#endif /* PIOS_INCLUDE_SDCARD */
|
#endif /* PIOS_INCLUDE_SDCARD */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user