mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-30 15:52:12 +01:00
Merged in mindnever/librepilot/LP-523_implement_uavobject_DataOverrideDefaults_method (pull request #430)
LP-523 Implement method for overriding uavobject defaults. Approved-by: Philippe Renon <philippe_renon@yahoo.fr> Approved-by: Vladimir Zidar <mr_w@mindnever.org> Approved-by: Lalanne Laurent <f5soh@free.fr> Approved-by: Brian Webb <webbbn@gmail.com> Approved-by: Alessio Morale <alessiomorale@gmail.com>
This commit is contained in:
commit
0448d627af
@ -71,6 +71,8 @@ typedef struct {
|
||||
*/
|
||||
typedef $(NAME)DataPacked __attribute__((aligned(4))) $(NAME)Data;
|
||||
|
||||
void $(NAME)DataOverrideDefaults($(NAME)Data * data);
|
||||
|
||||
/* Typesafe Object access functions */
|
||||
static inline int32_t $(NAME)Get($(NAME)Data * dataOut) {
|
||||
return UAVObjGetData($(NAME)Handle(), dataOut);
|
||||
@ -94,7 +96,7 @@ static inline int32_t $(NAME)ConnectFastCallback(UAVObjEventCallback cb) {
|
||||
return UAVObjConnectCallback($(NAME)Handle(), cb, EV_MASK_ALL_UPDATES, true);
|
||||
}
|
||||
static inline uint16_t $(NAME)CreateInstance() {
|
||||
return UAVObjCreateInstance($(NAME)Handle(), &$(NAME)SetDefaults);
|
||||
return UAVObjCreateInstance($(NAME)Handle());
|
||||
}
|
||||
static inline void $(NAME)RequestUpdate() {
|
||||
UAVObjRequestUpdate($(NAME)Handle());
|
||||
|
@ -182,16 +182,22 @@ typedef struct {
|
||||
uint32_t lastQueueErrorID;
|
||||
} UAVObjStats;
|
||||
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
UAVObjInitializeCallback init_callback;
|
||||
uint16_t instance_size;
|
||||
} __attribute__((packed, aligned(4))) UAVObjType;
|
||||
|
||||
int32_t UAVObjInitialize();
|
||||
void UAVObjGetStats(UAVObjStats *statsOut);
|
||||
void UAVObjClearStats();
|
||||
UAVObjHandle UAVObjRegister(uint32_t id, bool isSingleInstance, bool isSettings, bool isPriority, uint32_t num_bytes, UAVObjInitializeCallback initCb);
|
||||
UAVObjHandle UAVObjRegister(const UAVObjType *type, bool isSingleInstance, bool isSettings, bool isPriority);
|
||||
UAVObjHandle UAVObjGetByID(uint32_t id);
|
||||
uint32_t UAVObjGetID(UAVObjHandle obj);
|
||||
uint32_t UAVObjGetNumBytes(UAVObjHandle obj);
|
||||
uint16_t UAVObjGetNumInstances(UAVObjHandle obj);
|
||||
UAVObjHandle UAVObjGetLinkedObj(UAVObjHandle obj);
|
||||
uint16_t UAVObjCreateInstance(UAVObjHandle obj_handle, UAVObjInitializeCallback initCb);
|
||||
uint16_t UAVObjCreateInstance(UAVObjHandle obj_handle);
|
||||
bool UAVObjIsSingleInstance(UAVObjHandle obj);
|
||||
bool UAVObjIsMetaobject(UAVObjHandle obj);
|
||||
bool UAVObjIsSettings(UAVObjHandle obj);
|
||||
@ -208,10 +214,12 @@ int32_t UAVObjDeleteSettings();
|
||||
int32_t UAVObjSaveMetaobjects();
|
||||
int32_t UAVObjLoadMetaobjects();
|
||||
int32_t UAVObjDeleteMetaobjects();
|
||||
int32_t UAVObjSetDefaults(UAVObjHandle obj_handle);
|
||||
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 UAVObjSetInstanceDefaults(UAVObjHandle obj_handle, uint16_t instId);
|
||||
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);
|
||||
|
@ -112,14 +112,13 @@ struct UAVOMeta {
|
||||
|
||||
/* Shared data structure for all data-carrying UAVObjects (UAVOSingle and UAVOMulti) */
|
||||
struct UAVOData {
|
||||
struct UAVOBase base;
|
||||
uint32_t id;
|
||||
struct UAVOBase base;
|
||||
const UAVObjType *type; /* this contains id, instance_size and data initializer */
|
||||
/*
|
||||
* Embed the Meta object as another complete UAVO
|
||||
* inside the payload for this UAVO.
|
||||
*/
|
||||
struct UAVOMeta metaObj;
|
||||
uint16_t instance_size;
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
/* Augmented type for Single Instance Data UAVO */
|
||||
|
@ -63,14 +63,24 @@ int32_t $(NAME)Initialize(void)
|
||||
return -2;
|
||||
}
|
||||
|
||||
static const UAVObjType objType = {
|
||||
.id = $(NAMEUC)_OBJID,
|
||||
.instance_size = $(NAMEUC)_NUMBYTES,
|
||||
.init_callback = &$(NAME)SetDefaults,
|
||||
};
|
||||
|
||||
// Register object with the object manager
|
||||
handle = UAVObjRegister($(NAMEUC)_OBJID,
|
||||
$(NAMEUC)_ISSINGLEINST, $(NAMEUC)_ISSETTINGS, $(NAMEUC)_ISPRIORITY, $(NAMEUC)_NUMBYTES, &$(NAME)SetDefaults);
|
||||
handle = UAVObjRegister(&objType,
|
||||
$(NAMEUC)_ISSINGLEINST, $(NAMEUC)_ISSETTINGS, $(NAMEUC)_ISPRIORITY);
|
||||
|
||||
// Done
|
||||
return handle ? 0 : -1;
|
||||
}
|
||||
|
||||
static inline void DataOverrideDefaults(__attribute__((unused)) $(NAME)Data * data) {}
|
||||
|
||||
void $(NAME)DataOverrideDefaults($(NAME)Data * data) __attribute__((weak, alias("DataOverrideDefaults")));
|
||||
|
||||
/**
|
||||
* Initialize object fields and metadata with the default values.
|
||||
* If a default value is not specified the object fields
|
||||
@ -84,6 +94,7 @@ void $(NAME)SetDefaults(UAVObjHandle obj, uint16_t instId)
|
||||
UAVObjGetInstanceData(obj, instId, &data);
|
||||
memset(&data, 0, sizeof($(NAME)Data));
|
||||
$(INITFIELDS)
|
||||
$(NAME)DataOverrideDefaults(&data);
|
||||
UAVObjSetInstanceData(obj, instId, &data);
|
||||
|
||||
// Initialize object metadata to their default values
|
||||
|
@ -225,7 +225,7 @@ static struct UAVOData *UAVObjAllocSingle(uint32_t num_bytes)
|
||||
uint32_t object_size = sizeof(struct UAVOSingle) + num_bytes;
|
||||
|
||||
/* Allocate the object from the heap */
|
||||
struct UAVOSingle *uavo_single = (struct UAVOSingle *)pios_fastheapmalloc(object_size);
|
||||
struct UAVOSingle *uavo_single = (struct UAVOSingle *)pios_malloc(object_size);
|
||||
|
||||
if (!uavo_single) {
|
||||
return NULL;
|
||||
@ -250,7 +250,7 @@ static struct UAVOData *UAVObjAllocMulti(uint32_t num_bytes)
|
||||
uint32_t object_size = sizeof(struct UAVOMulti) + num_bytes;
|
||||
|
||||
/* Allocate the object from the heap */
|
||||
struct UAVOMulti *uavo_multi = (struct UAVOMulti *)pios_fastheapmalloc(object_size);
|
||||
struct UAVOMulti *uavo_multi = (struct UAVOMulti *)pios_malloc(object_size);
|
||||
|
||||
if (!uavo_multi) {
|
||||
return NULL;
|
||||
@ -278,33 +278,30 @@ static struct UAVOData *UAVObjAllocMulti(uint32_t num_bytes)
|
||||
|
||||
/**
|
||||
* Register and new object in the object manager.
|
||||
* \param[in] id Unique object ID
|
||||
* \param[in] pointer to UAVObjType structure that holds Unique object ID, instance size, initialization function
|
||||
* \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)
|
||||
* \param[in] initCb Default field and metadata initialization function
|
||||
* \param[in] isPriority
|
||||
* \return Object handle, or NULL if failure.
|
||||
* \return
|
||||
*/
|
||||
UAVObjHandle UAVObjRegister(uint32_t id,
|
||||
bool isSingleInstance, bool isSettings, bool isPriority,
|
||||
uint32_t num_bytes,
|
||||
UAVObjInitializeCallback initCb)
|
||||
UAVObjHandle UAVObjRegister(const UAVObjType *type,
|
||||
bool isSingleInstance, bool isSettings, bool isPriority)
|
||||
{
|
||||
struct UAVOData *uavo_data = NULL;
|
||||
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
/* Don't allow duplicate registrations */
|
||||
if (UAVObjGetByID(id)) {
|
||||
if (UAVObjGetByID(type->id)) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
/* Map the various flags to one of the UAVO types we understand */
|
||||
if (isSingleInstance) {
|
||||
uavo_data = UAVObjAllocSingle(num_bytes);
|
||||
uavo_data = UAVObjAllocSingle(type->instance_size);
|
||||
} else {
|
||||
uavo_data = UAVObjAllocMulti(num_bytes);
|
||||
uavo_data = UAVObjAllocMulti(type->instance_size);
|
||||
}
|
||||
|
||||
if (!uavo_data) {
|
||||
@ -312,8 +309,7 @@ UAVObjHandle UAVObjRegister(uint32_t id,
|
||||
}
|
||||
|
||||
/* Fill in the details about this UAVO */
|
||||
uavo_data->id = id;
|
||||
uavo_data->instance_size = num_bytes;
|
||||
uavo_data->type = type;
|
||||
if (isSettings) {
|
||||
uavo_data->base.flags.isSettings = true;
|
||||
// settings defaults to being sent with priority
|
||||
@ -325,8 +321,8 @@ UAVObjHandle UAVObjRegister(uint32_t id,
|
||||
UAVObjInitMetaData(&uavo_data->metaObj);
|
||||
|
||||
/* Initialize object fields and metadata to default values */
|
||||
if (initCb) {
|
||||
initCb((UAVObjHandle)uavo_data, 0);
|
||||
if (type->init_callback) {
|
||||
type->init_callback((UAVObjHandle)uavo_data, 0);
|
||||
}
|
||||
|
||||
/* Always try to load the meta object from flash */
|
||||
@ -360,11 +356,11 @@ UAVObjHandle UAVObjGetByID(uint32_t id)
|
||||
|
||||
// Look for object
|
||||
UAVO_LIST_ITERATE(tmp_obj)
|
||||
if (tmp_obj->id == id) {
|
||||
if (tmp_obj->type->id == id) {
|
||||
found_obj = (UAVObjHandle *)tmp_obj;
|
||||
goto unlock_exit;
|
||||
}
|
||||
if (MetaObjectId(tmp_obj->id) == id) {
|
||||
if (MetaObjectId(tmp_obj->type->id) == id) {
|
||||
found_obj = (UAVObjHandle *)&(tmp_obj->metaObj);
|
||||
goto unlock_exit;
|
||||
}
|
||||
@ -391,12 +387,12 @@ uint32_t UAVObjGetID(UAVObjHandle 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);
|
||||
return MetaObjectId(uavo_data->type->id);
|
||||
} else {
|
||||
/* We have a data object, augment our pointer */
|
||||
struct UAVOData *uavo_data = (struct UAVOData *)uavo_base;
|
||||
|
||||
return uavo_data->id;
|
||||
return uavo_data->type->id;
|
||||
}
|
||||
}
|
||||
|
||||
@ -420,7 +416,7 @@ uint32_t UAVObjGetNumBytes(UAVObjHandle obj)
|
||||
/* We have a data object, augment our pointer */
|
||||
struct UAVOData *uavo = (struct UAVOData *)uavo_base;
|
||||
|
||||
instance_size = uavo->instance_size;
|
||||
instance_size = uavo->type->instance_size;
|
||||
}
|
||||
|
||||
return instance_size;
|
||||
@ -478,8 +474,7 @@ uint16_t UAVObjGetNumInstances(UAVObjHandle obj_handle)
|
||||
* \param[in] obj The object handle
|
||||
* \return The instance ID or 0 if an error
|
||||
*/
|
||||
uint16_t UAVObjCreateInstance(UAVObjHandle obj_handle,
|
||||
UAVObjInitializeCallback initCb)
|
||||
uint16_t UAVObjCreateInstance(UAVObjHandle obj_handle)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
@ -501,8 +496,8 @@ uint16_t UAVObjCreateInstance(UAVObjHandle obj_handle,
|
||||
}
|
||||
|
||||
// Initialize instance data
|
||||
if (initCb) {
|
||||
initCb(obj_handle, instId);
|
||||
if (((struct UAVOData *)obj_handle)->type->init_callback) {
|
||||
((struct UAVOData *)obj_handle)->type->init_callback(obj_handle, instId);
|
||||
}
|
||||
|
||||
unlock_exit:
|
||||
@ -550,7 +545,7 @@ int32_t UAVObjUnpack(UAVObjHandle obj_handle, uint16_t instId, const uint8_t *da
|
||||
}
|
||||
}
|
||||
// Set the data
|
||||
memcpy(InstanceData(instEntry), dataIn, obj->instance_size);
|
||||
memcpy(InstanceData(instEntry), dataIn, obj->type->instance_size);
|
||||
}
|
||||
|
||||
// Fire event
|
||||
@ -596,7 +591,7 @@ int32_t UAVObjPack(UAVObjHandle obj_handle, uint16_t instId, uint8_t *dataOut)
|
||||
goto unlock_exit;
|
||||
}
|
||||
// Pack data
|
||||
memcpy(dataOut, InstanceData(instEntry), obj->instance_size);
|
||||
memcpy(dataOut, InstanceData(instEntry), obj->type->instance_size);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
@ -638,7 +633,7 @@ uint8_t UAVObjUpdateCRC(UAVObjHandle obj_handle, uint16_t instId, uint8_t crc)
|
||||
goto unlock_exit;
|
||||
}
|
||||
// Update crc
|
||||
crc = PIOS_CRC_updateCRC(crc, (uint8_t *)InstanceData(instEntry), (int32_t)obj->instance_size);
|
||||
crc = PIOS_CRC_updateCRC(crc, (uint8_t *)InstanceData(instEntry), (int32_t)obj->type->instance_size);
|
||||
}
|
||||
|
||||
unlock_exit:
|
||||
@ -677,7 +672,7 @@ void UAVObjInstanceWriteToLog(UAVObjHandle obj_handle, uint16_t instId)
|
||||
goto unlock_exit;
|
||||
}
|
||||
// Pack data
|
||||
PIOS_DEBUGLOG_UAVObject(UAVObjGetID(obj_handle), instId, obj->instance_size, (uint8_t *)InstanceData(instEntry));
|
||||
PIOS_DEBUGLOG_UAVObject(UAVObjGetID(obj_handle), instId, obj->type->instance_size, (uint8_t *)InstanceData(instEntry));
|
||||
}
|
||||
|
||||
unlock_exit:
|
||||
@ -857,6 +852,11 @@ xSemaphoreGiveRecursive(mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int32_t UAVObjSetDefaults(UAVObjHandle obj_handle)
|
||||
{
|
||||
return UAVObjSetInstanceDefaults(obj_handle, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the object data
|
||||
* \param[in] obj The object handle
|
||||
@ -901,6 +901,42 @@ int32_t UAVObjGetDataField(UAVObjHandle obj_handle, void *dataOut, uint32_t offs
|
||||
return UAVObjGetInstanceDataField(obj_handle, 0, dataOut, offset, size);
|
||||
}
|
||||
|
||||
int32_t UAVObjSetInstanceDefaults(UAVObjHandle obj_handle, uint16_t instId)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
if (IsMetaobject(obj_handle)) {
|
||||
if (instId != 0) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
// How do we set meta data defaults?
|
||||
// MetaDataPtr((struct UAVOMeta *)obj_handle), MetaNumBytes;
|
||||
} else {
|
||||
// Check access level
|
||||
if (UAVObjReadOnly(obj_handle)) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
// Set default data
|
||||
if (((struct UAVOData *)obj_handle)->type->init_callback) {
|
||||
((struct UAVOData *)obj_handle)->type->init_callback(obj_handle, instId);
|
||||
}
|
||||
}
|
||||
|
||||
// Fire event
|
||||
sendEvent((struct UAVOBase *)obj_handle, instId, EV_UPDATED);
|
||||
rc = 0;
|
||||
|
||||
unlock_exit:
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data of a specific object instance
|
||||
* \param[in] obj The object handle
|
||||
@ -940,7 +976,7 @@ int32_t UAVObjSetInstanceData(UAVObjHandle obj_handle, uint16_t instId,
|
||||
goto unlock_exit;
|
||||
}
|
||||
// Set data
|
||||
memcpy(InstanceData(instEntry), dataIn, obj->instance_size);
|
||||
memcpy(InstanceData(instEntry), dataIn, obj->type->instance_size);
|
||||
}
|
||||
|
||||
// Fire event
|
||||
@ -1000,7 +1036,7 @@ int32_t UAVObjSetInstanceDataField(UAVObjHandle obj_handle, uint16_t instId, con
|
||||
}
|
||||
|
||||
// Check for overrun
|
||||
if ((size + offset) > obj->instance_size) {
|
||||
if ((size + offset) > obj->type->instance_size) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
@ -1055,7 +1091,7 @@ int32_t UAVObjGetInstanceData(UAVObjHandle obj_handle, uint16_t instId,
|
||||
goto unlock_exit;
|
||||
}
|
||||
// Set data
|
||||
memcpy(dataOut, InstanceData(instEntry), obj->instance_size);
|
||||
memcpy(dataOut, InstanceData(instEntry), obj->type->instance_size);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
@ -1108,7 +1144,7 @@ int32_t UAVObjGetInstanceDataField(UAVObjHandle obj_handle, uint16_t instId, voi
|
||||
}
|
||||
|
||||
// Check for overrun
|
||||
if ((size + offset) > obj->instance_size) {
|
||||
if ((size + offset) > obj->type->instance_size) {
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
@ -1597,8 +1633,8 @@ static InstanceHandle createInstance(struct UAVOData *obj, uint16_t instId)
|
||||
}
|
||||
|
||||
/* Create the actual instance */
|
||||
uint32_t size = sizeof(struct UAVOMultiInst) + obj->instance_size;
|
||||
instEntry = (struct UAVOMultiInst *)pios_fastheapmalloc(size);
|
||||
uint32_t size = sizeof(struct UAVOMultiInst) + obj->type->instance_size;
|
||||
instEntry = (struct UAVOMultiInst *)pios_malloc(size);
|
||||
if (!instEntry) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -121,6 +121,8 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, uint16_t instId)
|
||||
int32_t UAVObjDelete(UAVObjHandle obj_handle, uint16_t instId)
|
||||
{
|
||||
PIOS_Assert(obj_handle);
|
||||
PIOS_FLASHFS_ObjDelete(pios_uavo_settings_fs_id, UAVObjGetID(obj_handle), instId);
|
||||
if (PIOS_FLASHFS_ObjDelete(pios_uavo_settings_fs_id, UAVObjGetID(obj_handle), instId) == 0) {
|
||||
UAVObjSetInstanceDefaults(obj_handle, instId);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -212,6 +212,8 @@ void UAVObjectBrowserWidget::eraseObject()
|
||||
UAVObject *obj = objItem->object();
|
||||
Q_ASSERT(obj);
|
||||
updateObjectPersistance(ObjectPersistence::OPERATION_DELETE, obj);
|
||||
// Retrieve object so that correct default value is displayed
|
||||
requestUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user