mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-17 02:52:12 +01:00
Merge remote-tracking branch 'origin/stac/corvus-integrated-metadata' into next
This commit is contained in:
commit
fa77eafaf1
@ -109,7 +109,10 @@ class UAVObject:
|
||||
|
||||
def addField(self, field):
|
||||
append(self.fields, field)
|
||||
|
||||
'''
|
||||
#
|
||||
# Support for getName was removed from embedded UAVO database to save RAM + Flash
|
||||
#
|
||||
def getName(self):
|
||||
"""__NATIVE__
|
||||
UAVObjHandle objHandle;
|
||||
@ -143,6 +146,7 @@ class UAVObject:
|
||||
return PM_RET_OK;
|
||||
"""
|
||||
pass
|
||||
'''
|
||||
|
||||
def read(self):
|
||||
"""__NATIVE__
|
||||
|
@ -255,9 +255,9 @@ static int32_t RadioComBridgeInitialize(void)
|
||||
PipXSettingsPairIDGet(&(data->pairStats[0].pairID));
|
||||
|
||||
// Configure our UAVObjects for updates.
|
||||
UAVObjConnectQueue(UAVObjGetByName("PipXStatus"), data->objEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ);
|
||||
UAVObjConnectQueue(UAVObjGetByName("GCSReceiver"), data->objEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ);
|
||||
UAVObjConnectQueue(UAVObjGetByName("ObjectPersistence"), data->objEventQueue, EV_UPDATED | EV_UPDATED_MANUAL);
|
||||
UAVObjConnectQueue(UAVObjGetByID(PIPXSTATUS_OBJID), data->objEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ);
|
||||
UAVObjConnectQueue(UAVObjGetByID(GCSRECEIVER_OBJID), data->objEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ);
|
||||
UAVObjConnectQueue(UAVObjGetByID(OBJECTPERSISTENCE_OBJID), data->objEventQueue, EV_UPDATED | EV_UPDATED_MANUAL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
12
flight/PiOS.posix/inc/pios_struct_helper.h
Normal file
12
flight/PiOS.posix/inc/pios_struct_helper.h
Normal file
@ -0,0 +1,12 @@
|
||||
/* Taken from include/linux/kernel.h from the Linux kernel tree */
|
||||
|
||||
/**
|
||||
* container_of - cast a member of a structure out to the containing structure
|
||||
* @ptr: the pointer to the member.
|
||||
* @type: the type of the container struct this is embedded in.
|
||||
* @member: the name of the member within the struct.
|
||||
*
|
||||
*/
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
12
flight/PiOS/inc/pios_struct_helper.h
Normal file
12
flight/PiOS/inc/pios_struct_helper.h
Normal file
@ -0,0 +1,12 @@
|
||||
/* Taken from include/linux/kernel.h from the Linux kernel tree */
|
||||
|
||||
/**
|
||||
* container_of - cast a member of a structure out to the containing structure
|
||||
* @ptr: the pointer to the member.
|
||||
* @type: the type of the container struct this is embedded in.
|
||||
* @member: the name of the member within the struct.
|
||||
*
|
||||
*/
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
1
flight/Project/gdb/simposix
Normal file
1
flight/Project/gdb/simposix
Normal file
@ -0,0 +1 @@
|
||||
handle SIGUSR1 noprint nostop
|
@ -38,7 +38,7 @@ OUTDIR := $(TOP)/build/$(TARGET)
|
||||
|
||||
# Set developer code and compile options
|
||||
# Set to YES for debugging
|
||||
DEBUG ?= NO
|
||||
DEBUG ?= YES
|
||||
|
||||
# Set to YES when using Code Sourcery toolchain
|
||||
CODE_SOURCERY ?= NO
|
||||
|
@ -133,7 +133,7 @@ typedef void (*UAVObjEventCallback)(UAVObjEvent* ev);
|
||||
/**
|
||||
* Callback used to initialize the object fields to their default values.
|
||||
*/
|
||||
typedef void (*UAVObjInitializeCallback)(UAVObjHandle obj, uint16_t instId);
|
||||
typedef void (*UAVObjInitializeCallback)(UAVObjHandle obj_handle, uint16_t instId);
|
||||
|
||||
/**
|
||||
* Event manager statistics
|
||||
@ -148,25 +148,23 @@ typedef struct {
|
||||
int32_t UAVObjInitialize();
|
||||
void UAVObjGetStats(UAVObjStats* statsOut);
|
||||
void UAVObjClearStats();
|
||||
UAVObjHandle UAVObjRegister(uint32_t id, const char* name, const char* metaName, int32_t isMetaobject,
|
||||
UAVObjHandle UAVObjRegister(uint32_t id,
|
||||
int32_t isSingleInstance, int32_t isSettings, uint32_t numBytes, UAVObjInitializeCallback initCb);
|
||||
UAVObjHandle UAVObjGetByID(uint32_t id);
|
||||
UAVObjHandle UAVObjGetByName(char* name);
|
||||
uint32_t UAVObjGetID(UAVObjHandle obj);
|
||||
const char* UAVObjGetName(UAVObjHandle obj);
|
||||
uint32_t UAVObjGetNumBytes(UAVObjHandle obj);
|
||||
uint16_t UAVObjGetNumInstances(UAVObjHandle obj);
|
||||
UAVObjHandle UAVObjGetLinkedObj(UAVObjHandle obj);
|
||||
uint16_t UAVObjCreateInstance(UAVObjHandle obj, UAVObjInitializeCallback initCb);
|
||||
int32_t UAVObjIsSingleInstance(UAVObjHandle obj);
|
||||
int32_t UAVObjIsMetaobject(UAVObjHandle obj);
|
||||
int32_t UAVObjIsSettings(UAVObjHandle obj);
|
||||
int32_t UAVObjUnpack(UAVObjHandle obj, uint16_t instId, const uint8_t* dataIn);
|
||||
int32_t UAVObjPack(UAVObjHandle obj, uint16_t instId, uint8_t* dataOut);
|
||||
int32_t UAVObjSave(UAVObjHandle obj, uint16_t instId);
|
||||
int32_t UAVObjLoad(UAVObjHandle obj, uint16_t instId);
|
||||
int32_t UAVObjDelete(UAVObjHandle obj, uint16_t instId);
|
||||
int32_t UAVObjSaveToFile(UAVObjHandle obj, uint16_t instId, FILEINFO* file);
|
||||
uint16_t UAVObjCreateInstance(UAVObjHandle obj_handle, UAVObjInitializeCallback initCb);
|
||||
bool UAVObjIsSingleInstance(UAVObjHandle obj);
|
||||
bool UAVObjIsMetaobject(UAVObjHandle obj);
|
||||
bool UAVObjIsSettings(UAVObjHandle obj);
|
||||
int32_t UAVObjUnpack(UAVObjHandle obj_handle, uint16_t instId, const uint8_t* dataIn);
|
||||
int32_t UAVObjPack(UAVObjHandle obj_handle, uint16_t instId, uint8_t* dataOut);
|
||||
int32_t UAVObjSave(UAVObjHandle obj_handle, uint16_t instId);
|
||||
int32_t UAVObjLoad(UAVObjHandle obj_handle, uint16_t instId);
|
||||
int32_t UAVObjDelete(UAVObjHandle obj_handle, uint16_t instId);
|
||||
int32_t UAVObjSaveToFile(UAVObjHandle obj_handle, uint16_t instId, FILEINFO* file);
|
||||
UAVObjHandle UAVObjLoadFromFile(FILEINFO* file);
|
||||
int32_t UAVObjSaveSettings();
|
||||
int32_t UAVObjLoadSettings();
|
||||
@ -174,18 +172,17 @@ int32_t UAVObjDeleteSettings();
|
||||
int32_t UAVObjSaveMetaobjects();
|
||||
int32_t UAVObjLoadMetaobjects();
|
||||
int32_t UAVObjDeleteMetaobjects();
|
||||
int32_t UAVObjSetData(UAVObjHandle obj, const void* dataIn);
|
||||
int32_t UAVObjSetDataField(UAVObjHandle obj, const void* dataIn, uint32_t offset, uint32_t size);
|
||||
int32_t UAVObjGetData(UAVObjHandle obj, void* dataOut);
|
||||
int32_t UAVObjGetDataField(UAVObjHandle obj, void* dataOut, uint32_t offset, uint32_t size);
|
||||
int32_t UAVObjSetInstanceData(UAVObjHandle obj, uint16_t instId, const void* dataIn);
|
||||
int32_t UAVObjSetInstanceDataField(UAVObjHandle obj, uint16_t instId, const void* dataIn, uint32_t offset, uint32_t size);
|
||||
int32_t UAVObjGetInstanceData(UAVObjHandle obj, uint16_t instId, void* dataOut);
|
||||
int32_t UAVObjGetInstanceDataField(UAVObjHandle obj, uint16_t instId, void* dataOut, uint32_t offset, uint32_t size);
|
||||
int32_t UAVObjSetMetadata(UAVObjHandle obj, const UAVObjMetadata* dataIn);
|
||||
int32_t UAVObjGetMetadata(UAVObjHandle obj, UAVObjMetadata* dataOut);
|
||||
int32_t UAVObjSetData(UAVObjHandle obj_handle, const void* dataIn);
|
||||
int32_t UAVObjSetDataField(UAVObjHandle obj_handle, const void* dataIn, uint32_t offset, uint32_t size);
|
||||
int32_t UAVObjGetData(UAVObjHandle obj_handle, void* dataOut);
|
||||
int32_t UAVObjGetDataField(UAVObjHandle obj_handle, void* dataOut, uint32_t offset, uint32_t size);
|
||||
int32_t UAVObjSetInstanceData(UAVObjHandle obj_handle, uint16_t instId, const void* dataIn);
|
||||
int32_t UAVObjSetInstanceDataField(UAVObjHandle obj_handle, uint16_t instId, const void* dataIn, uint32_t offset, uint32_t size);
|
||||
int32_t UAVObjGetInstanceData(UAVObjHandle obj_handle, uint16_t instId, void* dataOut);
|
||||
int32_t UAVObjGetInstanceDataField(UAVObjHandle obj_handle, uint16_t instId, void* dataOut, uint32_t offset, uint32_t size);
|
||||
int32_t UAVObjSetMetadata(UAVObjHandle obj_handle, const UAVObjMetadata* dataIn);
|
||||
int32_t UAVObjGetMetadata(UAVObjHandle obj_handle, UAVObjMetadata* dataOut);
|
||||
uint8_t UAVObjGetMetadataAccess(const UAVObjMetadata* dataOut);
|
||||
void UAVObjMetadataInitialize(UAVObjMetadata* dataOut);
|
||||
UAVObjAccessType UAVObjGetAccess(const UAVObjMetadata* dataOut);
|
||||
void UAVObjSetAccess(UAVObjMetadata* dataOut, UAVObjAccessType mode);
|
||||
UAVObjAccessType UAVObjGetGcsAccess(const UAVObjMetadata* dataOut);
|
||||
@ -199,14 +196,14 @@ void UAVObjSetTelemetryUpdateMode(UAVObjMetadata* dataOut, UAVObjUpdateMode val)
|
||||
UAVObjUpdateMode UAVObjGetGcsTelemetryUpdateMode(const UAVObjMetadata* dataOut);
|
||||
void UAVObjSetTelemetryGcsUpdateMode(UAVObjMetadata* dataOut, UAVObjUpdateMode val);
|
||||
int8_t UAVObjReadOnly(UAVObjHandle obj);
|
||||
int32_t UAVObjConnectQueue(UAVObjHandle obj, xQueueHandle queue, uint8_t eventMask);
|
||||
int32_t UAVObjDisconnectQueue(UAVObjHandle obj, xQueueHandle queue);
|
||||
int32_t UAVObjConnectCallback(UAVObjHandle obj, UAVObjEventCallback cb, uint8_t eventMask);
|
||||
int32_t UAVObjDisconnectCallback(UAVObjHandle obj, UAVObjEventCallback cb);
|
||||
int32_t UAVObjConnectQueue(UAVObjHandle obj_handle, xQueueHandle queue, uint8_t eventMask);
|
||||
int32_t UAVObjDisconnectQueue(UAVObjHandle obj_handle, xQueueHandle queue);
|
||||
int32_t UAVObjConnectCallback(UAVObjHandle obj_handle, UAVObjEventCallback cb, uint8_t eventMask);
|
||||
int32_t UAVObjDisconnectCallback(UAVObjHandle obj_handle, UAVObjEventCallback cb);
|
||||
void UAVObjRequestUpdate(UAVObjHandle obj);
|
||||
void UAVObjRequestInstanceUpdate(UAVObjHandle obj, uint16_t instId);
|
||||
void UAVObjRequestInstanceUpdate(UAVObjHandle obj_handle, uint16_t instId);
|
||||
void UAVObjUpdated(UAVObjHandle obj);
|
||||
void UAVObjInstanceUpdated(UAVObjHandle obj, uint16_t instId);
|
||||
void UAVObjInstanceUpdated(UAVObjHandle obj_handle, uint16_t instId);
|
||||
void UAVObjIterate(void (*iterator)(UAVObjHandle obj));
|
||||
|
||||
#endif // UAVOBJECTMANAGER_H
|
||||
|
@ -42,8 +42,6 @@
|
||||
|
||||
// Object constants
|
||||
#define $(NAMEUC)_OBJID $(OBJIDHEX)
|
||||
#define $(NAMEUC)_NAME "$(NAME)"
|
||||
#define $(NAMEUC)_METANAME "$(NAME)Meta"
|
||||
#define $(NAMEUC)_ISSINGLEINST $(ISSINGLEINST)
|
||||
#define $(NAMEUC)_ISSETTINGS $(ISSETTINGS)
|
||||
#define $(NAMEUC)_NUMBYTES sizeof($(NAME)Data)
|
||||
|
@ -1,20 +1,20 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @addtogroup UAVObjects OpenPilot UAVObjects
|
||||
* @{
|
||||
* @addtogroup UAV Object Manager
|
||||
* @brief The core UAV Objects functions, most of which are wrappered by
|
||||
* autogenerated defines
|
||||
* @{
|
||||
*
|
||||
*
|
||||
* @file uavobjectmanager.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief Object manager library. This library holds a collection of all objects.
|
||||
* It can be used by all modules/libraries to find an object reference.
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
*
|
||||
*****************************************************************************/
|
||||
******************************************************************************
|
||||
* @addtogroup UAVObjects OpenPilot UAVObjects
|
||||
* @{
|
||||
* @addtogroup UAV Object Manager
|
||||
* @brief The core UAV Objects functions, most of which are wrappered by
|
||||
* autogenerated defines
|
||||
* @{
|
||||
*
|
||||
*
|
||||
* @file uavobjectmanager.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @brief Object manager library. This library holds a collection of all objects.
|
||||
* It can be used by all modules/libraries to find an object reference.
|
||||
* @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
|
||||
@ -32,6 +32,7 @@
|
||||
*/
|
||||
|
||||
#include "openpilot.h"
|
||||
#include "pios_struct_helper.h"
|
||||
|
||||
// Constants
|
||||
|
||||
@ -39,84 +40,144 @@
|
||||
|
||||
// Macros
|
||||
#define SET_BITS(var, shift, value, mask) var = (var & ~(mask << shift)) | (value << shift);
|
||||
#define OLGetIsMetaobject(olp) ((olp)->flags & OL_IS_METAOBJECT)
|
||||
#define OLSetIsMetaobject(olp, val) ((olp)->flags = (((val) == 0) ? ((olp)->flags & ~OL_IS_METAOBJECT) : ((olp)->flags | OL_IS_METAOBJECT)))
|
||||
#define OLGetIsSingleInstance(olp) ((olp)->flags & OL_IS_SINGLE_INSTANCE)
|
||||
#define OLSetIsSingleInstance(olp, val) ((olp)->flags = (((val) == 0) ? ((olp)->flags & ~OL_IS_SINGLE_INSTANCE) : ((olp)->flags | OL_IS_SINGLE_INSTANCE)))
|
||||
#define OLGetIsSettings(olp) ((olp)->flags & OL_IS_SETTINGS)
|
||||
#define OLSetIsSettings(olp, val) ((olp)->flags = (((val) == 0) ? ((olp)->flags & ~OL_IS_SETTINGS) : ((olp)->flags | OL_IS_SETTINGS)))
|
||||
|
||||
/**
|
||||
* List of event queues and the eventmask associated with the queue.
|
||||
*/
|
||||
struct ObjectEventListStruct {
|
||||
xQueueHandle queue;
|
||||
UAVObjEventCallback cb;
|
||||
uint8_t eventMask;
|
||||
struct ObjectEventListStruct *next;
|
||||
};
|
||||
typedef struct ObjectEventListStruct ObjectEventList;
|
||||
|
||||
/**
|
||||
* List of object instances, holds the actual data structure and instance ID
|
||||
*/
|
||||
struct ObjectInstListStruct {
|
||||
void *data;
|
||||
uint16_t instId;
|
||||
struct ObjectInstListStruct *next;
|
||||
};
|
||||
typedef struct ObjectInstListStruct ObjectInstList;
|
||||
/** opaque type for instances **/
|
||||
typedef void* InstanceHandle;
|
||||
|
||||
typedef enum {
|
||||
OL_IS_METAOBJECT = 0x01, /** Set if this is a metaobject */
|
||||
OL_IS_SINGLE_INSTANCE = 0x02, /** Set if this object has a single instance */
|
||||
OL_IS_SETTINGS = 0x04 /** Set if this object is a settings object */
|
||||
} ObjectListFlags;
|
||||
|
||||
/**
|
||||
* List of objects registered in the object manager
|
||||
*/
|
||||
struct ObjectListStruct {
|
||||
uint32_t id;
|
||||
/** The object ID */
|
||||
const char *name;
|
||||
/** The object name */
|
||||
ObjectListFlags flags;
|
||||
/** The object list mode flags */
|
||||
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) */
|
||||
struct ObjectEventEntry {
|
||||
xQueueHandle queue;
|
||||
UAVObjEventCallback cb;
|
||||
uint8_t eventMask;
|
||||
struct ObjectEventEntry * next;
|
||||
};
|
||||
typedef struct ObjectListStruct ObjectList;
|
||||
|
||||
/*
|
||||
MetaInstance == [UAVOBase [UAVObjMetadata]]
|
||||
SingleInstance == [UAVOBase [UAVOData [InstanceData]]]
|
||||
MultiInstance == [UAVOBase [UAVOData [NumInstances [InstanceData0 [next]]]]
|
||||
____________________/
|
||||
\-->[InstanceData1 [next]]
|
||||
_________...________/
|
||||
\-->[InstanceDataN [next]]
|
||||
*/
|
||||
|
||||
/*
|
||||
* UAVO Base Type
|
||||
* - All Types of UAVObjects are of this base type
|
||||
* - The flags determine what type(s) this object
|
||||
*/
|
||||
struct UAVOBase {
|
||||
/* Let these objects be added to an event queue */
|
||||
struct ObjectEventEntry * next_event;
|
||||
|
||||
/* Describe the type of object that follows this header */
|
||||
struct UAVOInfo {
|
||||
bool isMeta : 1;
|
||||
bool isSingle : 1;
|
||||
bool isSettings : 1;
|
||||
} flags;
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Augmented type for Meta UAVO */
|
||||
struct UAVOMeta {
|
||||
struct UAVOBase base;
|
||||
UAVObjMetadata instance0;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Shared data structure for all data-carrying UAVObjects (UAVOSingle and UAVOMulti) */
|
||||
struct UAVOData {
|
||||
struct UAVOBase base;
|
||||
uint32_t id;
|
||||
/*
|
||||
* Embed the Meta object as another complete UAVO
|
||||
* inside the payload for this UAVO.
|
||||
*/
|
||||
struct UAVOMeta metaObj;
|
||||
struct UAVOData * next;
|
||||
uint16_t instance_size;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Augmented type for Single Instance Data UAVO */
|
||||
struct UAVOSingle {
|
||||
struct UAVOData uavo;
|
||||
|
||||
uint8_t instance0[];
|
||||
/*
|
||||
* Additional space will be malloc'd here to hold the
|
||||
* the data for this instance.
|
||||
*/
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Part of a linked list of instances chained off of a multi instance UAVO. */
|
||||
struct UAVOMultiInst {
|
||||
struct UAVOMultiInst * next;
|
||||
uint8_t instance[];
|
||||
/*
|
||||
* Additional space will be malloc'd here to hold the
|
||||
* the data for this instance.
|
||||
*/
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Augmented type for Multi Instance Data UAVO */
|
||||
struct UAVOMulti {
|
||||
struct UAVOData uavo;
|
||||
|
||||
uint16_t num_instances;
|
||||
struct UAVOMultiInst instance0;
|
||||
/*
|
||||
* Additional space will be malloc'd here to hold the
|
||||
* the data for instance 0.
|
||||
*/
|
||||
} __attribute__((packed));
|
||||
|
||||
/** all information about a metaobject are hardcoded constants **/
|
||||
#define MetaNumBytes sizeof(UAVObjMetadata)
|
||||
#define MetaBaseObjectPtr(obj) ((struct UAVOData *)((obj)-offsetof(struct UAVOData, metaObj)))
|
||||
#define MetaObjectPtr(obj) ((struct UAVODataMeta*) &((obj)->metaObj))
|
||||
#define MetaDataPtr(obj) ((UAVObjMetadata*)&((obj)->instance0))
|
||||
#define LinkedMetaDataPtr(obj) ((UAVObjMetadata*)&((obj)->metaObj.instance0))
|
||||
#define MetaObjectId(id) ((id)+1)
|
||||
|
||||
/** all information about instances are dependant on object type **/
|
||||
#define ObjSingleInstanceDataOffset(obj) ((void*)(&(( (struct UAVOSingle*)obj )->instance0)))
|
||||
#define InstanceDataOffset(inst) ((void*)&(( (struct UAVOMultiInst*)inst )->instance))
|
||||
#define InstanceData(instance) (void*)instance
|
||||
|
||||
// Private functions
|
||||
static int32_t sendEvent(ObjectList * obj, uint16_t instId,
|
||||
UAVObjEventType event);
|
||||
static ObjectInstList *createInstance(ObjectList * obj, uint16_t instId);
|
||||
static ObjectInstList *getInstance(ObjectList * obj, uint16_t instId);
|
||||
static int32_t connectObj(UAVObjHandle obj, xQueueHandle queue,
|
||||
UAVObjEventCallback cb, uint8_t eventMask);
|
||||
static int32_t disconnectObj(UAVObjHandle obj, xQueueHandle queue,
|
||||
UAVObjEventCallback cb);
|
||||
static int32_t sendEvent(struct UAVOBase * obj, uint16_t instId,
|
||||
UAVObjEventType event);
|
||||
static InstanceHandle createInstance(struct UAVOData * obj, uint16_t instId);
|
||||
static InstanceHandle getInstance(struct UAVOData * obj, uint16_t instId);
|
||||
static int32_t connectObj(UAVObjHandle obj_handle, xQueueHandle queue,
|
||||
UAVObjEventCallback cb, uint8_t eventMask);
|
||||
static int32_t disconnectObj(UAVObjHandle obj_handle, xQueueHandle queue,
|
||||
UAVObjEventCallback cb);
|
||||
|
||||
#if defined(PIOS_INCLUDE_SDCARD)
|
||||
static void objectFilename(ObjectList * obj, uint8_t * filename);
|
||||
static void objectFilename(UAVObjHandle obj_handle, uint8_t * filename);
|
||||
static void customSPrintf(uint8_t * buffer, uint8_t * format, ...);
|
||||
#endif
|
||||
|
||||
// Private variables
|
||||
static ObjectList *objList;
|
||||
static struct UAVOData * uavo_list;
|
||||
static xSemaphoreHandle mutex;
|
||||
static UAVObjMetadata defMetadata;
|
||||
static const UAVObjMetadata defMetadata = {
|
||||
.flags = (ACCESS_READWRITE << UAVOBJ_ACCESS_SHIFT |
|
||||
ACCESS_READWRITE << UAVOBJ_GCS_ACCESS_SHIFT |
|
||||
1 << UAVOBJ_TELEMETRY_ACKED_SHIFT |
|
||||
1 << UAVOBJ_GCS_TELEMETRY_ACKED_SHIFT |
|
||||
UPDATEMODE_ONCHANGE << UAVOBJ_TELEMETRY_UPDATE_MODE_SHIFT |
|
||||
UPDATEMODE_ONCHANGE << UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT),
|
||||
.telemetryUpdatePeriod = 0,
|
||||
.gcsTelemetryUpdatePeriod = 0,
|
||||
.loggingUpdatePeriod = 0,
|
||||
};
|
||||
|
||||
static UAVObjStats stats;
|
||||
|
||||
/**
|
||||
@ -126,31 +187,32 @@ static UAVObjStats stats;
|
||||
*/
|
||||
int32_t UAVObjInitialize()
|
||||
{
|
||||
// Initialize variables
|
||||
objList = NULL;
|
||||
memset(&stats, 0, sizeof(UAVObjStats));
|
||||
// Initialize variables
|
||||
uavo_list = NULL;
|
||||
memset(&stats, 0, sizeof(UAVObjStats));
|
||||
|
||||
// Create mutex
|
||||
mutex = xSemaphoreCreateRecursiveMutex();
|
||||
if (mutex == NULL)
|
||||
return -1;
|
||||
// Create mutex
|
||||
mutex = xSemaphoreCreateRecursiveMutex();
|
||||
if (mutex == NULL)
|
||||
return -1;
|
||||
|
||||
// Initialize default metadata structure (metadata of metaobjects)
|
||||
UAVObjMetadataInitialize(&defMetadata);
|
||||
|
||||
// Done
|
||||
return 0;
|
||||
// Done
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************
|
||||
* Statistics
|
||||
****************/
|
||||
|
||||
/**
|
||||
* Get the statistics counters
|
||||
* @param[out] statsOut The statistics counters will be copied there
|
||||
*/
|
||||
void UAVObjGetStats(UAVObjStats * statsOut)
|
||||
{
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
memcpy(statsOut, &stats, sizeof(UAVObjStats));
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
memcpy(statsOut, &stats, sizeof(UAVObjStats));
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -158,17 +220,84 @@ void UAVObjGetStats(UAVObjStats * statsOut)
|
||||
*/
|
||||
void UAVObjClearStats()
|
||||
{
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
memset(&stats, 0, sizeof(UAVObjStats));
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
memset(&stats, 0, sizeof(UAVObjStats));
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
}
|
||||
|
||||
/************************
|
||||
* Object Initialization
|
||||
***********************/
|
||||
|
||||
static void UAVObjInitMetaData (struct UAVOMeta * obj_meta)
|
||||
{
|
||||
/* Fill in the common part of the UAVO */
|
||||
struct UAVOBase * uavo_base = &(obj_meta->base);
|
||||
memset(uavo_base, 0, sizeof(*uavo_base));
|
||||
uavo_base->flags.isMeta = true;
|
||||
uavo_base->flags.isSingle = true;
|
||||
uavo_base->next_event = NULL;
|
||||
|
||||
/* Clear the instance data carried in the UAVO */
|
||||
memset(&(obj_meta->instance0), 0, sizeof(obj_meta->instance0));
|
||||
}
|
||||
|
||||
static struct UAVOData * UAVObjAllocSingle(uint32_t num_bytes)
|
||||
{
|
||||
/* Compute the complete size of the object, including the data for a single embedded instance */
|
||||
uint32_t object_size = sizeof(struct UAVOSingle) + num_bytes;
|
||||
|
||||
/* Allocate the object from the heap */
|
||||
struct UAVOSingle * uavo_single = (struct UAVOSingle *) pvPortMalloc(object_size);
|
||||
if (!uavo_single)
|
||||
return (NULL);
|
||||
|
||||
/* Fill in the common part of the UAVO */
|
||||
struct UAVOBase * uavo_base = &(uavo_single->uavo.base);
|
||||
memset(uavo_base, 0, sizeof(*uavo_base));
|
||||
uavo_base->flags.isSingle = true;
|
||||
uavo_base->next_event = NULL;
|
||||
|
||||
/* Clear the instance data carried in the UAVO */
|
||||
memset(&(uavo_single->instance0), 0, num_bytes);
|
||||
|
||||
/* Give back the generic UAVO part */
|
||||
return (&(uavo_single->uavo));
|
||||
}
|
||||
|
||||
static struct UAVOData * UAVObjAllocMulti(uint32_t num_bytes)
|
||||
{
|
||||
/* Compute the complete size of the object, including the data for a single embedded instance */
|
||||
uint32_t object_size = sizeof(struct UAVOMulti) + num_bytes;
|
||||
|
||||
/* Allocate the object from the heap */
|
||||
struct UAVOMulti * uavo_multi = (struct UAVOMulti *) pvPortMalloc(object_size);
|
||||
if (!uavo_multi)
|
||||
return (NULL);
|
||||
|
||||
/* Fill in the common part of the UAVO */
|
||||
struct UAVOBase * uavo_base = &(uavo_multi->uavo.base);
|
||||
memset(uavo_base, 0, sizeof(*uavo_base));
|
||||
uavo_base->flags.isSingle = false;
|
||||
uavo_base->next_event = NULL;
|
||||
|
||||
/* Set up the type-specific part of the UAVO */
|
||||
uavo_multi->num_instances = 1;
|
||||
|
||||
/* Clear the instance data carried in the UAVO */
|
||||
memset (&(uavo_multi->instance0), 0, num_bytes);
|
||||
|
||||
/* Give back the generic UAVO part */
|
||||
return (&(uavo_multi->uavo));
|
||||
}
|
||||
|
||||
/**************************
|
||||
* UAVObject Database APIs
|
||||
*************************/
|
||||
|
||||
/**
|
||||
* Register and new object in the object manager.
|
||||
* \param[in] id Unique object ID
|
||||
* \param[in] name Object name
|
||||
* \param[in] nameName Metaobject name
|
||||
* \param[in] isMetaobject Is this a metaobject (1:true, 0:false)
|
||||
* \param[in] isSingleInstance Is this a single instance or multi-instance object
|
||||
* \param[in] isSettings Is this a settings object
|
||||
* \param[in] numBytes Number of bytes of object data (for one instance)
|
||||
@ -176,85 +305,60 @@ void UAVObjClearStats()
|
||||
* \return Object handle, or NULL if failure.
|
||||
* \return
|
||||
*/
|
||||
UAVObjHandle UAVObjRegister(uint32_t id, const char *name,
|
||||
const char *metaName, int32_t isMetaobject,
|
||||
int32_t isSingleInstance, int32_t isSettings,
|
||||
uint32_t numBytes,
|
||||
UAVObjInitializeCallback initCb)
|
||||
UAVObjHandle UAVObjRegister(uint32_t id,
|
||||
int32_t isSingleInstance, int32_t isSettings,
|
||||
uint32_t num_bytes,
|
||||
UAVObjInitializeCallback initCb)
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
ObjectInstList *instEntry;
|
||||
ObjectList *metaObj;
|
||||
struct UAVOData * uavo_data = NULL;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Check that the object is not already registered
|
||||
LL_FOREACH(objList, objEntry) {
|
||||
if (objEntry->id == id) {
|
||||
// Already registered, ignore
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* Don't allow duplicate registrations */
|
||||
if (UAVObjGetByID(id))
|
||||
goto unlock_exit;
|
||||
|
||||
// Create and append entry
|
||||
objEntry = (ObjectList *) pvPortMalloc(sizeof(ObjectList));
|
||||
if (objEntry == NULL) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
}
|
||||
objEntry->id = id;
|
||||
objEntry->name = name;
|
||||
OLSetIsMetaobject(objEntry, isMetaobject);
|
||||
OLSetIsSingleInstance(objEntry, isSingleInstance);
|
||||
OLSetIsSettings(objEntry, isSettings);
|
||||
objEntry->numBytes = numBytes;
|
||||
objEntry->events = NULL;
|
||||
objEntry->numInstances = 0;
|
||||
objEntry->instances.data = NULL;
|
||||
objEntry->instances.instId = 0xFFFF;
|
||||
objEntry->instances.next = NULL;
|
||||
objEntry->linkedObj = NULL; // will be set later
|
||||
LL_APPEND(objList, objEntry);
|
||||
/* Map the various flags to one of the UAVO types we understand */
|
||||
if (isSingleInstance) {
|
||||
uavo_data = UAVObjAllocSingle (num_bytes);
|
||||
} else {
|
||||
uavo_data = UAVObjAllocMulti (num_bytes);
|
||||
}
|
||||
|
||||
// Create instance zero
|
||||
instEntry = createInstance(objEntry, 0);
|
||||
if (instEntry == NULL) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
}
|
||||
// Create metaobject and update linkedObj
|
||||
if (isMetaobject) {
|
||||
objEntry->linkedObj = NULL; // will be set later
|
||||
} else {
|
||||
// Create metaobject
|
||||
metaObj =
|
||||
(ObjectList *) UAVObjRegister(id + 1, metaName,
|
||||
NULL, 1, 1, 0,
|
||||
sizeof
|
||||
(UAVObjMetadata),
|
||||
NULL);
|
||||
// Link two objects
|
||||
objEntry->linkedObj = metaObj;
|
||||
metaObj->linkedObj = objEntry;
|
||||
}
|
||||
if (!uavo_data)
|
||||
goto unlock_exit;
|
||||
|
||||
// Initialize object fields and metadata to default values
|
||||
if (initCb != NULL) {
|
||||
initCb((UAVObjHandle) objEntry, 0);
|
||||
}
|
||||
// Attempt to load object's metadata from the SD card (not done directly on the metaobject, but through the object)
|
||||
if (!OLGetIsMetaobject(objEntry)) {
|
||||
UAVObjLoad((UAVObjHandle) objEntry->linkedObj, 0);
|
||||
}
|
||||
// If this is a settings object, attempt to load from SD card
|
||||
if (OLGetIsSettings(objEntry)) {
|
||||
UAVObjLoad((UAVObjHandle) objEntry, 0);
|
||||
}
|
||||
// Release lock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return (UAVObjHandle) objEntry;
|
||||
/* Fill in the details about this UAVO */
|
||||
uavo_data->id = id;
|
||||
uavo_data->instance_size = num_bytes;
|
||||
if (isSettings) {
|
||||
uavo_data->base.flags.isSettings = true;
|
||||
}
|
||||
|
||||
/* Initialize the embedded meta UAVO */
|
||||
UAVObjInitMetaData (&uavo_data->metaObj);
|
||||
|
||||
/* Add the newly created object to the global list of objects */
|
||||
LL_APPEND(uavo_list, uavo_data);
|
||||
|
||||
/* Initialize object fields and metadata to default values */
|
||||
if (initCb)
|
||||
initCb((UAVObjHandle) uavo_data, 0);
|
||||
|
||||
/* Always try to load the meta object from flash */
|
||||
UAVObjLoad((UAVObjHandle) &(uavo_data->metaObj), 0);
|
||||
|
||||
/* Attempt to load settings object from flash */
|
||||
if (uavo_data->base.flags.isSettings)
|
||||
UAVObjLoad((UAVObjHandle) uavo_data, 0);
|
||||
|
||||
// fire events for outer object and its embedded meta object
|
||||
UAVObjInstanceUpdated((UAVObjHandle) uavo_data, 0);
|
||||
UAVObjInstanceUpdated((UAVObjHandle) &(uavo_data->metaObj), 0);
|
||||
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return (UAVObjHandle) uavo_data;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -264,52 +368,27 @@ UAVObjHandle UAVObjRegister(uint32_t id, const char *name,
|
||||
*/
|
||||
UAVObjHandle UAVObjGetByID(uint32_t id)
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
UAVObjHandle * found_obj = (UAVObjHandle *) NULL;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Look for object
|
||||
LL_FOREACH(objList, objEntry) {
|
||||
if (objEntry->id == id) {
|
||||
// Release lock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
// Done, object found
|
||||
return (UAVObjHandle) objEntry;
|
||||
}
|
||||
}
|
||||
// Look for object
|
||||
struct UAVOData * tmp_obj;
|
||||
LL_FOREACH(uavo_list, tmp_obj) {
|
||||
if (tmp_obj->id == id) {
|
||||
found_obj = (UAVObjHandle *)tmp_obj;
|
||||
goto unlock_exit;
|
||||
}
|
||||
if (MetaObjectId(tmp_obj->id) == id) {
|
||||
found_obj = (UAVObjHandle *)&(tmp_obj->metaObj);
|
||||
goto unlock_exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Object not found, release lock and return error
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an object from the list given its name
|
||||
* \param[in] name The name of the object
|
||||
* \return The object or NULL if not found.
|
||||
*/
|
||||
UAVObjHandle UAVObjGetByName(char *name)
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Look for object
|
||||
LL_FOREACH(objList, objEntry) {
|
||||
if (objEntry->name != NULL
|
||||
&& strcmp(objEntry->name, name) == 0) {
|
||||
// Release lock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
// Done, object found
|
||||
return (UAVObjHandle) objEntry;
|
||||
}
|
||||
}
|
||||
|
||||
// Object not found, release lock and return error
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return found_obj;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -317,19 +396,24 @@ UAVObjHandle UAVObjGetByName(char *name)
|
||||
* \param[in] obj The object handle
|
||||
* \return The object ID
|
||||
*/
|
||||
uint32_t UAVObjGetID(UAVObjHandle obj)
|
||||
uint32_t UAVObjGetID(UAVObjHandle obj_handle)
|
||||
{
|
||||
return ((ObjectList *) obj)->id;
|
||||
}
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
/**
|
||||
* Get the object's name
|
||||
* \param[in] obj The object handle
|
||||
* \return The object's name
|
||||
*/
|
||||
const char *UAVObjGetName(UAVObjHandle obj)
|
||||
{
|
||||
return ((ObjectList *) obj)->name;
|
||||
/* Recover the common object header */
|
||||
struct UAVOBase * uavo_base = (struct UAVOBase *) obj_handle;
|
||||
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
/* We have a meta object, find our containing UAVO */
|
||||
struct UAVOData * uavo_data = container_of ((struct UAVOMeta *)uavo_base, struct UAVOData, metaObj);
|
||||
|
||||
return MetaObjectId (uavo_data->id);
|
||||
} else {
|
||||
/* We have a data object, augment our pointer */
|
||||
struct UAVOData * uavo_data = (struct UAVOData *) uavo_base;
|
||||
|
||||
return (uavo_data->id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -339,7 +423,23 @@ const char *UAVObjGetName(UAVObjHandle obj)
|
||||
*/
|
||||
uint32_t UAVObjGetNumBytes(UAVObjHandle obj)
|
||||
{
|
||||
return ((ObjectList *) obj)->numBytes;
|
||||
PIOS_Assert(obj);
|
||||
|
||||
uint32_t instance_size;
|
||||
|
||||
/* Recover the common object header */
|
||||
struct UAVOBase * uavo_base = (struct UAVOBase *) obj;
|
||||
|
||||
if (uavo_base->flags.isMeta) {
|
||||
instance_size = MetaNumBytes;
|
||||
} else {
|
||||
/* We have a data object, augment our pointer */
|
||||
struct UAVOData * uavo = (struct UAVOData *) uavo_base;
|
||||
|
||||
instance_size = uavo->instance_size;
|
||||
}
|
||||
|
||||
return (instance_size);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -349,9 +449,24 @@ uint32_t UAVObjGetNumBytes(UAVObjHandle obj)
|
||||
* \param[in] obj The object handle
|
||||
* \return The object linked object handle
|
||||
*/
|
||||
UAVObjHandle UAVObjGetLinkedObj(UAVObjHandle obj)
|
||||
UAVObjHandle UAVObjGetLinkedObj(UAVObjHandle obj_handle)
|
||||
{
|
||||
return (UAVObjHandle) (((ObjectList *) obj)->linkedObj);
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
/* Recover the common object header */
|
||||
struct UAVOBase * uavo_base = (struct UAVOBase *) obj_handle;
|
||||
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
/* We have a meta object, find our containing UAVO. */
|
||||
struct UAVOData * uavo_data = container_of ((struct UAVOMeta *)uavo_base, struct UAVOData, metaObj);
|
||||
|
||||
return (UAVObjHandle) uavo_data;
|
||||
} else {
|
||||
/* We have a data object, augment our pointer */
|
||||
struct UAVOData * uavo_data = (struct UAVOData *) uavo_base;
|
||||
|
||||
return (UAVObjHandle) &(uavo_data->metaObj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -359,13 +474,19 @@ UAVObjHandle UAVObjGetLinkedObj(UAVObjHandle obj)
|
||||
* \param[in] obj The object handle
|
||||
* \return The number of instances
|
||||
*/
|
||||
uint16_t UAVObjGetNumInstances(UAVObjHandle obj)
|
||||
uint16_t UAVObjGetNumInstances(UAVObjHandle obj_handle)
|
||||
{
|
||||
uint32_t numInstances;
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
numInstances = ((ObjectList *) obj)->numInstances;
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return numInstances;
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
if (UAVObjIsSingleInstance(obj_handle)) {
|
||||
/* Only one instance is allowed */
|
||||
return 1;
|
||||
} else {
|
||||
/* Multi-instance object. Inspect the object */
|
||||
/* Augment our pointer to reflect the proper type */
|
||||
struct UAVOMulti * uavo_multi = (struct UAVOMulti *) obj_handle;
|
||||
return uavo_multi->num_instances;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -373,29 +494,37 @@ uint16_t UAVObjGetNumInstances(UAVObjHandle obj)
|
||||
* \param[in] obj The object handle
|
||||
* \return The instance ID or 0 if an error
|
||||
*/
|
||||
uint16_t UAVObjCreateInstance(UAVObjHandle obj,
|
||||
UAVObjInitializeCallback initCb)
|
||||
uint16_t UAVObjCreateInstance(UAVObjHandle obj_handle,
|
||||
UAVObjInitializeCallback initCb)
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
ObjectInstList *instEntry;
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create new instance
|
||||
objEntry = (ObjectList *) obj;
|
||||
instEntry = createInstance(objEntry, objEntry->numInstances);
|
||||
if (instEntry == NULL) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Initialize instance data
|
||||
if (initCb != NULL) {
|
||||
initCb(obj, instEntry->instId);
|
||||
}
|
||||
// Unlock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return instEntry->instId;
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
InstanceHandle instEntry;
|
||||
uint16_t instId = 0;
|
||||
|
||||
// Create new instance
|
||||
instId = UAVObjGetNumInstances(obj_handle);
|
||||
instEntry = createInstance( (struct UAVOData *)obj_handle, instId);
|
||||
if (instEntry == NULL) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
// Initialize instance data
|
||||
if (initCb) {
|
||||
initCb(obj_handle, instId);
|
||||
}
|
||||
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
|
||||
return instId;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -403,9 +532,14 @@ uint16_t UAVObjCreateInstance(UAVObjHandle obj,
|
||||
* \param[in] obj The object handle
|
||||
* \return True (1) if this is a single instance object
|
||||
*/
|
||||
int32_t UAVObjIsSingleInstance(UAVObjHandle obj)
|
||||
bool UAVObjIsSingleInstance(UAVObjHandle obj_handle)
|
||||
{
|
||||
return OLGetIsSingleInstance((ObjectList *) obj);
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
/* Recover the common object header */
|
||||
struct UAVOBase * uavo_base = (struct UAVOBase *) obj_handle;
|
||||
|
||||
return uavo_base->flags.isSingle;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -413,9 +547,14 @@ int32_t UAVObjIsSingleInstance(UAVObjHandle obj)
|
||||
* \param[in] obj The object handle
|
||||
* \return True (1) if this is metaobject
|
||||
*/
|
||||
int32_t UAVObjIsMetaobject(UAVObjHandle obj)
|
||||
bool UAVObjIsMetaobject(UAVObjHandle obj_handle)
|
||||
{
|
||||
return OLGetIsMetaobject((ObjectList *) obj);
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
/* Recover the common object header */
|
||||
struct UAVOBase * uavo_base = (struct UAVOBase *) obj_handle;
|
||||
|
||||
return uavo_base->flags.isMeta;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -423,9 +562,14 @@ int32_t UAVObjIsMetaobject(UAVObjHandle obj)
|
||||
* \param[in] obj The object handle
|
||||
* \return True (1) if this is a settings object
|
||||
*/
|
||||
int32_t UAVObjIsSettings(UAVObjHandle obj)
|
||||
bool UAVObjIsSettings(UAVObjHandle obj_handle)
|
||||
{
|
||||
return OLGetIsSettings((ObjectList *) obj);
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
/* Recover the common object header */
|
||||
struct UAVOBase * uavo_base = (struct UAVOBase *) obj_handle;
|
||||
|
||||
return uavo_base->flags.isSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -435,39 +579,49 @@ int32_t UAVObjIsSettings(UAVObjHandle obj)
|
||||
* \param[in] dataIn The byte array
|
||||
* \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_handle, uint16_t instId,
|
||||
const uint8_t * dataIn)
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
ObjectInstList *instEntry;
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Cast handle to object
|
||||
objEntry = (ObjectList *) obj;
|
||||
int32_t rc = -1;
|
||||
|
||||
// Get the instance
|
||||
instEntry = getInstance(objEntry, instId);
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
if (instId != 0) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
memcpy(MetaDataPtr((struct UAVOMeta *)obj_handle), dataIn, MetaNumBytes);
|
||||
} else {
|
||||
struct UAVOData *obj;
|
||||
InstanceHandle instEntry;
|
||||
|
||||
// If the instance does not exist create it and any other instances before it
|
||||
if (instEntry == NULL) {
|
||||
instEntry = createInstance(objEntry, instId);
|
||||
if (instEntry == NULL) {
|
||||
// Error, unlock and return
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// Set the data
|
||||
memcpy(instEntry->data, dataIn, objEntry->numBytes);
|
||||
// Cast handle to object
|
||||
obj = (struct UAVOData *) obj_handle;
|
||||
|
||||
// Fire event
|
||||
sendEvent(objEntry, instId, EV_UNPACKED);
|
||||
// Get the instance
|
||||
instEntry = getInstance(obj, instId);
|
||||
|
||||
// Unlock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
// If the instance does not exist create it and any other instances before it
|
||||
if (instEntry == NULL) {
|
||||
instEntry = createInstance(obj, instId);
|
||||
if (instEntry == NULL) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
}
|
||||
// Set the data
|
||||
memcpy(InstanceData(instEntry), dataIn, obj->instance_size);
|
||||
}
|
||||
|
||||
// Fire event
|
||||
sendEvent((struct UAVOBase*)obj_handle, instId, EV_UNPACKED);
|
||||
rc = 0;
|
||||
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -477,30 +631,41 @@ int32_t UAVObjUnpack(UAVObjHandle obj, uint16_t instId,
|
||||
* \param[out] dataOut The byte array
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjPack(UAVObjHandle obj, uint16_t instId, uint8_t * dataOut)
|
||||
int32_t UAVObjPack(UAVObjHandle obj_handle, uint16_t instId, uint8_t * dataOut)
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
ObjectInstList *instEntry;
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Cast handle to object
|
||||
objEntry = (ObjectList *) obj;
|
||||
int32_t rc = -1;
|
||||
|
||||
// Get the instance
|
||||
instEntry = getInstance(objEntry, instId);
|
||||
if (instEntry == NULL) {
|
||||
// Error, unlock and return
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Pack data
|
||||
memcpy(dataOut, instEntry->data, objEntry->numBytes);
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
if (instId != 0) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
memcpy(dataOut, MetaDataPtr((struct UAVOMeta *)obj_handle), MetaNumBytes);
|
||||
} else {
|
||||
struct UAVOData *obj;
|
||||
InstanceHandle instEntry;
|
||||
|
||||
// Unlock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
// Cast handle to object
|
||||
obj = (struct UAVOData *) obj_handle;
|
||||
|
||||
// Get the instance
|
||||
instEntry = getInstance(obj, instId);
|
||||
if (instEntry == NULL) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
// Pack data
|
||||
memcpy(dataOut, InstanceData(instEntry), obj->instance_size);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -512,50 +677,72 @@ int32_t UAVObjPack(UAVObjHandle obj, uint16_t instId, uint8_t * dataOut)
|
||||
* @param[in] file File to append to
|
||||
* @return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjSaveToFile(UAVObjHandle obj, uint16_t instId,
|
||||
FILEINFO * file)
|
||||
int32_t UAVObjSaveToFile(UAVObjHandle obj_handle, uint16_t instId,
|
||||
FILEINFO * file)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
#if defined(PIOS_INCLUDE_SDCARD)
|
||||
uint32_t bytesWritten;
|
||||
ObjectList *objEntry;
|
||||
ObjectInstList *instEntry;
|
||||
uint32_t bytesWritten;
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// 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);
|
||||
|
||||
// Cast to object
|
||||
objEntry = (ObjectList *) obj;
|
||||
// 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;
|
||||
|
||||
// Get the instance information
|
||||
instEntry = getInstance(objEntry, instId);
|
||||
if (instEntry == NULL) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Write the object ID
|
||||
PIOS_FWRITE(file, &objEntry->id, sizeof(objEntry->id),
|
||||
&bytesWritten);
|
||||
// Cast to object
|
||||
uavo = (struct UAVOData *) obj_handle;
|
||||
|
||||
// Write the instance ID
|
||||
if (!OLGetIsSingleInstance(objEntry)) {
|
||||
PIOS_FWRITE(file, &instEntry->instId,
|
||||
sizeof(instEntry->instId), &bytesWritten);
|
||||
}
|
||||
// Write the data and check that the write was successful
|
||||
PIOS_FWRITE(file, instEntry->data, objEntry->numBytes,
|
||||
&bytesWritten);
|
||||
if (bytesWritten != objEntry->numBytes) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Done
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
// 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);
|
||||
#endif /* PIOS_INCLUDE_SDCARD */
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -568,59 +755,60 @@ int32_t UAVObjSaveToFile(UAVObjHandle obj, uint16_t instId,
|
||||
* @param[in] file File to append to
|
||||
* @return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjSave(UAVObjHandle obj, uint16_t instId)
|
||||
int32_t UAVObjSave(UAVObjHandle obj_handle, uint16_t instId)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
|
||||
ObjectList *objEntry = (ObjectList *) obj;
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
if (instId != 0)
|
||||
return -1;
|
||||
|
||||
if (objEntry == NULL)
|
||||
return -1;
|
||||
if (PIOS_FLASHFS_ObjSave(obj_handle, instId, (uint8_t*) MetaDataPtr((struct UAVOMeta *)obj_handle)) != 0)
|
||||
return -1;
|
||||
} else {
|
||||
InstanceHandle instEntry = getInstance( (struct UAVOData *)obj_handle, instId);
|
||||
|
||||
ObjectInstList *instEntry = getInstance(objEntry, instId);
|
||||
if (instEntry == NULL)
|
||||
return -1;
|
||||
|
||||
if (instEntry == NULL)
|
||||
return -1;
|
||||
if (InstanceData(instEntry) == NULL)
|
||||
return -1;
|
||||
|
||||
if (instEntry->data == NULL)
|
||||
return -1;
|
||||
|
||||
if (PIOS_FLASHFS_ObjSave(obj, instId, instEntry->data) != 0)
|
||||
return -1;
|
||||
if (PIOS_FLASHFS_ObjSave(obj_handle, instId, InstanceData(instEntry)) != 0)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#if defined(PIOS_INCLUDE_SDCARD)
|
||||
FILEINFO file;
|
||||
ObjectList *objEntry;
|
||||
uint8_t filename[14];
|
||||
FILEINFO file;
|
||||
uint8_t filename[14];
|
||||
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Cast to object
|
||||
objEntry = (ObjectList *) obj;
|
||||
// Get filename
|
||||
objectFilename(obj_handle, filename);
|
||||
|
||||
// Get filename
|
||||
objectFilename(objEntry, filename);
|
||||
|
||||
// Open file
|
||||
if (PIOS_FOPEN_WRITE(filename, file)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Append object
|
||||
if (UAVObjSaveToFile(obj, instId, &file) == -1) {
|
||||
PIOS_FCLOSE(file);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Done, close file and unlock
|
||||
PIOS_FCLOSE(file);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
// 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_INCLUDE_SDCARD */
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -631,68 +819,87 @@ int32_t UAVObjSave(UAVObjHandle obj, uint16_t instId)
|
||||
UAVObjHandle UAVObjLoadFromFile(FILEINFO * file)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_SDCARD)
|
||||
uint32_t bytesRead;
|
||||
ObjectList *objEntry;
|
||||
ObjectInstList *instEntry;
|
||||
uint32_t objId;
|
||||
uint16_t instId;
|
||||
UAVObjHandle obj;
|
||||
uint32_t bytesRead;
|
||||
struct UAVOBase *objEntry;
|
||||
InstanceHandle instEntry;
|
||||
uint32_t objId;
|
||||
uint16_t instId;
|
||||
UAVObjHandle obj_handle;
|
||||
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return NULL;
|
||||
}
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return NULL;
|
||||
}
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Read the object ID
|
||||
if (PIOS_FREAD(file, &objId, sizeof(objId), &bytesRead)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
}
|
||||
// Get the object
|
||||
obj = UAVObjGetByID(objId);
|
||||
if (obj == 0) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
}
|
||||
objEntry = (ObjectList *) obj;
|
||||
// Read the object ID
|
||||
if (PIOS_FREAD(file, &objId, sizeof(objId), &bytesRead)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
}
|
||||
// Get the object
|
||||
obj_handle = UAVObjGetByID(objId);
|
||||
if (obj_handle == 0) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
}
|
||||
objEntry = (struct UAVOBase *) obj_handle;
|
||||
|
||||
// Get the instance ID
|
||||
instId = 0;
|
||||
if (!OLGetIsSingleInstance(objEntry)) {
|
||||
if (PIOS_FREAD
|
||||
// Get the instance ID
|
||||
instId = 0;
|
||||
if (!UAVObjIsSingleInstance(obj_handle)) {
|
||||
if (PIOS_FREAD
|
||||
(file, &instId, sizeof(instId), &bytesRead)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// Get the instance information
|
||||
instEntry = getInstance(objEntry, instId);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// If the instance does not exist create it and any other instances before it
|
||||
if (instEntry == NULL) {
|
||||
instEntry = createInstance(objEntry, instId);
|
||||
if (instEntry == NULL) {
|
||||
// Error, unlock and return
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// Read the instance data
|
||||
if (PIOS_FREAD
|
||||
(file, instEntry->data, objEntry->numBytes, &bytesRead)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
}
|
||||
// Fire event
|
||||
sendEvent(objEntry, instId, EV_UNPACKED);
|
||||
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 NULL;
|
||||
}
|
||||
// Read the instance data
|
||||
if (PIOS_FREAD
|
||||
(file, MetaDataPtr((struct UAVOMeta *)obj_handle), MetaNumBytes, &bytesRead)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
|
||||
// Unlock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return obj;
|
||||
// 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 NULL;
|
||||
}
|
||||
}
|
||||
// Read the instance data
|
||||
if (PIOS_FREAD
|
||||
(file, InstanceData(instEntry), ((struct UAVOData *)objEntry)->instance_size, &bytesRead)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Fire event
|
||||
sendEvent(objEntry, instId, EV_UNPACKED);
|
||||
|
||||
// Unlock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return obj_handle;
|
||||
#else /* PIOS_INCLUDE_SDCARD */
|
||||
return NULL;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -704,74 +911,74 @@ UAVObjHandle UAVObjLoadFromFile(FILEINFO * file)
|
||||
* @param[in] instId The object instance
|
||||
* @return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjLoad(UAVObjHandle obj, uint16_t instId)
|
||||
int32_t UAVObjLoad(UAVObjHandle obj_handle, uint16_t instId)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
|
||||
ObjectList *objEntry = (ObjectList *) obj;
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
if (instId != 0)
|
||||
return -1;
|
||||
|
||||
if (objEntry == NULL)
|
||||
return -1;
|
||||
// Fire event on success
|
||||
if (PIOS_FLASHFS_ObjLoad(obj_handle, instId, (uint8_t*) MetaDataPtr((struct UAVOMeta *)obj_handle)) == 0)
|
||||
sendEvent((struct UAVOBase*)obj_handle, instId, EV_UNPACKED);
|
||||
else
|
||||
return -1;
|
||||
} else {
|
||||
|
||||
ObjectInstList *instEntry = getInstance(objEntry, instId);
|
||||
InstanceHandle instEntry = getInstance( (struct UAVOData *)obj_handle, instId);
|
||||
|
||||
if (instEntry == NULL)
|
||||
return -1;
|
||||
if (instEntry == NULL)
|
||||
return -1;
|
||||
|
||||
if (instEntry->data == NULL)
|
||||
return -1;
|
||||
// Fire event on success
|
||||
if (PIOS_FLASHFS_ObjLoad(obj_handle, instId, InstanceData(instEntry)) == 0)
|
||||
sendEvent((struct UAVOBase*)obj_handle, instId, EV_UNPACKED);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Fire event on success
|
||||
int32_t retval;
|
||||
if ((retval = PIOS_FLASHFS_ObjLoad(obj, instId, instEntry->data)) == 0)
|
||||
sendEvent(objEntry, instId, EV_UNPACKED);
|
||||
else
|
||||
return retval;
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_INCLUDE_SDCARD)
|
||||
FILEINFO file;
|
||||
ObjectList *objEntry;
|
||||
UAVObjHandle loadedObj;
|
||||
ObjectList *loadedObjEntry;
|
||||
uint8_t filename[14];
|
||||
FILEINFO file;
|
||||
UAVObjHandle loadedObj;
|
||||
uint8_t filename[14];
|
||||
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Cast to object
|
||||
objEntry = (ObjectList *) obj;
|
||||
// Get filename
|
||||
objectFilename(obj_handle, filename);
|
||||
|
||||
// Get filename
|
||||
objectFilename(objEntry, filename);
|
||||
|
||||
// Open file
|
||||
if (PIOS_FOPEN_READ(filename, file)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Load object
|
||||
loadedObj = UAVObjLoadFromFile(&file);
|
||||
if (loadedObj == 0) {
|
||||
PIOS_FCLOSE(file);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Check that the IDs match
|
||||
loadedObjEntry = (ObjectList *) loadedObj;
|
||||
if (loadedObjEntry->id != objEntry->id) {
|
||||
PIOS_FCLOSE(file);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Done, close file and unlock
|
||||
PIOS_FCLOSE(file);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
// Open file
|
||||
if (PIOS_FOPEN_READ(filename, file)) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Load object
|
||||
loadedObj = UAVObjLoadFromFile(&file);
|
||||
if (loadedObj == 0) {
|
||||
PIOS_FCLOSE(file);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Check that the IDs match
|
||||
if (UAVObjGetID(loadedObj) != UAVObjGetID(obj_handle)) {
|
||||
PIOS_FCLOSE(file);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Done, close file and unlock
|
||||
PIOS_FCLOSE(file);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif /* PIOS_INCLUDE_SDCARD */
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -780,35 +987,32 @@ int32_t UAVObjLoad(UAVObjHandle obj, uint16_t instId)
|
||||
* @param[in] instId The object instance
|
||||
* @return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjDelete(UAVObjHandle obj, uint16_t instId)
|
||||
int32_t UAVObjDelete(UAVObjHandle obj_handle, uint16_t instId)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
#if defined(PIOS_INCLUDE_FLASH_SECTOR_SETTINGS)
|
||||
PIOS_FLASHFS_ObjDelete(obj, instId);
|
||||
PIOS_FLASHFS_ObjDelete(obj_handle, instId);
|
||||
#endif
|
||||
#if defined(PIOS_INCLUDE_SDCARD)
|
||||
ObjectList *objEntry;
|
||||
uint8_t filename[14];
|
||||
uint8_t filename[14];
|
||||
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Check for file system availability
|
||||
if (PIOS_SDCARD_IsMounted() == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Cast to object
|
||||
objEntry = (ObjectList *) obj;
|
||||
// Get filename
|
||||
objectFilename(obj_handle, filename);
|
||||
|
||||
// Get filename
|
||||
objectFilename(objEntry, filename);
|
||||
// Delete file
|
||||
PIOS_FUNLINK(filename);
|
||||
|
||||
// Delete file
|
||||
PIOS_FUNLINK(filename);
|
||||
|
||||
// Done
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
// Done
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
#endif /* PIOS_INCLUDE_SDCARD */
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -817,27 +1021,30 @@ int32_t UAVObjDelete(UAVObjHandle obj, uint16_t instId)
|
||||
*/
|
||||
int32_t UAVObjSaveSettings()
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Save all settings objects
|
||||
LL_FOREACH(objList, objEntry) {
|
||||
// Check if this is a settings object
|
||||
if (OLGetIsSettings(objEntry)) {
|
||||
// Save object
|
||||
if (UAVObjSave((UAVObjHandle) objEntry, 0) ==
|
||||
-1) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
int32_t rc = -1;
|
||||
|
||||
// Done
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
// Save all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
// Check if this is a settings object
|
||||
if (UAVObjIsSettings(obj)) {
|
||||
// Save object
|
||||
if (UAVObjSave((UAVObjHandle) obj, 0) ==
|
||||
-1) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -846,27 +1053,30 @@ int32_t UAVObjSaveSettings()
|
||||
*/
|
||||
int32_t UAVObjLoadSettings()
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Load all settings objects
|
||||
LL_FOREACH(objList, objEntry) {
|
||||
// Check if this is a settings object
|
||||
if (OLGetIsSettings(objEntry)) {
|
||||
// Load object
|
||||
if (UAVObjLoad((UAVObjHandle) objEntry, 0) ==
|
||||
-1) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
int32_t rc = -1;
|
||||
|
||||
// Done
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
// Load all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
// Check if this is a settings object
|
||||
if (UAVObjIsSettings(obj)) {
|
||||
// Load object
|
||||
if (UAVObjLoad((UAVObjHandle) obj, 0) ==
|
||||
-1) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -875,27 +1085,30 @@ int32_t UAVObjLoadSettings()
|
||||
*/
|
||||
int32_t UAVObjDeleteSettings()
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Save all settings objects
|
||||
LL_FOREACH(objList, objEntry) {
|
||||
// Check if this is a settings object
|
||||
if (OLGetIsSettings(objEntry)) {
|
||||
// Save object
|
||||
if (UAVObjDelete((UAVObjHandle) objEntry, 0)
|
||||
== -1) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
int32_t rc = -1;
|
||||
|
||||
// Done
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
// Save all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
// Check if this is a settings object
|
||||
if (UAVObjIsSettings(obj)) {
|
||||
// Save object
|
||||
if (UAVObjDelete((UAVObjHandle) obj, 0)
|
||||
== -1) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -904,27 +1117,27 @@ int32_t UAVObjDeleteSettings()
|
||||
*/
|
||||
int32_t UAVObjSaveMetaobjects()
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Save all settings objects
|
||||
LL_FOREACH(objList, objEntry) {
|
||||
// Check if this is a settings object
|
||||
if (OLGetIsMetaobject(objEntry)) {
|
||||
// Save object
|
||||
if (UAVObjSave((UAVObjHandle) objEntry, 0) ==
|
||||
-1) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
int32_t rc = -1;
|
||||
|
||||
// Done
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
// Save all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
// Save object
|
||||
if (UAVObjSave( (UAVObjHandle) MetaObjectPtr(obj), 0) ==
|
||||
-1) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -933,27 +1146,27 @@ int32_t UAVObjSaveMetaobjects()
|
||||
*/
|
||||
int32_t UAVObjLoadMetaobjects()
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Load all settings objects
|
||||
LL_FOREACH(objList, objEntry) {
|
||||
// Check if this is a settings object
|
||||
if (OLGetIsMetaobject(objEntry)) {
|
||||
// Load object
|
||||
if (UAVObjLoad((UAVObjHandle) objEntry, 0) ==
|
||||
-1) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
int32_t rc = -1;
|
||||
|
||||
// Done
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
// Load all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
// Load object
|
||||
if (UAVObjLoad((UAVObjHandle) MetaObjectPtr(obj), 0) ==
|
||||
-1) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -962,253 +1175,293 @@ int32_t UAVObjLoadMetaobjects()
|
||||
*/
|
||||
int32_t UAVObjDeleteMetaobjects()
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Load all settings objects
|
||||
LL_FOREACH(objList, objEntry) {
|
||||
// Check if this is a settings object
|
||||
if (OLGetIsMetaobject(objEntry)) {
|
||||
// Load object
|
||||
if (UAVObjDelete((UAVObjHandle) objEntry, 0)
|
||||
== -1) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Done
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the object data
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] dataIn The object's data structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjSetData(UAVObjHandle obj, const void *dataIn)
|
||||
{
|
||||
return UAVObjSetInstanceData(obj, 0, dataIn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the object data
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] dataIn The object's data structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjSetDataField(UAVObjHandle obj, const void* dataIn, uint32_t offset, uint32_t size)
|
||||
{
|
||||
return UAVObjSetInstanceDataField(obj, 0, dataIn, offset, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object data
|
||||
* \param[in] obj The object handle
|
||||
* \param[out] dataOut The object's data structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjGetData(UAVObjHandle obj, void *dataOut)
|
||||
{
|
||||
return UAVObjGetInstanceData(obj, 0, dataOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object data
|
||||
* \param[in] obj The object handle
|
||||
* \param[out] dataOut The object's data structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjGetDataField(UAVObjHandle obj, void* dataOut, uint32_t offset, uint32_t size)
|
||||
{
|
||||
return UAVObjGetInstanceDataField(obj, 0, dataOut, offset, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data of a specific object instance
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] instId The object instance ID
|
||||
* \param[in] dataIn The object's data structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjSetInstanceData(UAVObjHandle obj, uint16_t instId,
|
||||
const void *dataIn)
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
ObjectInstList *instEntry;
|
||||
UAVObjMetadata *mdata;
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Cast to object info
|
||||
objEntry = (ObjectList *) obj;
|
||||
|
||||
// Check access level
|
||||
if (!OLGetIsMetaobject(objEntry)) {
|
||||
mdata =
|
||||
(UAVObjMetadata *) (objEntry->linkedObj->instances.
|
||||
data);
|
||||
if (UAVObjGetAccess(mdata) == ACCESS_READONLY) {
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// Get instance information
|
||||
instEntry = getInstance(objEntry, instId);
|
||||
if (instEntry == NULL) {
|
||||
// Error, unlock and return
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Set data
|
||||
memcpy(instEntry->data, dataIn, objEntry->numBytes);
|
||||
|
||||
// Fire event
|
||||
sendEvent(objEntry, instId, EV_UPDATED);
|
||||
|
||||
// Unlock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data of a specific object instance
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] instId The object instance ID
|
||||
* \param[in] dataIn The object's data structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjSetInstanceDataField(UAVObjHandle obj, uint16_t instId, const void* dataIn, uint32_t offset, uint32_t size)
|
||||
{
|
||||
ObjectList* objEntry;
|
||||
ObjectInstList* instEntry;
|
||||
UAVObjMetadata* mdata;
|
||||
|
||||
// Lock
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Cast to object info
|
||||
objEntry = (ObjectList*)obj;
|
||||
int32_t rc = -1;
|
||||
|
||||
// Check access level
|
||||
if ( !OLGetIsMetaobject(objEntry) )
|
||||
{
|
||||
mdata = (UAVObjMetadata*)(objEntry->linkedObj->instances.data);
|
||||
if ( UAVObjGetAccess(mdata) == ACCESS_READONLY )
|
||||
{
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
// Load all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
// Load object
|
||||
if (UAVObjDelete((UAVObjHandle) MetaObjectPtr(obj), 0)
|
||||
== -1) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Get instance information
|
||||
instEntry = getInstance(objEntry, instId);
|
||||
if ( instEntry == NULL )
|
||||
{
|
||||
// Error, unlock and return
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
rc = 0;
|
||||
|
||||
// return if we set too much of what we have
|
||||
if ( (size + offset) > objEntry->numBytes) {
|
||||
// Error, unlock and return
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set data
|
||||
memcpy(instEntry->data + offset, dataIn, size);
|
||||
|
||||
// Fire event
|
||||
sendEvent(objEntry, instId, EV_UPDATED);
|
||||
|
||||
// Unlock
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data of a specific object instance
|
||||
* Set the object data
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] instId The object instance ID
|
||||
* \param[out] dataOut The object's data structure
|
||||
* \param[in] dataIn The object's data structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjGetInstanceData(UAVObjHandle obj, uint16_t instId,
|
||||
void *dataOut)
|
||||
int32_t UAVObjSetData(UAVObjHandle obj_handle, const void *dataIn)
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
ObjectInstList *instEntry;
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Cast to object info
|
||||
objEntry = (ObjectList *) obj;
|
||||
|
||||
// Get instance information
|
||||
instEntry = getInstance(objEntry, instId);
|
||||
if (instEntry == NULL) {
|
||||
// Error, unlock and return
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
// Set data
|
||||
memcpy(dataOut, instEntry->data, objEntry->numBytes);
|
||||
|
||||
// Unlock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
return UAVObjSetInstanceData(obj_handle, 0, dataIn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data of a specific object instance
|
||||
* Set the object data
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] dataIn The object's data structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjSetDataField(UAVObjHandle obj_handle, const void* dataIn, uint32_t offset, uint32_t size)
|
||||
{
|
||||
return UAVObjSetInstanceDataField(obj_handle, 0, dataIn, offset, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object data
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] instId The object instance ID
|
||||
* \param[out] dataOut The object's data structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjGetInstanceDataField(UAVObjHandle obj, uint16_t instId, void* dataOut, uint32_t offset, uint32_t size)
|
||||
int32_t UAVObjGetData(UAVObjHandle obj_handle, void *dataOut)
|
||||
{
|
||||
ObjectList* objEntry;
|
||||
ObjectInstList* instEntry;
|
||||
return UAVObjGetInstanceData(obj_handle, 0, dataOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object data
|
||||
* \param[in] obj The object handle
|
||||
* \param[out] dataOut The object's data structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjGetDataField(UAVObjHandle obj_handle, void* dataOut, uint32_t offset, uint32_t size)
|
||||
{
|
||||
return UAVObjGetInstanceDataField(obj_handle, 0, dataOut, offset, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data of a specific object instance
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] instId The object instance ID
|
||||
* \param[in] dataIn The object's data structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjSetInstanceData(UAVObjHandle obj_handle, uint16_t instId,
|
||||
const void *dataIn)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Cast to object info
|
||||
objEntry = (ObjectList*)obj;
|
||||
int32_t rc = -1;
|
||||
|
||||
// Get instance information
|
||||
instEntry = getInstance(objEntry, instId);
|
||||
if ( instEntry == NULL )
|
||||
{
|
||||
// Error, unlock and return
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
if (instId != 0) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
memcpy(MetaDataPtr((struct UAVOMeta *)obj_handle), dataIn, MetaNumBytes);
|
||||
} else {
|
||||
struct UAVOData *obj;
|
||||
InstanceHandle instEntry;
|
||||
|
||||
// Cast to object info
|
||||
obj = (struct UAVOData *) obj_handle;
|
||||
|
||||
// Check access level
|
||||
if (UAVObjReadOnly(obj_handle)) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
// Get instance information
|
||||
instEntry = getInstance(obj, instId);
|
||||
if (instEntry == NULL) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
// Set data
|
||||
memcpy(InstanceData(instEntry), dataIn, obj->instance_size);
|
||||
}
|
||||
|
||||
// return if we request too much of what we can give
|
||||
if ( (size + offset) > objEntry->numBytes)
|
||||
{
|
||||
// Error, unlock and return
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set data
|
||||
memcpy(dataOut, instEntry->data + offset, size);
|
||||
// Fire event
|
||||
sendEvent((struct UAVOBase *)obj_handle, instId, EV_UPDATED);
|
||||
rc = 0;
|
||||
|
||||
// Unlock
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data of a specific object instance
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] instId The object instance ID
|
||||
* \param[in] dataIn The object's data structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjSetInstanceDataField(UAVObjHandle obj_handle, uint16_t instId, const void* dataIn, uint32_t offset, uint32_t size)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
// Get instance information
|
||||
if (instId != 0) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
// Check for overrun
|
||||
if ((size + offset) > MetaNumBytes) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
// Set data
|
||||
memcpy(MetaDataPtr((struct UAVOMeta *)obj_handle) + offset, dataIn, size);
|
||||
} else {
|
||||
struct UAVOData * obj;
|
||||
InstanceHandle instEntry;
|
||||
|
||||
// Cast to object info
|
||||
obj = (struct UAVOData *)obj_handle;
|
||||
|
||||
// Check access level
|
||||
if (UAVObjReadOnly(obj_handle)) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
// Get instance information
|
||||
instEntry = getInstance(obj, instId);
|
||||
if (instEntry == NULL) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
// Check for overrun
|
||||
if ((size + offset) > obj->instance_size) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
// Set data
|
||||
memcpy(InstanceData(instEntry) + offset, dataIn, size);
|
||||
}
|
||||
|
||||
|
||||
// Fire event
|
||||
sendEvent((struct UAVOBase *)obj_handle, instId, EV_UPDATED);
|
||||
rc = 0;
|
||||
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data of a specific object instance
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] instId The object instance ID
|
||||
* \param[out] dataOut The object's data structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjGetInstanceData(UAVObjHandle obj_handle, uint16_t instId,
|
||||
void *dataOut)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
// Get instance information
|
||||
if (instId != 0) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
// Set data
|
||||
memcpy(dataOut, MetaDataPtr((struct UAVOMeta *)obj_handle), MetaNumBytes);
|
||||
} else {
|
||||
struct UAVOData *obj;
|
||||
InstanceHandle instEntry;
|
||||
|
||||
// Cast to object info
|
||||
obj = (struct UAVOData *) obj_handle;
|
||||
|
||||
// Get instance information
|
||||
instEntry = getInstance(obj, instId);
|
||||
if (instEntry == NULL) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
// Set data
|
||||
memcpy(dataOut, InstanceData(instEntry), obj->instance_size);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data of a specific object instance
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] instId The object instance ID
|
||||
* \param[out] dataOut The object's data structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjGetInstanceDataField(UAVObjHandle obj_handle, uint16_t instId, void* dataOut, uint32_t offset, uint32_t size)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
// Get instance information
|
||||
if (instId != 0) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
// Check for overrun
|
||||
if ((size + offset) > MetaNumBytes) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
// Set data
|
||||
memcpy(dataOut, MetaDataPtr((struct UAVOMeta *)obj_handle) + offset, size);
|
||||
} else {
|
||||
struct UAVOData * obj;
|
||||
InstanceHandle instEntry;
|
||||
|
||||
// Cast to object info
|
||||
obj = (struct UAVOData *)obj_handle;
|
||||
|
||||
// Get instance information
|
||||
instEntry = getInstance(obj, instId);
|
||||
if (instEntry == NULL) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
// Check for overrun
|
||||
if ((size + offset) > obj->instance_size) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
// Set data
|
||||
memcpy(dataOut, InstanceData(instEntry) + offset, size);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1217,25 +1470,21 @@ int32_t UAVObjGetInstanceDataField(UAVObjHandle obj, uint16_t instId, void* data
|
||||
* \param[in] dataIn The object's metadata structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjSetMetadata(UAVObjHandle obj, const UAVObjMetadata * dataIn)
|
||||
int32_t UAVObjSetMetadata(UAVObjHandle obj_handle, const UAVObjMetadata * dataIn)
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Set metadata (metadata of metaobjects can not be modified)
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set metadata (metadata of metaobjects can not be modified)
|
||||
objEntry = (ObjectList *) obj;
|
||||
if (!OLGetIsMetaobject(objEntry)) {
|
||||
UAVObjSetData((UAVObjHandle) objEntry->linkedObj,
|
||||
dataIn);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Unlock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
UAVObjSetData((UAVObjHandle) MetaObjectPtr((struct UAVOData *)obj_handle), dataIn);
|
||||
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1244,44 +1493,29 @@ int32_t UAVObjSetMetadata(UAVObjHandle obj, const UAVObjMetadata * dataIn)
|
||||
* \param[out] dataOut The object's metadata structure
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjGetMetadata(UAVObjHandle obj, UAVObjMetadata * dataOut)
|
||||
int32_t UAVObjGetMetadata(UAVObjHandle obj_handle, UAVObjMetadata * dataOut)
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Get metadata
|
||||
objEntry = (ObjectList *) obj;
|
||||
if (OLGetIsMetaobject(objEntry)) {
|
||||
memcpy(dataOut, &defMetadata, sizeof(UAVObjMetadata));
|
||||
} else {
|
||||
UAVObjGetData((UAVObjHandle) objEntry->linkedObj,
|
||||
dataOut);
|
||||
}
|
||||
// Get metadata
|
||||
if (UAVObjIsMetaobject(obj_handle)) {
|
||||
memcpy(dataOut, &defMetadata, sizeof(UAVObjMetadata));
|
||||
} else {
|
||||
UAVObjGetData((UAVObjHandle) MetaObjectPtr( (struct UAVOData *)obj_handle ),
|
||||
dataOut);
|
||||
}
|
||||
|
||||
// Unlock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
// Unlock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a UAVObjMetadata object.
|
||||
* \param[in] metadata The metadata object
|
||||
*/
|
||||
void UAVObjMetadataInitialize(UAVObjMetadata* metadata)
|
||||
{
|
||||
metadata->flags =
|
||||
ACCESS_READWRITE << UAVOBJ_ACCESS_SHIFT |
|
||||
ACCESS_READWRITE << UAVOBJ_GCS_ACCESS_SHIFT |
|
||||
1 << UAVOBJ_TELEMETRY_ACKED_SHIFT |
|
||||
1 << UAVOBJ_GCS_TELEMETRY_ACKED_SHIFT |
|
||||
UPDATEMODE_ONCHANGE << UAVOBJ_TELEMETRY_UPDATE_MODE_SHIFT |
|
||||
UPDATEMODE_ONCHANGE << UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT;
|
||||
metadata->telemetryUpdatePeriod = 0;
|
||||
metadata->gcsTelemetryUpdatePeriod = 0;
|
||||
metadata->loggingUpdatePeriod = 0;
|
||||
}
|
||||
/*******************************
|
||||
* Object Metadata Manipulation
|
||||
******************************/
|
||||
|
||||
/**
|
||||
* Get the UAVObject metadata access member
|
||||
@ -1290,6 +1524,7 @@ void UAVObjMetadataInitialize(UAVObjMetadata* metadata)
|
||||
*/
|
||||
UAVObjAccessType UAVObjGetAccess(const UAVObjMetadata* metadata)
|
||||
{
|
||||
PIOS_Assert(metadata);
|
||||
return (metadata->flags >> UAVOBJ_ACCESS_SHIFT) & 1;
|
||||
}
|
||||
|
||||
@ -1300,6 +1535,7 @@ UAVObjAccessType UAVObjGetAccess(const UAVObjMetadata* metadata)
|
||||
*/
|
||||
void UAVObjSetAccess(UAVObjMetadata* metadata, UAVObjAccessType mode)
|
||||
{
|
||||
PIOS_Assert(metadata);
|
||||
SET_BITS(metadata->flags, UAVOBJ_ACCESS_SHIFT, mode, 1);
|
||||
}
|
||||
|
||||
@ -1310,6 +1546,7 @@ void UAVObjSetAccess(UAVObjMetadata* metadata, UAVObjAccessType mode)
|
||||
*/
|
||||
UAVObjAccessType UAVObjGetGcsAccess(const UAVObjMetadata* metadata)
|
||||
{
|
||||
PIOS_Assert(metadata);
|
||||
return (metadata->flags >> UAVOBJ_GCS_ACCESS_SHIFT) & 1;
|
||||
}
|
||||
|
||||
@ -1319,6 +1556,7 @@ UAVObjAccessType UAVObjGetGcsAccess(const UAVObjMetadata* metadata)
|
||||
* \param[in] mode The access mode
|
||||
*/
|
||||
void UAVObjSetGcsAccess(UAVObjMetadata* metadata, UAVObjAccessType mode) {
|
||||
PIOS_Assert(metadata);
|
||||
SET_BITS(metadata->flags, UAVOBJ_GCS_ACCESS_SHIFT, mode, 1);
|
||||
}
|
||||
|
||||
@ -1328,6 +1566,7 @@ void UAVObjSetGcsAccess(UAVObjMetadata* metadata, UAVObjAccessType mode) {
|
||||
* \return the telemetry acked boolean
|
||||
*/
|
||||
uint8_t UAVObjGetTelemetryAcked(const UAVObjMetadata* metadata) {
|
||||
PIOS_Assert(metadata);
|
||||
return (metadata->flags >> UAVOBJ_TELEMETRY_ACKED_SHIFT) & 1;
|
||||
}
|
||||
|
||||
@ -1337,6 +1576,7 @@ uint8_t UAVObjGetTelemetryAcked(const UAVObjMetadata* metadata) {
|
||||
* \param[in] val The telemetry acked boolean
|
||||
*/
|
||||
void UAVObjSetTelemetryAcked(UAVObjMetadata* metadata, uint8_t val) {
|
||||
PIOS_Assert(metadata);
|
||||
SET_BITS(metadata->flags, UAVOBJ_TELEMETRY_ACKED_SHIFT, val, 1);
|
||||
}
|
||||
|
||||
@ -1346,6 +1586,7 @@ void UAVObjSetTelemetryAcked(UAVObjMetadata* metadata, uint8_t val) {
|
||||
* \return the telemetry acked boolean
|
||||
*/
|
||||
uint8_t UAVObjGetGcsTelemetryAcked(const UAVObjMetadata* metadata) {
|
||||
PIOS_Assert(metadata);
|
||||
return (metadata->flags >> UAVOBJ_GCS_TELEMETRY_ACKED_SHIFT) & 1;
|
||||
}
|
||||
|
||||
@ -1355,6 +1596,7 @@ uint8_t UAVObjGetGcsTelemetryAcked(const UAVObjMetadata* metadata) {
|
||||
* \param[in] val The GCS telemetry acked boolean
|
||||
*/
|
||||
void UAVObjSetGcsTelemetryAcked(UAVObjMetadata* metadata, uint8_t val) {
|
||||
PIOS_Assert(metadata);
|
||||
SET_BITS(metadata->flags, UAVOBJ_GCS_TELEMETRY_ACKED_SHIFT, val, 1);
|
||||
}
|
||||
|
||||
@ -1364,6 +1606,7 @@ void UAVObjSetGcsTelemetryAcked(UAVObjMetadata* metadata, uint8_t val) {
|
||||
* \return the telemetry update mode
|
||||
*/
|
||||
UAVObjUpdateMode UAVObjGetTelemetryUpdateMode(const UAVObjMetadata* metadata) {
|
||||
PIOS_Assert(metadata);
|
||||
return (metadata->flags >> UAVOBJ_TELEMETRY_UPDATE_MODE_SHIFT) & UAVOBJ_UPDATE_MODE_MASK;
|
||||
}
|
||||
|
||||
@ -1373,6 +1616,7 @@ UAVObjUpdateMode UAVObjGetTelemetryUpdateMode(const UAVObjMetadata* metadata) {
|
||||
* \param[in] val The telemetry update mode
|
||||
*/
|
||||
void UAVObjSetTelemetryUpdateMode(UAVObjMetadata* metadata, UAVObjUpdateMode val) {
|
||||
PIOS_Assert(metadata);
|
||||
SET_BITS(metadata->flags, UAVOBJ_TELEMETRY_UPDATE_MODE_SHIFT, val, UAVOBJ_UPDATE_MODE_MASK);
|
||||
}
|
||||
|
||||
@ -1382,6 +1626,7 @@ void UAVObjSetTelemetryUpdateMode(UAVObjMetadata* metadata, UAVObjUpdateMode val
|
||||
* \return the GCS telemetry update mode
|
||||
*/
|
||||
UAVObjUpdateMode UAVObjGetGcsTelemetryUpdateMode(const UAVObjMetadata* metadata) {
|
||||
PIOS_Assert(metadata);
|
||||
return (metadata->flags >> UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT) & UAVOBJ_UPDATE_MODE_MASK;
|
||||
}
|
||||
|
||||
@ -1391,6 +1636,7 @@ UAVObjUpdateMode UAVObjGetGcsTelemetryUpdateMode(const UAVObjMetadata* metadata)
|
||||
* \param[in] val The GCS telemetry update mode
|
||||
*/
|
||||
void UAVObjSetGcsTelemetryUpdateMode(UAVObjMetadata* metadata, UAVObjUpdateMode val) {
|
||||
PIOS_Assert(metadata);
|
||||
SET_BITS(metadata->flags, UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT, val, UAVOBJ_UPDATE_MODE_MASK);
|
||||
}
|
||||
|
||||
@ -1403,22 +1649,13 @@ void UAVObjSetGcsTelemetryUpdateMode(UAVObjMetadata* metadata, UAVObjUpdateMode
|
||||
* \arg 1 if read only
|
||||
* \arg -1 if unable to get meta data
|
||||
*/
|
||||
int8_t UAVObjReadOnly(UAVObjHandle obj)
|
||||
int8_t UAVObjReadOnly(UAVObjHandle obj_handle)
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
UAVObjMetadata *mdata;
|
||||
|
||||
// Cast to object info
|
||||
objEntry = (ObjectList *) obj;
|
||||
|
||||
// Check access level
|
||||
if (!OLGetIsMetaobject(objEntry)) {
|
||||
mdata =
|
||||
(UAVObjMetadata *) (objEntry->linkedObj->instances.
|
||||
data);
|
||||
return UAVObjGetAccess(mdata) == ACCESS_READONLY;
|
||||
}
|
||||
return -1;
|
||||
PIOS_Assert(obj_handle);
|
||||
if (!UAVObjIsMetaobject(obj_handle)) {
|
||||
return UAVObjGetAccess(LinkedMetaDataPtr( (struct UAVOData *)obj_handle)) == ACCESS_READONLY;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1429,14 +1666,16 @@ 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)
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjConnectQueue(UAVObjHandle obj, xQueueHandle queue,
|
||||
uint8_t eventMask)
|
||||
int32_t UAVObjConnectQueue(UAVObjHandle obj_handle, xQueueHandle queue,
|
||||
uint8_t eventMask)
|
||||
{
|
||||
int32_t res;
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
res = connectObj(obj, queue, 0, eventMask);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return res;
|
||||
PIOS_Assert(obj_handle);
|
||||
PIOS_Assert(queue);
|
||||
int32_t res;
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
res = connectObj(obj_handle, queue, 0, eventMask);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1445,13 +1684,15 @@ int32_t UAVObjConnectQueue(UAVObjHandle obj, xQueueHandle queue,
|
||||
* \param[in] queue The event queue
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjDisconnectQueue(UAVObjHandle obj, xQueueHandle queue)
|
||||
int32_t UAVObjDisconnectQueue(UAVObjHandle obj_handle, xQueueHandle queue)
|
||||
{
|
||||
int32_t res;
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
res = disconnectObj(obj, queue, 0);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return res;
|
||||
PIOS_Assert(obj_handle);
|
||||
PIOS_Assert(queue);
|
||||
int32_t res;
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
res = disconnectObj(obj_handle, queue, 0);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1462,14 +1703,15 @@ 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)
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjConnectCallback(UAVObjHandle obj, UAVObjEventCallback cb,
|
||||
uint8_t eventMask)
|
||||
int32_t UAVObjConnectCallback(UAVObjHandle obj_handle, UAVObjEventCallback cb,
|
||||
uint8_t eventMask)
|
||||
{
|
||||
int32_t res;
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
res = connectObj(obj, 0, cb, eventMask);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return res;
|
||||
PIOS_Assert(obj_handle);
|
||||
int32_t res;
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
res = connectObj(obj_handle, 0, cb, eventMask);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1478,13 +1720,14 @@ int32_t UAVObjConnectCallback(UAVObjHandle obj, UAVObjEventCallback cb,
|
||||
* \param[in] cb The event callback
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
int32_t UAVObjDisconnectCallback(UAVObjHandle obj, UAVObjEventCallback cb)
|
||||
int32_t UAVObjDisconnectCallback(UAVObjHandle obj_handle, UAVObjEventCallback cb)
|
||||
{
|
||||
int32_t res;
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
res = disconnectObj(obj, 0, cb);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return res;
|
||||
PIOS_Assert(obj_handle);
|
||||
int32_t res;
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
res = disconnectObj(obj_handle, 0, cb);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1492,9 +1735,9 @@ int32_t UAVObjDisconnectCallback(UAVObjHandle obj, UAVObjEventCallback cb)
|
||||
* will be generated as soon as the object is updated.
|
||||
* \param[in] obj The object handle
|
||||
*/
|
||||
void UAVObjRequestUpdate(UAVObjHandle obj)
|
||||
void UAVObjRequestUpdate(UAVObjHandle obj_handle)
|
||||
{
|
||||
UAVObjRequestInstanceUpdate(obj, UAVOBJ_ALL_INSTANCES);
|
||||
UAVObjRequestInstanceUpdate(obj_handle, UAVOBJ_ALL_INSTANCES);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1503,20 +1746,21 @@ void UAVObjRequestUpdate(UAVObjHandle obj)
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] instId Object instance ID to update
|
||||
*/
|
||||
void UAVObjRequestInstanceUpdate(UAVObjHandle obj, uint16_t instId)
|
||||
void UAVObjRequestInstanceUpdate(UAVObjHandle obj_handle, uint16_t instId)
|
||||
{
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
sendEvent((ObjectList *) obj, instId, EV_UPDATE_REQ);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
PIOS_Assert(obj_handle);
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
sendEvent((struct UAVOBase *) obj_handle, instId, EV_UPDATE_REQ);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the object's data to the GCS (triggers a EV_UPDATED_MANUAL event on this object).
|
||||
* \param[in] obj The object handle
|
||||
*/
|
||||
void UAVObjUpdated(UAVObjHandle obj)
|
||||
void UAVObjUpdated(UAVObjHandle obj_handle)
|
||||
{
|
||||
UAVObjInstanceUpdated(obj, UAVOBJ_ALL_INSTANCES);
|
||||
UAVObjInstanceUpdated(obj_handle, UAVOBJ_ALL_INSTANCES);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1524,11 +1768,12 @@ void UAVObjUpdated(UAVObjHandle obj)
|
||||
* \param[in] obj The object handle
|
||||
* \param[in] instId The object instance ID
|
||||
*/
|
||||
void UAVObjInstanceUpdated(UAVObjHandle obj, uint16_t instId)
|
||||
void UAVObjInstanceUpdated(UAVObjHandle obj_handle, uint16_t instId)
|
||||
{
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
sendEvent((ObjectList *) obj, instId, EV_UPDATED_MANUAL);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
PIOS_Assert(obj_handle);
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
sendEvent((struct UAVOBase *) obj_handle, instId, EV_UPDATED_MANUAL);
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1538,133 +1783,152 @@ void UAVObjInstanceUpdated(UAVObjHandle obj, uint16_t instId)
|
||||
*/
|
||||
void UAVObjIterate(void (*iterator) (UAVObjHandle obj))
|
||||
{
|
||||
ObjectList *objEntry;
|
||||
PIOS_Assert(iterator);
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Iterate through the list and invoke iterator for each object
|
||||
LL_FOREACH(objList, objEntry) {
|
||||
(*iterator) ((UAVObjHandle) objEntry);
|
||||
}
|
||||
// Iterate through the list and invoke iterator for each object
|
||||
struct UAVOData *obj;
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
(*iterator) ((UAVObjHandle) obj);
|
||||
(*iterator) ((UAVObjHandle) &obj->metaObj);
|
||||
}
|
||||
|
||||
// Release lock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
// Release lock
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an event to all event queues registered on the object.
|
||||
* Send a triggered event to all event queues registered on the object.
|
||||
*/
|
||||
static int32_t sendEvent(ObjectList * obj, uint16_t instId,
|
||||
UAVObjEventType event)
|
||||
static int32_t sendEvent(struct UAVOBase * obj, uint16_t instId,
|
||||
UAVObjEventType triggered_event)
|
||||
{
|
||||
ObjectEventList *eventEntry;
|
||||
UAVObjEvent msg;
|
||||
/* Set up the message that will be sent to all registered listeners */
|
||||
UAVObjEvent msg = {
|
||||
.obj = (UAVObjHandle) obj,
|
||||
.event = triggered_event,
|
||||
.instId = instId,
|
||||
};
|
||||
|
||||
// Setup event
|
||||
msg.obj = (UAVObjHandle) obj;
|
||||
msg.event = event;
|
||||
msg.instId = instId;
|
||||
// Go through each object and push the event message in the queue (if event is activated for the queue)
|
||||
struct ObjectEventEntry *event;
|
||||
LL_FOREACH(obj->next_event, event) {
|
||||
if (event->eventMask == 0
|
||||
|| (event->eventMask & triggered_event) != 0) {
|
||||
// Send to queue if a valid queue is registered
|
||||
if (event->queue) {
|
||||
// will not block
|
||||
if (xQueueSend(event->queue, &msg, 0) != pdTRUE) {
|
||||
stats.lastQueueErrorID = UAVObjGetID(obj);
|
||||
++stats.eventQueueErrors;
|
||||
}
|
||||
}
|
||||
|
||||
// Go through each object and push the event message in the queue (if event is activated for the queue)
|
||||
LL_FOREACH(obj->events, eventEntry) {
|
||||
if (eventEntry->eventMask == 0
|
||||
|| (eventEntry->eventMask & event) != 0) {
|
||||
// Send to queue if a valid queue is registered
|
||||
if (eventEntry->queue != 0) {
|
||||
if (xQueueSend(eventEntry->queue, &msg, 0) != pdTRUE) // will not block
|
||||
{
|
||||
stats.lastQueueErrorID = UAVObjGetID(obj);
|
||||
++stats.eventQueueErrors;
|
||||
}
|
||||
}
|
||||
// Invoke callback (from event task) if a valid one is registered
|
||||
if (eventEntry->cb != 0) {
|
||||
if (EventCallbackDispatch(&msg, eventEntry->cb) != pdTRUE) // invoke callback from the event task, will not block
|
||||
{
|
||||
++stats.eventCallbackErrors;
|
||||
stats.lastCallbackErrorID = UAVObjGetID(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Invoke callback (from event task) if a valid one is registered
|
||||
if (event->cb) {
|
||||
// invoke callback from the event task, will not block
|
||||
if (EventCallbackDispatch(&msg, event->cb) != pdTRUE) {
|
||||
++stats.eventCallbackErrors;
|
||||
stats.lastCallbackErrorID = UAVObjGetID(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Done
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new object instance, return the instance info or NULL if failure.
|
||||
*/
|
||||
static ObjectInstList *createInstance(ObjectList * obj, uint16_t instId)
|
||||
static InstanceHandle createInstance(struct UAVOData * obj, uint16_t instId)
|
||||
{
|
||||
ObjectInstList *instEntry;
|
||||
int32_t n;
|
||||
struct UAVOMultiInst *instEntry;
|
||||
|
||||
// For single instance objects, only instance zero is allowed
|
||||
if (OLGetIsSingleInstance(obj) && instId != 0) {
|
||||
return NULL;
|
||||
}
|
||||
// Make sure that the instance ID is within limits
|
||||
if (instId >= UAVOBJ_MAX_INSTANCES) {
|
||||
return NULL;
|
||||
}
|
||||
// Check if the instance already exists
|
||||
if (getInstance(obj, instId) != NULL) {
|
||||
return NULL;
|
||||
}
|
||||
// Create any missing instances (all instance IDs must be sequential)
|
||||
for (n = obj->numInstances; n < instId; ++n) {
|
||||
if (createInstance(obj, n) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* Don't allow more than one instance for single instance objects */
|
||||
if (UAVObjIsSingleInstance(&(obj->base))) {
|
||||
PIOS_Assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (instId == 0) { /* Instance 0 ObjectInstList allocated with ObjectList element */
|
||||
instEntry = &obj->instances;
|
||||
instEntry->data = pvPortMalloc(obj->numBytes);
|
||||
if (instEntry->data == NULL)
|
||||
return NULL;
|
||||
memset(instEntry->data, 0, obj->numBytes);
|
||||
instEntry->instId = instId;
|
||||
} else {
|
||||
// Create the actual instance
|
||||
instEntry =
|
||||
(ObjectInstList *)
|
||||
pvPortMalloc(sizeof(ObjectInstList));
|
||||
if (instEntry == NULL)
|
||||
return NULL;
|
||||
instEntry->data = pvPortMalloc(obj->numBytes);
|
||||
if (instEntry->data == NULL)
|
||||
return NULL;
|
||||
memset(instEntry->data, 0, obj->numBytes);
|
||||
instEntry->instId = instId;
|
||||
LL_APPEND(obj->instances.next, instEntry);
|
||||
}
|
||||
++obj->numInstances;
|
||||
/* Don't create more than the allowed number of instances */
|
||||
if (instId >= UAVOBJ_MAX_INSTANCES) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Fire event
|
||||
UAVObjInstanceUpdated((UAVObjHandle) obj, instId);
|
||||
/* Don't allow duplicate instances */
|
||||
if (instId < UAVObjGetNumInstances(&(obj->base))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Done
|
||||
return instEntry;
|
||||
// Create any missing instances (all instance IDs must be sequential)
|
||||
for (uint16_t n = UAVObjGetNumInstances(&(obj->base)); n < instId; ++n) {
|
||||
if (createInstance(obj, n) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the actual instance */
|
||||
instEntry = (struct UAVOMultiInst *) pvPortMalloc(sizeof(struct UAVOMultiInst)+obj->instance_size);
|
||||
if (!instEntry)
|
||||
return NULL;
|
||||
memset(InstanceDataOffset(instEntry), 0, obj->instance_size);
|
||||
LL_APPEND(( (struct UAVOMulti*)obj )->instance0.next, instEntry);
|
||||
|
||||
( (struct UAVOMulti*)obj )->num_instances++;
|
||||
|
||||
// Fire event
|
||||
UAVObjInstanceUpdated((UAVObjHandle) obj, instId);
|
||||
|
||||
// Done
|
||||
return InstanceDataOffset(instEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance information or NULL if the instance does not exist
|
||||
*/
|
||||
static ObjectInstList *getInstance(ObjectList * obj, uint16_t instId)
|
||||
static InstanceHandle getInstance(struct UAVOData * obj, uint16_t instId)
|
||||
{
|
||||
ObjectInstList *instEntry;
|
||||
if (UAVObjIsMetaobject(&obj->base)) {
|
||||
/* Metadata Instance */
|
||||
|
||||
// Look for specified instance ID
|
||||
LL_FOREACH(&(obj->instances), instEntry) {
|
||||
if (instEntry->instId == instId) {
|
||||
return instEntry;
|
||||
}
|
||||
}
|
||||
// If this point is reached then instance id was not found
|
||||
return NULL;
|
||||
if (instId != 0)
|
||||
return NULL;
|
||||
|
||||
/* Augment our pointer to reflect the proper type */
|
||||
struct UAVOMeta * uavo_meta = (struct UAVOMeta *) obj;
|
||||
return (&(uavo_meta->instance0));
|
||||
|
||||
} else if (UAVObjIsSingleInstance(&(obj->base))) {
|
||||
/* Single Instance */
|
||||
|
||||
if (instId != 0)
|
||||
return NULL;
|
||||
|
||||
/* Augment our pointer to reflect the proper type */
|
||||
struct UAVOSingle * uavo_single = (struct UAVOSingle *) obj;
|
||||
return (&(uavo_single->instance0));
|
||||
} else {
|
||||
/* Multi Instance */
|
||||
/* Augment our pointer to reflect the proper type */
|
||||
struct UAVOMulti * uavo_multi = (struct UAVOMulti *) obj;
|
||||
if (instId >= uavo_multi->num_instances)
|
||||
return NULL;
|
||||
|
||||
// Look for specified instance ID
|
||||
uint16_t instance = 0;
|
||||
struct UAVOMultiInst *instEntry;
|
||||
LL_FOREACH(&(uavo_multi->instance0), instEntry) {
|
||||
if (instance++ == instId) {
|
||||
/* Found it */
|
||||
return &(instEntry->instance);
|
||||
}
|
||||
}
|
||||
/* Instance was not found */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1675,35 +1939,34 @@ 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)
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
static int32_t connectObj(UAVObjHandle obj, xQueueHandle queue,
|
||||
UAVObjEventCallback cb, uint8_t eventMask)
|
||||
static int32_t connectObj(UAVObjHandle obj_handle, xQueueHandle queue,
|
||||
UAVObjEventCallback cb, uint8_t eventMask)
|
||||
{
|
||||
ObjectEventList *eventEntry;
|
||||
ObjectList *objEntry;
|
||||
struct ObjectEventEntry *event;
|
||||
struct UAVOBase *obj;
|
||||
|
||||
// Check that the queue is not already connected, if it is simply update event mask
|
||||
objEntry = (ObjectList *) obj;
|
||||
LL_FOREACH(objEntry->events, eventEntry) {
|
||||
if (eventEntry->queue == queue && eventEntry->cb == cb) {
|
||||
// Already connected, update event mask and return
|
||||
eventEntry->eventMask = eventMask;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// Check that the queue is not already connected, if it is simply update event mask
|
||||
obj = (struct UAVOBase *) obj_handle;
|
||||
LL_FOREACH(obj->next_event, event) {
|
||||
if (event->queue == queue && event->cb == cb) {
|
||||
// Already connected, update event mask and return
|
||||
event->eventMask = eventMask;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Add queue to list
|
||||
eventEntry =
|
||||
(ObjectEventList *) pvPortMalloc(sizeof(ObjectEventList));
|
||||
if (eventEntry == NULL) {
|
||||
return -1;
|
||||
}
|
||||
eventEntry->queue = queue;
|
||||
eventEntry->cb = cb;
|
||||
eventEntry->eventMask = eventMask;
|
||||
LL_APPEND(objEntry->events, eventEntry);
|
||||
// Add queue to list
|
||||
event = (struct ObjectEventEntry *) pvPortMalloc(sizeof(struct ObjectEventEntry));
|
||||
if (event == NULL) {
|
||||
return -1;
|
||||
}
|
||||
event->queue = queue;
|
||||
event->cb = cb;
|
||||
event->eventMask = eventMask;
|
||||
LL_APPEND(obj->next_event, event);
|
||||
|
||||
// Done
|
||||
return 0;
|
||||
// Done
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1713,25 +1976,25 @@ static int32_t connectObj(UAVObjHandle obj, xQueueHandle queue,
|
||||
* \param[in] cb The event callback
|
||||
* \return 0 if success or -1 if failure
|
||||
*/
|
||||
static int32_t disconnectObj(UAVObjHandle obj, xQueueHandle queue,
|
||||
UAVObjEventCallback cb)
|
||||
static int32_t disconnectObj(UAVObjHandle obj_handle, xQueueHandle queue,
|
||||
UAVObjEventCallback cb)
|
||||
{
|
||||
ObjectEventList *eventEntry;
|
||||
ObjectList *objEntry;
|
||||
struct ObjectEventEntry *event;
|
||||
struct UAVOBase *obj;
|
||||
|
||||
// Find queue and remove it
|
||||
objEntry = (ObjectList *) obj;
|
||||
LL_FOREACH(objEntry->events, eventEntry) {
|
||||
if ((eventEntry->queue == queue
|
||||
&& eventEntry->cb == cb)) {
|
||||
LL_DELETE(objEntry->events, eventEntry);
|
||||
vPortFree(eventEntry);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// Find queue and remove it
|
||||
obj = (struct UAVOBase *) obj_handle;
|
||||
LL_FOREACH(obj->next_event, event) {
|
||||
if ((event->queue == queue
|
||||
&& event->cb == cb)) {
|
||||
LL_DELETE(obj->next_event, event);
|
||||
vPortFree(event);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If this point is reached the queue was not found
|
||||
return -1;
|
||||
// If this point is reached the queue was not found
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(PIOS_INCLUDE_SDCARD)
|
||||
@ -1740,16 +2003,16 @@ static int32_t disconnectObj(UAVObjHandle obj, xQueueHandle queue,
|
||||
*/
|
||||
static void customSPrintf(uint8_t * buffer, uint8_t * format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsprintf((char *)buffer, (char *)format, args);
|
||||
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(ObjectList * obj, uint8_t * filename)
|
||||
static void objectFilename(UAVObjHandle obj_handle, uint8_t * filename)
|
||||
{
|
||||
customSPrintf(filename, (uint8_t *) "%X.obj", obj->id);
|
||||
customSPrintf(filename, (uint8_t *) "%X.obj", UAVObjGetID(obj_handle));
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_SDCARD */
|
||||
|
@ -54,7 +54,7 @@ int32_t $(NAME)Initialize(void)
|
||||
return -2;
|
||||
|
||||
// Register object with the object manager
|
||||
handle = UAVObjRegister($(NAMEUC)_OBJID, $(NAMEUC)_NAME, $(NAMEUC)_METANAME, 0,
|
||||
handle = UAVObjRegister($(NAMEUC)_OBJID,
|
||||
$(NAMEUC)_ISSINGLEINST, $(NAMEUC)_ISSETTINGS, $(NAMEUC)_NUMBYTES, &$(NAME)SetDefaults);
|
||||
|
||||
// Done
|
||||
|
Loading…
x
Reference in New Issue
Block a user