Skip to content

Commit 0448d62

Browse files
mindneverf5soh
authored andcommitted
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>
2 parents 4f9c89e + 9f12a27 commit 0448d62

7 files changed

Lines changed: 104 additions & 44 deletions

File tree

flight/uavobjects/inc/uavobject.h.template

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ typedef struct {
7171
*/
7272
typedef $(NAME)DataPacked __attribute__((aligned(4))) $(NAME)Data;
7373

74+
void $(NAME)DataOverrideDefaults($(NAME)Data * data);
75+
7476
/* Typesafe Object access functions */
7577
static inline int32_t $(NAME)Get($(NAME)Data * dataOut) {
7678
return UAVObjGetData($(NAME)Handle(), dataOut);
@@ -94,7 +96,7 @@ static inline int32_t $(NAME)ConnectFastCallback(UAVObjEventCallback cb) {
9496
return UAVObjConnectCallback($(NAME)Handle(), cb, EV_MASK_ALL_UPDATES, true);
9597
}
9698
static inline uint16_t $(NAME)CreateInstance() {
97-
return UAVObjCreateInstance($(NAME)Handle(), &$(NAME)SetDefaults);
99+
return UAVObjCreateInstance($(NAME)Handle());
98100
}
99101
static inline void $(NAME)RequestUpdate() {
100102
UAVObjRequestUpdate($(NAME)Handle());

flight/uavobjects/inc/uavobjectmanager.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,16 +182,22 @@ typedef struct {
182182
uint32_t lastQueueErrorID;
183183
} UAVObjStats;
184184

185+
typedef struct {
186+
uint32_t id;
187+
UAVObjInitializeCallback init_callback;
188+
uint16_t instance_size;
189+
} __attribute__((packed, aligned(4))) UAVObjType;
190+
185191
int32_t UAVObjInitialize();
186192
void UAVObjGetStats(UAVObjStats *statsOut);
187193
void UAVObjClearStats();
188-
UAVObjHandle UAVObjRegister(uint32_t id, bool isSingleInstance, bool isSettings, bool isPriority, uint32_t num_bytes, UAVObjInitializeCallback initCb);
194+
UAVObjHandle UAVObjRegister(const UAVObjType *type, bool isSingleInstance, bool isSettings, bool isPriority);
189195
UAVObjHandle UAVObjGetByID(uint32_t id);
190196
uint32_t UAVObjGetID(UAVObjHandle obj);
191197
uint32_t UAVObjGetNumBytes(UAVObjHandle obj);
192198
uint16_t UAVObjGetNumInstances(UAVObjHandle obj);
193199
UAVObjHandle UAVObjGetLinkedObj(UAVObjHandle obj);
194-
uint16_t UAVObjCreateInstance(UAVObjHandle obj_handle, UAVObjInitializeCallback initCb);
200+
uint16_t UAVObjCreateInstance(UAVObjHandle obj_handle);
195201
bool UAVObjIsSingleInstance(UAVObjHandle obj);
196202
bool UAVObjIsMetaobject(UAVObjHandle obj);
197203
bool UAVObjIsSettings(UAVObjHandle obj);
@@ -208,10 +214,12 @@ int32_t UAVObjDeleteSettings();
208214
int32_t UAVObjSaveMetaobjects();
209215
int32_t UAVObjLoadMetaobjects();
210216
int32_t UAVObjDeleteMetaobjects();
217+
int32_t UAVObjSetDefaults(UAVObjHandle obj_handle);
211218
int32_t UAVObjSetData(UAVObjHandle obj_handle, const void *dataIn);
212219
int32_t UAVObjSetDataField(UAVObjHandle obj_handle, const void *dataIn, uint32_t offset, uint32_t size);
213220
int32_t UAVObjGetData(UAVObjHandle obj_handle, void *dataOut);
214221
int32_t UAVObjGetDataField(UAVObjHandle obj_handle, void *dataOut, uint32_t offset, uint32_t size);
222+
int32_t UAVObjSetInstanceDefaults(UAVObjHandle obj_handle, uint16_t instId);
215223
int32_t UAVObjSetInstanceData(UAVObjHandle obj_handle, uint16_t instId, const void *dataIn);
216224
int32_t UAVObjSetInstanceDataField(UAVObjHandle obj_handle, uint16_t instId, const void *dataIn, uint32_t offset, uint32_t size);
217225
int32_t UAVObjGetInstanceData(UAVObjHandle obj_handle, uint16_t instId, void *dataOut);

flight/uavobjects/inc/uavobjectprivate.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,13 @@ struct UAVOMeta {
112112

113113
/* Shared data structure for all data-carrying UAVObjects (UAVOSingle and UAVOMulti) */
114114
struct UAVOData {
115-
struct UAVOBase base;
116-
uint32_t id;
115+
struct UAVOBase base;
116+
const UAVObjType *type; /* this contains id, instance_size and data initializer */
117117
/*
118118
* Embed the Meta object as another complete UAVO
119119
* inside the payload for this UAVO.
120120
*/
121121
struct UAVOMeta metaObj;
122-
uint16_t instance_size;
123122
} __attribute__((packed, aligned(4)));
124123

125124
/* Augmented type for Single Instance Data UAVO */

flight/uavobjects/uavobject.c.template

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,24 @@ int32_t $(NAME)Initialize(void)
6363
return -2;
6464
}
6565

66+
static const UAVObjType objType = {
67+
.id = $(NAMEUC)_OBJID,
68+
.instance_size = $(NAMEUC)_NUMBYTES,
69+
.init_callback = &$(NAME)SetDefaults,
70+
};
71+
6672
// Register object with the object manager
67-
handle = UAVObjRegister($(NAMEUC)_OBJID,
68-
$(NAMEUC)_ISSINGLEINST, $(NAMEUC)_ISSETTINGS, $(NAMEUC)_ISPRIORITY, $(NAMEUC)_NUMBYTES, &$(NAME)SetDefaults);
73+
handle = UAVObjRegister(&objType,
74+
$(NAMEUC)_ISSINGLEINST, $(NAMEUC)_ISSETTINGS, $(NAMEUC)_ISPRIORITY);
6975

7076
// Done
7177
return handle ? 0 : -1;
7278
}
7379

80+
static inline void DataOverrideDefaults(__attribute__((unused)) $(NAME)Data * data) {}
81+
82+
void $(NAME)DataOverrideDefaults($(NAME)Data * data) __attribute__((weak, alias("DataOverrideDefaults")));
83+
7484
/**
7585
* Initialize object fields and metadata with the default values.
7686
* If a default value is not specified the object fields
@@ -84,6 +94,7 @@ void $(NAME)SetDefaults(UAVObjHandle obj, uint16_t instId)
8494
UAVObjGetInstanceData(obj, instId, &data);
8595
memset(&data, 0, sizeof($(NAME)Data));
8696
$(INITFIELDS)
97+
$(NAME)DataOverrideDefaults(&data);
8798
UAVObjSetInstanceData(obj, instId, &data);
8899

89100
// Initialize object metadata to their default values

flight/uavobjects/uavobjectmanager.c

Lines changed: 71 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ static struct UAVOData *UAVObjAllocSingle(uint32_t num_bytes)
225225
uint32_t object_size = sizeof(struct UAVOSingle) + num_bytes;
226226

227227
/* Allocate the object from the heap */
228-
struct UAVOSingle *uavo_single = (struct UAVOSingle *)pios_fastheapmalloc(object_size);
228+
struct UAVOSingle *uavo_single = (struct UAVOSingle *)pios_malloc(object_size);
229229

230230
if (!uavo_single) {
231231
return NULL;
@@ -250,7 +250,7 @@ static struct UAVOData *UAVObjAllocMulti(uint32_t num_bytes)
250250
uint32_t object_size = sizeof(struct UAVOMulti) + num_bytes;
251251

252252
/* Allocate the object from the heap */
253-
struct UAVOMulti *uavo_multi = (struct UAVOMulti *)pios_fastheapmalloc(object_size);
253+
struct UAVOMulti *uavo_multi = (struct UAVOMulti *)pios_malloc(object_size);
254254

255255
if (!uavo_multi) {
256256
return NULL;
@@ -278,42 +278,38 @@ static struct UAVOData *UAVObjAllocMulti(uint32_t num_bytes)
278278

279279
/**
280280
* Register and new object in the object manager.
281-
* \param[in] id Unique object ID
281+
* \param[in] pointer to UAVObjType structure that holds Unique object ID, instance size, initialization function
282282
* \param[in] isSingleInstance Is this a single instance or multi-instance object
283283
* \param[in] isSettings Is this a settings object
284-
* \param[in] numBytes Number of bytes of object data (for one instance)
285-
* \param[in] initCb Default field and metadata initialization function
284+
* \param[in] isPriority
286285
* \return Object handle, or NULL if failure.
287286
* \return
288287
*/
289-
UAVObjHandle UAVObjRegister(uint32_t id,
290-
bool isSingleInstance, bool isSettings, bool isPriority,
291-
uint32_t num_bytes,
292-
UAVObjInitializeCallback initCb)
288+
UAVObjHandle UAVObjRegister(const UAVObjType *type,
289+
bool isSingleInstance, bool isSettings, bool isPriority)
293290
{
294291
struct UAVOData *uavo_data = NULL;
295292

296293
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
297294

298295
/* Don't allow duplicate registrations */
299-
if (UAVObjGetByID(id)) {
296+
if (UAVObjGetByID(type->id)) {
300297
goto unlock_exit;
301298
}
302299

303300
/* Map the various flags to one of the UAVO types we understand */
304301
if (isSingleInstance) {
305-
uavo_data = UAVObjAllocSingle(num_bytes);
302+
uavo_data = UAVObjAllocSingle(type->instance_size);
306303
} else {
307-
uavo_data = UAVObjAllocMulti(num_bytes);
304+
uavo_data = UAVObjAllocMulti(type->instance_size);
308305
}
309306

310307
if (!uavo_data) {
311308
goto unlock_exit;
312309
}
313310

314311
/* Fill in the details about this UAVO */
315-
uavo_data->id = id;
316-
uavo_data->instance_size = num_bytes;
312+
uavo_data->type = type;
317313
if (isSettings) {
318314
uavo_data->base.flags.isSettings = true;
319315
// settings defaults to being sent with priority
@@ -325,8 +321,8 @@ UAVObjHandle UAVObjRegister(uint32_t id,
325321
UAVObjInitMetaData(&uavo_data->metaObj);
326322

327323
/* Initialize object fields and metadata to default values */
328-
if (initCb) {
329-
initCb((UAVObjHandle)uavo_data, 0);
324+
if (type->init_callback) {
325+
type->init_callback((UAVObjHandle)uavo_data, 0);
330326
}
331327

332328
/* Always try to load the meta object from flash */
@@ -360,11 +356,11 @@ UAVObjHandle UAVObjGetByID(uint32_t id)
360356

361357
// Look for object
362358
UAVO_LIST_ITERATE(tmp_obj)
363-
if (tmp_obj->id == id) {
359+
if (tmp_obj->type->id == id) {
364360
found_obj = (UAVObjHandle *)tmp_obj;
365361
goto unlock_exit;
366362
}
367-
if (MetaObjectId(tmp_obj->id) == id) {
363+
if (MetaObjectId(tmp_obj->type->id) == id) {
368364
found_obj = (UAVObjHandle *)&(tmp_obj->metaObj);
369365
goto unlock_exit;
370366
}
@@ -391,12 +387,12 @@ uint32_t UAVObjGetID(UAVObjHandle obj_handle)
391387
/* We have a meta object, find our containing UAVO */
392388
struct UAVOData *uavo_data = container_of((struct UAVOMeta *)uavo_base, struct UAVOData, metaObj);
393389

394-
return MetaObjectId(uavo_data->id);
390+
return MetaObjectId(uavo_data->type->id);
395391
} else {
396392
/* We have a data object, augment our pointer */
397393
struct UAVOData *uavo_data = (struct UAVOData *)uavo_base;
398394

399-
return uavo_data->id;
395+
return uavo_data->type->id;
400396
}
401397
}
402398

@@ -420,7 +416,7 @@ uint32_t UAVObjGetNumBytes(UAVObjHandle obj)
420416
/* We have a data object, augment our pointer */
421417
struct UAVOData *uavo = (struct UAVOData *)uavo_base;
422418

423-
instance_size = uavo->instance_size;
419+
instance_size = uavo->type->instance_size;
424420
}
425421

426422
return instance_size;
@@ -478,8 +474,7 @@ uint16_t UAVObjGetNumInstances(UAVObjHandle obj_handle)
478474
* \param[in] obj The object handle
479475
* \return The instance ID or 0 if an error
480476
*/
481-
uint16_t UAVObjCreateInstance(UAVObjHandle obj_handle,
482-
UAVObjInitializeCallback initCb)
477+
uint16_t UAVObjCreateInstance(UAVObjHandle obj_handle)
483478
{
484479
PIOS_Assert(obj_handle);
485480

@@ -501,8 +496,8 @@ uint16_t UAVObjCreateInstance(UAVObjHandle obj_handle,
501496
}
502497

503498
// Initialize instance data
504-
if (initCb) {
505-
initCb(obj_handle, instId);
499+
if (((struct UAVOData *)obj_handle)->type->init_callback) {
500+
((struct UAVOData *)obj_handle)->type->init_callback(obj_handle, instId);
506501
}
507502

508503
unlock_exit:
@@ -550,7 +545,7 @@ int32_t UAVObjUnpack(UAVObjHandle obj_handle, uint16_t instId, const uint8_t *da
550545
}
551546
}
552547
// Set the data
553-
memcpy(InstanceData(instEntry), dataIn, obj->instance_size);
548+
memcpy(InstanceData(instEntry), dataIn, obj->type->instance_size);
554549
}
555550

556551
// Fire event
@@ -596,7 +591,7 @@ int32_t UAVObjPack(UAVObjHandle obj_handle, uint16_t instId, uint8_t *dataOut)
596591
goto unlock_exit;
597592
}
598593
// Pack data
599-
memcpy(dataOut, InstanceData(instEntry), obj->instance_size);
594+
memcpy(dataOut, InstanceData(instEntry), obj->type->instance_size);
600595
}
601596

602597
rc = 0;
@@ -638,7 +633,7 @@ uint8_t UAVObjUpdateCRC(UAVObjHandle obj_handle, uint16_t instId, uint8_t crc)
638633
goto unlock_exit;
639634
}
640635
// Update crc
641-
crc = PIOS_CRC_updateCRC(crc, (uint8_t *)InstanceData(instEntry), (int32_t)obj->instance_size);
636+
crc = PIOS_CRC_updateCRC(crc, (uint8_t *)InstanceData(instEntry), (int32_t)obj->type->instance_size);
642637
}
643638

644639
unlock_exit:
@@ -677,7 +672,7 @@ void UAVObjInstanceWriteToLog(UAVObjHandle obj_handle, uint16_t instId)
677672
goto unlock_exit;
678673
}
679674
// Pack data
680-
PIOS_DEBUGLOG_UAVObject(UAVObjGetID(obj_handle), instId, obj->instance_size, (uint8_t *)InstanceData(instEntry));
675+
PIOS_DEBUGLOG_UAVObject(UAVObjGetID(obj_handle), instId, obj->type->instance_size, (uint8_t *)InstanceData(instEntry));
681676
}
682677

683678
unlock_exit:
@@ -857,6 +852,11 @@ xSemaphoreGiveRecursive(mutex);
857852
return rc;
858853
}
859854

855+
int32_t UAVObjSetDefaults(UAVObjHandle obj_handle)
856+
{
857+
return UAVObjSetInstanceDefaults(obj_handle, 0);
858+
}
859+
860860
/**
861861
* Set the object data
862862
* \param[in] obj The object handle
@@ -901,6 +901,42 @@ int32_t UAVObjGetDataField(UAVObjHandle obj_handle, void *dataOut, uint32_t offs
901901
return UAVObjGetInstanceDataField(obj_handle, 0, dataOut, offset, size);
902902
}
903903

904+
int32_t UAVObjSetInstanceDefaults(UAVObjHandle obj_handle, uint16_t instId)
905+
{
906+
PIOS_Assert(obj_handle);
907+
908+
// Lock
909+
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
910+
911+
int32_t rc = -1;
912+
913+
if (IsMetaobject(obj_handle)) {
914+
if (instId != 0) {
915+
goto unlock_exit;
916+
}
917+
// How do we set meta data defaults?
918+
// MetaDataPtr((struct UAVOMeta *)obj_handle), MetaNumBytes;
919+
} else {
920+
// Check access level
921+
if (UAVObjReadOnly(obj_handle)) {
922+
goto unlock_exit;
923+
}
924+
925+
// Set default data
926+
if (((struct UAVOData *)obj_handle)->type->init_callback) {
927+
((struct UAVOData *)obj_handle)->type->init_callback(obj_handle, instId);
928+
}
929+
}
930+
931+
// Fire event
932+
sendEvent((struct UAVOBase *)obj_handle, instId, EV_UPDATED);
933+
rc = 0;
934+
935+
unlock_exit:
936+
xSemaphoreGiveRecursive(mutex);
937+
return rc;
938+
}
939+
904940
/**
905941
* Set the data of a specific object instance
906942
* \param[in] obj The object handle
@@ -940,7 +976,7 @@ int32_t UAVObjSetInstanceData(UAVObjHandle obj_handle, uint16_t instId,
940976
goto unlock_exit;
941977
}
942978
// Set data
943-
memcpy(InstanceData(instEntry), dataIn, obj->instance_size);
979+
memcpy(InstanceData(instEntry), dataIn, obj->type->instance_size);
944980
}
945981

946982
// Fire event
@@ -1000,7 +1036,7 @@ int32_t UAVObjSetInstanceDataField(UAVObjHandle obj_handle, uint16_t instId, con
10001036
}
10011037

10021038
// Check for overrun
1003-
if ((size + offset) > obj->instance_size) {
1039+
if ((size + offset) > obj->type->instance_size) {
10041040
goto unlock_exit;
10051041
}
10061042

@@ -1055,7 +1091,7 @@ int32_t UAVObjGetInstanceData(UAVObjHandle obj_handle, uint16_t instId,
10551091
goto unlock_exit;
10561092
}
10571093
// Set data
1058-
memcpy(dataOut, InstanceData(instEntry), obj->instance_size);
1094+
memcpy(dataOut, InstanceData(instEntry), obj->type->instance_size);
10591095
}
10601096

10611097
rc = 0;
@@ -1108,7 +1144,7 @@ int32_t UAVObjGetInstanceDataField(UAVObjHandle obj_handle, uint16_t instId, voi
11081144
}
11091145

11101146
// Check for overrun
1111-
if ((size + offset) > obj->instance_size) {
1147+
if ((size + offset) > obj->type->instance_size) {
11121148
goto unlock_exit;
11131149
}
11141150

@@ -1597,8 +1633,8 @@ static InstanceHandle createInstance(struct UAVOData *obj, uint16_t instId)
15971633
}
15981634

15991635
/* Create the actual instance */
1600-
uint32_t size = sizeof(struct UAVOMultiInst) + obj->instance_size;
1601-
instEntry = (struct UAVOMultiInst *)pios_fastheapmalloc(size);
1636+
uint32_t size = sizeof(struct UAVOMultiInst) + obj->type->instance_size;
1637+
instEntry = (struct UAVOMultiInst *)pios_malloc(size);
16021638
if (!instEntry) {
16031639
return NULL;
16041640
}

flight/uavobjects/uavobjectpersistence.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ int32_t UAVObjLoad(UAVObjHandle obj_handle, uint16_t instId)
121121
int32_t UAVObjDelete(UAVObjHandle obj_handle, uint16_t instId)
122122
{
123123
PIOS_Assert(obj_handle);
124-
PIOS_FLASHFS_ObjDelete(pios_uavo_settings_fs_id, UAVObjGetID(obj_handle), instId);
124+
if (PIOS_FLASHFS_ObjDelete(pios_uavo_settings_fs_id, UAVObjGetID(obj_handle), instId) == 0) {
125+
UAVObjSetInstanceDefaults(obj_handle, instId);
126+
}
125127
return 0;
126128
}

0 commit comments

Comments
 (0)