2 ******************************************************************************
3 * @addtogroup UAVObjects OpenPilot UAVObjects
5 * @addtogroup UAV Object Manager
6 * @brief The core UAV Objects functions, most of which are wrappered by
7 * autogenerated defines
11 * @file uavobjectmanager.h
12 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
13 * @brief Object manager library. This library holds a collection of all objects.
14 * It can be used by all modules/libraries to find an object reference.
15 * @see The GNU Public License (GPL) Version 3
17 *****************************************************************************/
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 3 of the License, or
22 * (at your option) any later version.
24 * This program is distributed in the hope that it will be useful, but
25 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29 * You should have received a copy of the GNU General Public License along
30 * with this program; if not, write to the Free Software Foundation, Inc.,
31 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include "openpilot.h"
35 #include "pios_struct_helper.h"
36 #include "inc/uavobjectprivate.h"
39 static InstanceHandle
createInstance(struct UAVOData
*obj
, uint16_t instId
);
40 static int32_t connectObj(UAVObjHandle obj_handle
, xQueueHandle queue
, UAVObjEventCallback cb
, uint8_t eventMask
, bool fast
);
41 static int32_t disconnectObj(UAVObjHandle obj_handle
, xQueueHandle queue
, UAVObjEventCallback cb
);
42 static void instanceAutoUpdated(UAVObjHandle obj_handle
, uint16_t instId
);
45 int32_t UAVObjPers_stub(__attribute__((unused
)) UAVObjHandle obj_handle
, __attribute__((unused
)) uint16_t instId
)
49 int32_t UAVObjSave(UAVObjHandle obj_handle
, uint16_t instId
) __attribute__((weak
, alias("UAVObjPers_stub")));;
50 int32_t UAVObjLoad(UAVObjHandle obj_handle
, uint16_t instId
) __attribute__((weak
, alias("UAVObjPers_stub")));
51 int32_t UAVObjDelete(UAVObjHandle obj_handle
, uint16_t instId
) __attribute__((weak
, alias("UAVObjPers_stub")));
55 static xSemaphoreHandle mutex
;
56 static const UAVObjMetadata defMetadata
= {
57 .flags
= (ACCESS_READWRITE
<< UAVOBJ_ACCESS_SHIFT
|
58 ACCESS_READWRITE
<< UAVOBJ_GCS_ACCESS_SHIFT
|
59 1 << UAVOBJ_TELEMETRY_ACKED_SHIFT
|
60 1 << UAVOBJ_GCS_TELEMETRY_ACKED_SHIFT
|
61 UPDATEMODE_ONCHANGE
<< UAVOBJ_TELEMETRY_UPDATE_MODE_SHIFT
|
62 UPDATEMODE_ONCHANGE
<< UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT
),
63 .telemetryUpdatePeriod
= 0,
64 .gcsTelemetryUpdatePeriod
= 0,
65 .loggingUpdatePeriod
= 0,
68 static UAVObjStats stats
;
71 static inline bool IsMetaobject(UAVObjHandle obj_handle
)
73 /* Recover the common object header */
74 struct UAVOBase
*uavo_base
= (struct UAVOBase
*)obj_handle
;
76 return uavo_base
->flags
.isMeta
;
79 static inline bool IsSingleInstance(UAVObjHandle obj_handle
)
81 /* Recover the common object header */
82 struct UAVOBase
*uavo_base
= (struct UAVOBase
*)obj_handle
;
84 return uavo_base
->flags
.isSingle
;
87 static inline bool IsSettings(UAVObjHandle obj_handle
)
89 /* Recover the common object header */
90 struct UAVOBase
*uavo_base
= (struct UAVOBase
*)obj_handle
;
92 return uavo_base
->flags
.isSettings
;
95 static inline bool IsPriority(UAVObjHandle obj_handle
)
97 /* Recover the common object header */
98 struct UAVOBase
*uavo_base
= (struct UAVOBase
*)obj_handle
;
100 return uavo_base
->flags
.isPriority
;
104 * Is this a metaobject?
105 * \param[in] obj The object handle
106 * \return True (1) if this is metaobject
108 bool UAVObjIsMetaobject(UAVObjHandle obj_handle
)
110 PIOS_Assert(obj_handle
);
111 return IsMetaobject(obj_handle
);
115 * Does this object contains a single instance or multiple instances?
116 * \param[in] obj The object handle
117 * \return True (1) if this is a single instance object
119 bool UAVObjIsSingleInstance(UAVObjHandle obj_handle
)
121 PIOS_Assert(obj_handle
);
122 return IsSingleInstance(obj_handle
);
126 * Is this a settings object?
127 * \param[in] obj The object handle
128 * \return True (1) if this is a settings object
130 bool UAVObjIsSettings(UAVObjHandle obj_handle
)
132 PIOS_Assert(obj_handle
);
133 return IsSettings(obj_handle
);
138 * Is this a prioritized object?
139 * \param[in] obj The object handle
140 * \return True (1) if this is a prioritized object
142 bool UAVObjIsPriority(UAVObjHandle obj_handle
)
144 return IsPriority(obj_handle
);
149 * Initialize the object manager
153 int32_t UAVObjInitialize()
155 // Initialize variables
156 memset(&stats
, 0, sizeof(UAVObjStats
));
158 /* Initialize _uavo_handles start/stop pointers */
159 #if (defined(__MACH__) && defined(__APPLE__))
160 uint64_t aslr_offset
= (uint64_t)&_aslr_offset
- getsectbyname("__DATA", "_aslr")->addr
;
161 __start__uavo_handles
= (struct UAVOData
* *)(getsectbyname("__DATA", "_uavo_handles")->addr
+ aslr_offset
);
162 __stop__uavo_handles
= (struct UAVOData
* *)((uint64_t)__start__uavo_handles
+ getsectbyname("__DATA", "_uavo_handles")->size
);
165 // Initialize the uavo handle table
166 memset(__start__uavo_handles
, 0,
167 (uintptr_t)__stop__uavo_handles
- (uintptr_t)__start__uavo_handles
);
170 mutex
= xSemaphoreCreateRecursiveMutex();
184 * Get the statistics counters
185 * @param[out] statsOut The statistics counters will be copied there
187 void UAVObjGetStats(UAVObjStats
*statsOut
)
189 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
190 memcpy(statsOut
, &stats
, sizeof(UAVObjStats
));
191 xSemaphoreGiveRecursive(mutex
);
195 * Clear the statistics counters
197 void UAVObjClearStats()
199 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
200 memset(&stats
, 0, sizeof(UAVObjStats
));
201 xSemaphoreGiveRecursive(mutex
);
204 /************************
205 * Object Initialization
206 ***********************/
208 static void UAVObjInitMetaData(struct UAVOMeta
*obj_meta
)
210 /* Fill in the common part of the UAVO */
211 struct UAVOBase
*uavo_base
= &(obj_meta
->base
);
213 memset(uavo_base
, 0, sizeof(*uavo_base
));
214 uavo_base
->flags
.isMeta
= true;
215 uavo_base
->flags
.isSingle
= true;
216 uavo_base
->next_event
= NULL
;
218 /* Clear the instance data carried in the UAVO */
219 memset(&(obj_meta
->instance0
), 0, sizeof(obj_meta
->instance0
));
222 static struct UAVOData
*UAVObjAllocSingle(uint32_t num_bytes
)
224 /* Compute the complete size of the object, including the data for a single embedded instance */
225 uint32_t object_size
= sizeof(struct UAVOSingle
) + num_bytes
;
227 /* Allocate the object from the heap */
228 struct UAVOSingle
*uavo_single
= (struct UAVOSingle
*)pios_malloc(object_size
);
234 /* Fill in the common part of the UAVO */
235 struct UAVOBase
*uavo_base
= &(uavo_single
->uavo
.base
);
236 memset(uavo_base
, 0, sizeof(*uavo_base
));
237 uavo_base
->flags
.isSingle
= true;
238 uavo_base
->next_event
= NULL
;
240 /* Clear the instance data carried in the UAVO */
241 memset(&(uavo_single
->instance0
), 0, num_bytes
);
243 /* Give back the generic UAVO part */
244 return &(uavo_single
->uavo
);
247 static struct UAVOData
*UAVObjAllocMulti(uint32_t num_bytes
)
249 /* Compute the complete size of the object, including the data for a single embedded instance */
250 uint32_t object_size
= sizeof(struct UAVOMulti
) + num_bytes
;
252 /* Allocate the object from the heap */
253 struct UAVOMulti
*uavo_multi
= (struct UAVOMulti
*)pios_malloc(object_size
);
259 /* Fill in the common part of the UAVO */
260 struct UAVOBase
*uavo_base
= &(uavo_multi
->uavo
.base
);
261 memset(uavo_base
, 0, sizeof(*uavo_base
));
262 uavo_base
->flags
.isSingle
= false;
263 uavo_base
->next_event
= NULL
;
265 /* Set up the type-specific part of the UAVO */
266 uavo_multi
->num_instances
= 1;
268 /* Clear the multi instance data carried in the UAVO */
269 memset(&(uavo_multi
->instance0
), 0, sizeof(struct UAVOMultiInst
) + num_bytes
);
271 /* Give back the generic UAVO part */
272 return &(uavo_multi
->uavo
);
275 /**************************
276 * UAVObject Database APIs
277 *************************/
280 * Register and new object in the object manager.
281 * \param[in] pointer to UAVObjType structure that holds Unique object ID, instance size, initialization function
282 * \param[in] isSingleInstance Is this a single instance or multi-instance object
283 * \param[in] isSettings Is this a settings object
284 * \param[in] isPriority
285 * \return Object handle, or NULL if failure.
288 UAVObjHandle
UAVObjRegister(const UAVObjType
*type
,
289 bool isSingleInstance
, bool isSettings
, bool isPriority
)
291 struct UAVOData
*uavo_data
= NULL
;
293 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
295 /* Don't allow duplicate registrations */
296 if (UAVObjGetByID(type
->id
)) {
300 /* Map the various flags to one of the UAVO types we understand */
301 if (isSingleInstance
) {
302 uavo_data
= UAVObjAllocSingle(type
->instance_size
);
304 uavo_data
= UAVObjAllocMulti(type
->instance_size
);
311 /* Fill in the details about this UAVO */
312 uavo_data
->type
= type
;
314 uavo_data
->base
.flags
.isSettings
= true;
315 // settings defaults to being sent with priority
316 uavo_data
->base
.flags
.isPriority
= true;
318 uavo_data
->base
.flags
.isPriority
= isPriority
;
320 /* Initialize the embedded meta UAVO */
321 UAVObjInitMetaData(&uavo_data
->metaObj
);
323 /* Initialize object fields and metadata to default values */
324 if (type
->init_callback
) {
325 type
->init_callback((UAVObjHandle
)uavo_data
, 0);
328 /* Always try to load the meta object from flash */
329 UAVObjLoad((UAVObjHandle
) & (uavo_data
->metaObj
), 0);
331 /* Attempt to load settings object from flash */
332 if (uavo_data
->base
.flags
.isSettings
) {
333 UAVObjLoad((UAVObjHandle
)uavo_data
, 0);
336 // fire events for outer object and its embedded meta object
337 instanceAutoUpdated((UAVObjHandle
)uavo_data
, 0);
338 instanceAutoUpdated((UAVObjHandle
) & (uavo_data
->metaObj
), 0);
341 xSemaphoreGiveRecursive(mutex
);
342 return (UAVObjHandle
)uavo_data
;
346 * Retrieve an object from the list given its id
347 * \param[in] The object ID
348 * \return The object or NULL if not found.
350 UAVObjHandle
UAVObjGetByID(uint32_t id
)
352 UAVObjHandle
*found_obj
= (UAVObjHandle
*)NULL
;
355 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
358 UAVO_LIST_ITERATE(tmp_obj
)
359 if (tmp_obj
->type
->id
== id
) {
360 found_obj
= (UAVObjHandle
*)tmp_obj
;
363 if (MetaObjectId(tmp_obj
->type
->id
) == id
) {
364 found_obj
= (UAVObjHandle
*)&(tmp_obj
->metaObj
);
370 xSemaphoreGiveRecursive(mutex
);
375 * Get the object's ID
376 * \param[in] obj The object handle
377 * \return The object ID
379 uint32_t UAVObjGetID(UAVObjHandle obj_handle
)
381 PIOS_Assert(obj_handle
);
383 /* Recover the common object header */
384 struct UAVOBase
*uavo_base
= (struct UAVOBase
*)obj_handle
;
386 if (IsMetaobject(obj_handle
)) {
387 /* We have a meta object, find our containing UAVO */
388 struct UAVOData
*uavo_data
= container_of((struct UAVOMeta
*)uavo_base
, struct UAVOData
, metaObj
);
390 return MetaObjectId(uavo_data
->type
->id
);
392 /* We have a data object, augment our pointer */
393 struct UAVOData
*uavo_data
= (struct UAVOData
*)uavo_base
;
395 return uavo_data
->type
->id
;
400 * Get the number of bytes of the object's data (for one instance)
401 * \param[in] obj The object handle
402 * \return The number of bytes
404 uint32_t UAVObjGetNumBytes(UAVObjHandle obj
)
408 uint32_t instance_size
;
410 /* Recover the common object header */
411 struct UAVOBase
*uavo_base
= (struct UAVOBase
*)obj
;
413 if (uavo_base
->flags
.isMeta
) {
414 instance_size
= MetaNumBytes
;
416 /* We have a data object, augment our pointer */
417 struct UAVOData
*uavo
= (struct UAVOData
*)uavo_base
;
419 instance_size
= uavo
->type
->instance_size
;
422 return instance_size
;
426 * Get the object this object is linked to. For regular objects, the linked object
427 * is the metaobject. For metaobjects the linked object is the parent object.
428 * This function is normally only needed by the telemetry module.
429 * \param[in] obj The object handle
430 * \return The object linked object handle
432 UAVObjHandle
UAVObjGetLinkedObj(UAVObjHandle obj_handle
)
434 PIOS_Assert(obj_handle
);
436 /* Recover the common object header */
437 struct UAVOBase
*uavo_base
= (struct UAVOBase
*)obj_handle
;
439 if (IsMetaobject(obj_handle
)) {
440 /* We have a meta object, find our containing UAVO. */
441 struct UAVOData
*uavo_data
= container_of((struct UAVOMeta
*)uavo_base
, struct UAVOData
, metaObj
);
443 return (UAVObjHandle
)uavo_data
;
445 /* We have a data object, augment our pointer */
446 struct UAVOData
*uavo_data
= (struct UAVOData
*)uavo_base
;
448 return (UAVObjHandle
) & (uavo_data
->metaObj
);
453 * Get the number of instances contained in the object.
454 * \param[in] obj The object handle
455 * \return The number of instances
457 uint16_t UAVObjGetNumInstances(UAVObjHandle obj_handle
)
459 PIOS_Assert(obj_handle
);
461 if (IsSingleInstance(obj_handle
)) {
462 /* Only one instance is allowed */
465 /* Multi-instance object. Inspect the object */
466 /* Augment our pointer to reflect the proper type */
467 struct UAVOMulti
*uavo_multi
= (struct UAVOMulti
*)obj_handle
;
468 return uavo_multi
->num_instances
;
473 * Create a new instance in the object.
474 * \param[in] obj The object handle
475 * \return The instance ID or 0 if an error
477 uint16_t UAVObjCreateInstance(UAVObjHandle obj_handle
)
479 PIOS_Assert(obj_handle
);
481 if (IsMetaobject(obj_handle
)) {
486 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
488 InstanceHandle instEntry
;
491 // Create new instance
492 instId
= UAVObjGetNumInstances(obj_handle
);
493 instEntry
= createInstance((struct UAVOData
*)obj_handle
, instId
);
494 if (instEntry
== NULL
) {
498 // Initialize instance data
499 if (((struct UAVOData
*)obj_handle
)->type
->init_callback
) {
500 ((struct UAVOData
*)obj_handle
)->type
->init_callback(obj_handle
, instId
);
504 xSemaphoreGiveRecursive(mutex
);
510 * Unpack an object from a byte array
511 * \param[in] obj The object handle
512 * \param[in] instId The instance ID
513 * \param[in] dataIn The byte array
514 * \param[in] create Create the object if it does not already exist.
515 * \return 0 if success or -1 if failure
517 int32_t UAVObjUnpack(UAVObjHandle obj_handle
, uint16_t instId
, const uint8_t *dataIn
, bool create
)
519 PIOS_Assert(obj_handle
);
522 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
526 if (IsMetaobject(obj_handle
)) {
530 memcpy(MetaDataPtr((struct UAVOMeta
*)obj_handle
), dataIn
, MetaNumBytes
);
532 struct UAVOData
*obj
;
533 InstanceHandle instEntry
;
535 // Cast handle to object
536 obj
= (struct UAVOData
*)obj_handle
;
539 instEntry
= getInstance(obj
, instId
);
541 // If the instance does not exist create it and any other instances before it
542 if ((instEntry
== NULL
) && create
) {
543 instEntry
= createInstance(obj
, instId
);
545 if (instEntry
== NULL
) {
550 memcpy(InstanceData(instEntry
), dataIn
, obj
->type
->instance_size
);
554 sendEvent((struct UAVOBase
*)obj_handle
, instId
, EV_UNPACKED
);
558 xSemaphoreGiveRecursive(mutex
);
563 * Pack an object to a byte array
564 * \param[in] obj The object handle
565 * \param[in] instId The instance ID
566 * \param[out] dataOut The byte array
567 * \return 0 if success or -1 if failure
569 int32_t UAVObjPack(UAVObjHandle obj_handle
, uint16_t instId
, uint8_t *dataOut
)
571 PIOS_Assert(obj_handle
);
574 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
578 if (IsMetaobject(obj_handle
)) {
582 memcpy(dataOut
, MetaDataPtr((struct UAVOMeta
*)obj_handle
), MetaNumBytes
);
584 struct UAVOData
*obj
;
585 InstanceHandle instEntry
;
587 // Cast handle to object
588 obj
= (struct UAVOData
*)obj_handle
;
591 instEntry
= getInstance(obj
, instId
);
592 if (instEntry
== NULL
) {
596 memcpy(dataOut
, InstanceData(instEntry
), obj
->type
->instance_size
);
602 xSemaphoreGiveRecursive(mutex
);
607 * Update a CRC with an object data
608 * \param[in] obj The object handle
609 * \param[in] instId The instance ID
610 * \param[in] crc The crc to update
611 * \return the updated crc
613 uint8_t UAVObjUpdateCRC(UAVObjHandle obj_handle
, uint16_t instId
, uint8_t crc
)
615 PIOS_Assert(obj_handle
);
618 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
620 if (IsMetaobject(obj_handle
)) {
626 struct UAVOData
*obj
;
627 InstanceHandle instEntry
;
629 // Cast handle to object
630 obj
= (struct UAVOData
*)obj_handle
;
633 instEntry
= getInstance(obj
, instId
);
634 if (instEntry
== NULL
) {
638 crc
= PIOS_CRC_updateCRC(crc
, (uint8_t *)InstanceData(instEntry
), (int32_t)obj
->type
->instance_size
);
642 xSemaphoreGiveRecursive(mutex
);
647 * Actually write the object's data to the logfile
648 * \param[in] obj The object handle
649 * \param[in] instId The object instance ID
651 #ifdef PIOS_INCLUDE_DEBUGLOG
652 void UAVObjInstanceWriteToLog(UAVObjHandle obj_handle
, uint16_t instId
)
654 PIOS_Assert(obj_handle
);
657 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
659 if (IsMetaobject(obj_handle
)) {
663 PIOS_DEBUGLOG_UAVObject(UAVObjGetID(obj_handle
), instId
, MetaNumBytes
, (uint8_t *)MetaDataPtr((struct UAVOMeta
*)obj_handle
));
665 struct UAVOData
*obj
;
666 InstanceHandle instEntry
;
668 // Cast handle to object
669 obj
= (struct UAVOData
*)obj_handle
;
672 instEntry
= getInstance(obj
, instId
);
673 if (instEntry
== NULL
) {
677 PIOS_DEBUGLOG_UAVObject(UAVObjGetID(obj_handle
), instId
, obj
->type
->instance_size
, (uint8_t *)InstanceData(instEntry
));
681 xSemaphoreGiveRecursive(mutex
);
683 #else /* ifdef PIOS_INCLUDE_DEBUGLOG */
684 void UAVObjInstanceWriteToLog(__attribute__((unused
)) UAVObjHandle obj_handle
, __attribute__((unused
)) uint16_t instId
) {}
685 #endif /* ifdef PIOS_INCLUDE_DEBUGLOG */
687 * Save all settings objects to the SD card.
688 * @return 0 if success or -1 if failure
690 int32_t UAVObjSaveSettings()
693 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
697 // Save all settings objects
698 UAVO_LIST_ITERATE(obj
)
699 // Check if this is a settings object
700 if (IsSettings(obj
)) {
702 if (UAVObjSave((UAVObjHandle
)obj
, 0) ==
712 xSemaphoreGiveRecursive(mutex
);
717 * Load all settings objects from the SD card.
718 * @return 0 if success or -1 if failure
720 int32_t UAVObjLoadSettings()
723 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
727 // Load all settings objects
728 UAVO_LIST_ITERATE(obj
)
729 // Check if this is a settings object
730 if (IsSettings(obj
)) {
732 if (UAVObjLoad((UAVObjHandle
)obj
, 0) ==
742 xSemaphoreGiveRecursive(mutex
);
747 * Delete all settings objects from the SD card.
748 * @return 0 if success or -1 if failure
750 int32_t UAVObjDeleteSettings()
753 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
757 // Save all settings objects
758 UAVO_LIST_ITERATE(obj
)
759 // Check if this is a settings object
760 if (IsSettings(obj
)) {
762 if (UAVObjDelete((UAVObjHandle
)obj
, 0)
772 xSemaphoreGiveRecursive(mutex
);
777 * Save all metaobjects to the SD card.
778 * @return 0 if success or -1 if failure
780 int32_t UAVObjSaveMetaobjects()
783 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
787 // Save all settings objects
788 UAVO_LIST_ITERATE(obj
)
790 if (UAVObjSave((UAVObjHandle
)MetaObjectPtr(obj
), 0) ==
799 xSemaphoreGiveRecursive(mutex
);
804 * Load all metaobjects from the SD card.
805 * @return 0 if success or -1 if failure
807 int32_t UAVObjLoadMetaobjects()
810 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
814 // Load all settings objects
815 UAVO_LIST_ITERATE(obj
)
817 if (UAVObjLoad((UAVObjHandle
)MetaObjectPtr(obj
), 0) ==
826 xSemaphoreGiveRecursive(mutex
);
831 * Delete all metaobjects from the SD card.
832 * @return 0 if success or -1 if failure
834 int32_t UAVObjDeleteMetaobjects()
837 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
841 // Load all settings objects
842 UAVO_LIST_ITERATE(obj
)
844 if (UAVObjDelete((UAVObjHandle
)MetaObjectPtr(obj
), 0)
853 xSemaphoreGiveRecursive(mutex
);
857 int32_t UAVObjSetDefaults(UAVObjHandle obj_handle
)
859 return UAVObjSetInstanceDefaults(obj_handle
, 0);
863 * Set the object data
864 * \param[in] obj The object handle
865 * \param[in] dataIn The object's data structure
866 * \return 0 if success or -1 if failure
868 int32_t UAVObjSetData(UAVObjHandle obj_handle
, const void *dataIn
)
870 return UAVObjSetInstanceData(obj_handle
, 0, dataIn
);
874 * Set the object data
875 * \param[in] obj The object handle
876 * \param[in] dataIn The object's data structure
877 * \return 0 if success or -1 if failure
879 int32_t UAVObjSetDataField(UAVObjHandle obj_handle
, const void *dataIn
, uint32_t offset
, uint32_t size
)
881 return UAVObjSetInstanceDataField(obj_handle
, 0, dataIn
, offset
, size
);
885 * Get the object data
886 * \param[in] obj The object handle
887 * \param[out] dataOut The object's data structure
888 * \return 0 if success or -1 if failure
890 int32_t UAVObjGetData(UAVObjHandle obj_handle
, void *dataOut
)
892 return UAVObjGetInstanceData(obj_handle
, 0, dataOut
);
896 * Get the object data
897 * \param[in] obj The object handle
898 * \param[out] dataOut The object's data structure
899 * \return 0 if success or -1 if failure
901 int32_t UAVObjGetDataField(UAVObjHandle obj_handle
, void *dataOut
, uint32_t offset
, uint32_t size
)
903 return UAVObjGetInstanceDataField(obj_handle
, 0, dataOut
, offset
, size
);
906 int32_t UAVObjSetInstanceDefaults(UAVObjHandle obj_handle
, uint16_t instId
)
908 PIOS_Assert(obj_handle
);
911 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
915 if (IsMetaobject(obj_handle
)) {
919 // How do we set meta data defaults?
920 // MetaDataPtr((struct UAVOMeta *)obj_handle), MetaNumBytes;
922 // Check access level
923 if (UAVObjReadOnly(obj_handle
)) {
928 if (((struct UAVOData
*)obj_handle
)->type
->init_callback
) {
929 ((struct UAVOData
*)obj_handle
)->type
->init_callback(obj_handle
, instId
);
934 sendEvent((struct UAVOBase
*)obj_handle
, instId
, EV_UPDATED
);
938 xSemaphoreGiveRecursive(mutex
);
943 * Set the data of a specific object instance
944 * \param[in] obj The object handle
945 * \param[in] instId The object instance ID
946 * \param[in] dataIn The object's data structure
947 * \return 0 if success or -1 if failure
949 int32_t UAVObjSetInstanceData(UAVObjHandle obj_handle
, uint16_t instId
,
952 PIOS_Assert(obj_handle
);
955 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
959 if (IsMetaobject(obj_handle
)) {
963 memcpy(MetaDataPtr((struct UAVOMeta
*)obj_handle
), dataIn
, MetaNumBytes
);
965 struct UAVOData
*obj
;
966 InstanceHandle instEntry
;
968 // Cast to object info
969 obj
= (struct UAVOData
*)obj_handle
;
971 // Check access level
972 if (UAVObjReadOnly(obj_handle
)) {
975 // Get instance information
976 instEntry
= getInstance(obj
, instId
);
977 if (instEntry
== NULL
) {
981 memcpy(InstanceData(instEntry
), dataIn
, obj
->type
->instance_size
);
985 sendEvent((struct UAVOBase
*)obj_handle
, instId
, EV_UPDATED
);
989 xSemaphoreGiveRecursive(mutex
);
994 * Set the data of a specific object instance
995 * \param[in] obj The object handle
996 * \param[in] instId The object instance ID
997 * \param[in] dataIn The object's data structure
998 * \return 0 if success or -1 if failure
1000 int32_t UAVObjSetInstanceDataField(UAVObjHandle obj_handle
, uint16_t instId
, const void *dataIn
, uint32_t offset
, uint32_t size
)
1002 PIOS_Assert(obj_handle
);
1005 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
1009 if (IsMetaobject(obj_handle
)) {
1010 // Get instance information
1015 // Check for overrun
1016 if ((size
+ offset
) > MetaNumBytes
) {
1021 memcpy(MetaDataPtr((struct UAVOMeta
*)obj_handle
) + offset
, dataIn
, size
);
1023 struct UAVOData
*obj
;
1024 InstanceHandle instEntry
;
1026 // Cast to object info
1027 obj
= (struct UAVOData
*)obj_handle
;
1029 // Check access level
1030 if (UAVObjReadOnly(obj_handle
)) {
1034 // Get instance information
1035 instEntry
= getInstance(obj
, instId
);
1036 if (instEntry
== NULL
) {
1040 // Check for overrun
1041 if ((size
+ offset
) > obj
->type
->instance_size
) {
1046 memcpy(InstanceData(instEntry
) + offset
, dataIn
, size
);
1051 sendEvent((struct UAVOBase
*)obj_handle
, instId
, EV_UPDATED
);
1055 xSemaphoreGiveRecursive(mutex
);
1060 * Get the data of a specific object instance
1061 * \param[in] obj The object handle
1062 * \param[in] instId The object instance ID
1063 * \param[out] dataOut The object's data structure
1064 * \return 0 if success or -1 if failure
1066 int32_t UAVObjGetInstanceData(UAVObjHandle obj_handle
, uint16_t instId
,
1069 PIOS_Assert(obj_handle
);
1072 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
1076 if (IsMetaobject(obj_handle
)) {
1077 // Get instance information
1082 memcpy(dataOut
, MetaDataPtr((struct UAVOMeta
*)obj_handle
), MetaNumBytes
);
1084 struct UAVOData
*obj
;
1085 InstanceHandle instEntry
;
1087 // Cast to object info
1088 obj
= (struct UAVOData
*)obj_handle
;
1090 // Get instance information
1091 instEntry
= getInstance(obj
, instId
);
1092 if (instEntry
== NULL
) {
1096 memcpy(dataOut
, InstanceData(instEntry
), obj
->type
->instance_size
);
1102 xSemaphoreGiveRecursive(mutex
);
1107 * Get the data of a specific object instance
1108 * \param[in] obj The object handle
1109 * \param[in] instId The object instance ID
1110 * \param[out] dataOut The object's data structure
1111 * \return 0 if success or -1 if failure
1113 int32_t UAVObjGetInstanceDataField(UAVObjHandle obj_handle
, uint16_t instId
, void *dataOut
, uint32_t offset
, uint32_t size
)
1115 PIOS_Assert(obj_handle
);
1118 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
1122 if (IsMetaobject(obj_handle
)) {
1123 // Get instance information
1128 // Check for overrun
1129 if ((size
+ offset
) > MetaNumBytes
) {
1134 memcpy(dataOut
, MetaDataPtr((struct UAVOMeta
*)obj_handle
) + offset
, size
);
1136 struct UAVOData
*obj
;
1137 InstanceHandle instEntry
;
1139 // Cast to object info
1140 obj
= (struct UAVOData
*)obj_handle
;
1142 // Get instance information
1143 instEntry
= getInstance(obj
, instId
);
1144 if (instEntry
== NULL
) {
1148 // Check for overrun
1149 if ((size
+ offset
) > obj
->type
->instance_size
) {
1154 memcpy(dataOut
, InstanceData(instEntry
) + offset
, size
);
1160 xSemaphoreGiveRecursive(mutex
);
1165 * Set the object metadata
1166 * \param[in] obj The object handle
1167 * \param[in] dataIn The object's metadata structure
1168 * \return 0 if success or -1 if failure
1170 int32_t UAVObjSetMetadata(UAVObjHandle obj_handle
, const UAVObjMetadata
*dataIn
)
1172 PIOS_Assert(obj_handle
);
1174 // Set metadata (metadata of metaobjects can not be modified)
1175 if (IsMetaobject(obj_handle
)) {
1179 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
1181 UAVObjSetData((UAVObjHandle
)MetaObjectPtr((struct UAVOData
*)obj_handle
), dataIn
);
1183 xSemaphoreGiveRecursive(mutex
);
1188 * Get the object metadata
1189 * \param[in] obj The object handle
1190 * \param[out] dataOut The object's metadata structure
1191 * \return 0 if success or -1 if failure
1193 int32_t UAVObjGetMetadata(UAVObjHandle obj_handle
, UAVObjMetadata
*dataOut
)
1195 PIOS_Assert(obj_handle
);
1198 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
1201 if (IsMetaobject(obj_handle
)) {
1202 memcpy(dataOut
, &defMetadata
, sizeof(UAVObjMetadata
));
1204 UAVObjGetData((UAVObjHandle
)MetaObjectPtr((struct UAVOData
*)obj_handle
),
1209 xSemaphoreGiveRecursive(mutex
);
1213 /*******************************
1214 * Object Metadata Manipulation
1215 ******************************/
1218 * Get the UAVObject metadata access member
1219 * \param[in] metadata The metadata object
1220 * \return the access type
1222 UAVObjAccessType
UAVObjGetAccess(const UAVObjMetadata
*metadata
)
1224 PIOS_Assert(metadata
);
1225 return (metadata
->flags
>> UAVOBJ_ACCESS_SHIFT
) & 1;
1229 * Set the UAVObject metadata access member
1230 * \param[in] metadata The metadata object
1231 * \param[in] mode The access mode
1233 void UAVObjSetAccess(UAVObjMetadata
*metadata
, UAVObjAccessType mode
)
1235 PIOS_Assert(metadata
);
1236 SET_BITS(metadata
->flags
, UAVOBJ_ACCESS_SHIFT
, mode
, 1);
1240 * Get the UAVObject metadata GCS access member
1241 * \param[in] metadata The metadata object
1242 * \return the GCS access type
1244 UAVObjAccessType
UAVObjGetGcsAccess(const UAVObjMetadata
*metadata
)
1246 PIOS_Assert(metadata
);
1247 return (metadata
->flags
>> UAVOBJ_GCS_ACCESS_SHIFT
) & 1;
1251 * Set the UAVObject metadata GCS access member
1252 * \param[in] metadata The metadata object
1253 * \param[in] mode The access mode
1255 void UAVObjSetGcsAccess(UAVObjMetadata
*metadata
, UAVObjAccessType mode
)
1257 PIOS_Assert(metadata
);
1258 SET_BITS(metadata
->flags
, UAVOBJ_GCS_ACCESS_SHIFT
, mode
, 1);
1262 * Get the UAVObject metadata telemetry acked member
1263 * \param[in] metadata The metadata object
1264 * \return the telemetry acked boolean
1266 uint8_t UAVObjGetTelemetryAcked(const UAVObjMetadata
*metadata
)
1268 PIOS_Assert(metadata
);
1269 return (metadata
->flags
>> UAVOBJ_TELEMETRY_ACKED_SHIFT
) & 1;
1273 * Set the UAVObject metadata telemetry acked member
1274 * \param[in] metadata The metadata object
1275 * \param[in] val The telemetry acked boolean
1277 void UAVObjSetTelemetryAcked(UAVObjMetadata
*metadata
, uint8_t val
)
1279 PIOS_Assert(metadata
);
1280 SET_BITS(metadata
->flags
, UAVOBJ_TELEMETRY_ACKED_SHIFT
, val
, 1);
1284 * Get the UAVObject metadata GCS telemetry acked member
1285 * \param[in] metadata The metadata object
1286 * \return the telemetry acked boolean
1288 uint8_t UAVObjGetGcsTelemetryAcked(const UAVObjMetadata
*metadata
)
1290 PIOS_Assert(metadata
);
1291 return (metadata
->flags
>> UAVOBJ_GCS_TELEMETRY_ACKED_SHIFT
) & 1;
1295 * Set the UAVObject metadata GCS telemetry acked member
1296 * \param[in] metadata The metadata object
1297 * \param[in] val The GCS telemetry acked boolean
1299 void UAVObjSetGcsTelemetryAcked(UAVObjMetadata
*metadata
, uint8_t val
)
1301 PIOS_Assert(metadata
);
1302 SET_BITS(metadata
->flags
, UAVOBJ_GCS_TELEMETRY_ACKED_SHIFT
, val
, 1);
1306 * Get the UAVObject metadata telemetry update mode
1307 * \param[in] metadata The metadata object
1308 * \return the telemetry update mode
1310 UAVObjUpdateMode
UAVObjGetTelemetryUpdateMode(const UAVObjMetadata
*metadata
)
1312 PIOS_Assert(metadata
);
1313 return (metadata
->flags
>> UAVOBJ_TELEMETRY_UPDATE_MODE_SHIFT
) & UAVOBJ_UPDATE_MODE_MASK
;
1317 * Set the UAVObject metadata telemetry update mode member
1318 * \param[in] metadata The metadata object
1319 * \param[in] val The telemetry update mode
1321 void UAVObjSetTelemetryUpdateMode(UAVObjMetadata
*metadata
, UAVObjUpdateMode val
)
1323 PIOS_Assert(metadata
);
1324 SET_BITS(metadata
->flags
, UAVOBJ_TELEMETRY_UPDATE_MODE_SHIFT
, val
, UAVOBJ_UPDATE_MODE_MASK
);
1328 * Get the UAVObject metadata GCS telemetry update mode
1329 * \param[in] metadata The metadata object
1330 * \return the GCS telemetry update mode
1332 UAVObjUpdateMode
UAVObjGetGcsTelemetryUpdateMode(const UAVObjMetadata
*metadata
)
1334 PIOS_Assert(metadata
);
1335 return (metadata
->flags
>> UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT
) & UAVOBJ_UPDATE_MODE_MASK
;
1339 * Set the UAVObject metadata GCS telemetry update mode member
1340 * \param[in] metadata The metadata object
1341 * \param[in] val The GCS telemetry update mode
1343 void UAVObjSetGcsTelemetryUpdateMode(UAVObjMetadata
*metadata
, UAVObjUpdateMode val
)
1345 PIOS_Assert(metadata
);
1346 SET_BITS(metadata
->flags
, UAVOBJ_GCS_TELEMETRY_UPDATE_MODE_SHIFT
, val
, UAVOBJ_UPDATE_MODE_MASK
);
1350 * Get the UAVObject metadata logging update mode
1351 * \param[in] metadata The metadata object
1352 * \return the GCS telemetry update mode
1354 UAVObjUpdateMode
UAVObjGetLoggingUpdateMode(const UAVObjMetadata
*metadata
)
1356 PIOS_Assert(metadata
);
1357 return (metadata
->flags
>> UAVOBJ_LOGGING_UPDATE_MODE_SHIFT
) & UAVOBJ_UPDATE_MODE_MASK
;
1361 * Set the UAVObject metadata logging update mode member
1362 * \param[in] metadata The metadata object
1363 * \param[in] val The GCS telemetry update mode
1365 void UAVObjSetLoggingUpdateMode(UAVObjMetadata
*metadata
, UAVObjUpdateMode val
)
1367 PIOS_Assert(metadata
);
1368 SET_BITS(metadata
->flags
, UAVOBJ_LOGGING_UPDATE_MODE_SHIFT
, val
, UAVOBJ_UPDATE_MODE_MASK
);
1373 * Check if an object is read only
1374 * \param[in] obj The object handle
1376 * \arg 0 if not read only
1377 * \arg 1 if read only
1378 * \arg -1 if unable to get meta data
1380 int8_t UAVObjReadOnly(UAVObjHandle obj_handle
)
1382 PIOS_Assert(obj_handle
);
1383 if (!IsMetaobject(obj_handle
)) {
1384 return UAVObjGetAccess(LinkedMetaDataPtr((struct UAVOData
*)obj_handle
)) == ACCESS_READONLY
;
1390 * Connect an event queue to the object, if the queue is already connected then the event mask is only updated.
1391 * All events matching the event mask will be pushed to the event queue.
1392 * \param[in] obj The object handle
1393 * \param[in] queue The event queue
1394 * \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL)
1395 * \return 0 if success or -1 if failure
1397 int32_t UAVObjConnectQueue(UAVObjHandle obj_handle
, xQueueHandle queue
,
1400 PIOS_Assert(obj_handle
);
1403 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
1404 res
= connectObj(obj_handle
, queue
, 0, eventMask
, false);
1405 xSemaphoreGiveRecursive(mutex
);
1410 * Disconnect an event queue from the object.
1411 * \param[in] obj The object handle
1412 * \param[in] queue The event queue
1413 * \return 0 if success or -1 if failure
1415 int32_t UAVObjDisconnectQueue(UAVObjHandle obj_handle
, xQueueHandle queue
)
1417 PIOS_Assert(obj_handle
);
1420 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
1421 res
= disconnectObj(obj_handle
, queue
, 0);
1422 xSemaphoreGiveRecursive(mutex
);
1427 * Connect an event callback to the object, if the callback is already connected then the event mask is only updated.
1428 * The supplied callback will be invoked on all events matching the event mask.
1429 * \param[in] obj The object handle
1430 * \param[in] cb The event callback
1431 * \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL)
1432 * \return 0 if success or -1 if failure
1434 int32_t UAVObjConnectCallback(UAVObjHandle obj_handle
, UAVObjEventCallback cb
,
1435 uint8_t eventMask
, bool fast
)
1437 PIOS_Assert(obj_handle
);
1439 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
1440 res
= connectObj(obj_handle
, 0, cb
, eventMask
, fast
);
1441 xSemaphoreGiveRecursive(mutex
);
1446 * Disconnect an event callback from the object.
1447 * \param[in] obj The object handle
1448 * \param[in] cb The event callback
1449 * \return 0 if success or -1 if failure
1451 int32_t UAVObjDisconnectCallback(UAVObjHandle obj_handle
, UAVObjEventCallback cb
)
1453 PIOS_Assert(obj_handle
);
1455 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
1456 res
= disconnectObj(obj_handle
, 0, cb
);
1457 xSemaphoreGiveRecursive(mutex
);
1462 * Request an update of the object's data from the GCS. The call will not wait for the response, a EV_UPDATED event
1463 * will be generated as soon as the object is updated.
1464 * \param[in] obj The object handle
1466 void UAVObjRequestUpdate(UAVObjHandle obj_handle
)
1468 UAVObjRequestInstanceUpdate(obj_handle
, UAVOBJ_ALL_INSTANCES
);
1472 * Request an update of the object's data from the GCS.
1473 * The call will not wait for the response, a EV_UPDATED event will be generated as soon as the object is updated.
1474 * \param[in] obj The object handle
1475 * \param[in] instId Object instance ID to update
1477 void UAVObjRequestInstanceUpdate(UAVObjHandle obj_handle
, uint16_t instId
)
1479 PIOS_Assert(obj_handle
);
1480 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
1481 sendEvent((struct UAVOBase
*)obj_handle
, instId
, EV_UPDATE_REQ
);
1482 xSemaphoreGiveRecursive(mutex
);
1486 * Trigger a EV_UPDATED_MANUAL event for an object.
1487 * \param[in] obj The object handle
1489 void UAVObjUpdated(UAVObjHandle obj_handle
)
1491 UAVObjInstanceUpdated(obj_handle
, UAVOBJ_ALL_INSTANCES
);
1495 * Trigger a EV_UPDATED_MANUAL event for an object instance.
1496 * \param[in] obj The object handle
1497 * \param[in] instId The object instance ID
1499 void UAVObjInstanceUpdated(UAVObjHandle obj_handle
, uint16_t instId
)
1501 PIOS_Assert(obj_handle
);
1502 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
1503 sendEvent((struct UAVOBase
*)obj_handle
, instId
, EV_UPDATED_MANUAL
);
1504 xSemaphoreGiveRecursive(mutex
);
1508 * Trigger a EV_UPDATED event for an object instance.
1509 * \param[in] obj The object handle
1510 * \param[in] instId The object instance ID
1512 static void instanceAutoUpdated(UAVObjHandle obj_handle
, uint16_t instId
)
1514 PIOS_Assert(obj_handle
);
1515 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
1516 sendEvent((struct UAVOBase
*)obj_handle
, instId
, EV_UPDATED
);
1517 xSemaphoreGiveRecursive(mutex
);
1521 * Log the object's data (triggers a EV_LOGGING_MANUAL event on this object).
1522 * \param[in] obj The object handle
1524 void UAVObjLogging(UAVObjHandle obj_handle
)
1526 UAVObjInstanceLogging(obj_handle
, UAVOBJ_ALL_INSTANCES
);
1530 * Log the object's data (triggers a EV_LOGGING_MANUAL event on this object).
1531 * \param[in] obj The object handle
1532 * \param[in] instId The object instance ID
1534 void UAVObjInstanceLogging(UAVObjHandle obj_handle
, uint16_t instId
)
1536 PIOS_Assert(obj_handle
);
1537 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
1538 sendEvent((struct UAVOBase
*)obj_handle
, instId
, EV_LOGGING_MANUAL
);
1539 xSemaphoreGiveRecursive(mutex
);
1543 * Iterate through all objects in the list.
1544 * \param iterator This function will be called once for each object,
1545 * the object will be passed as a parameter
1547 void UAVObjIterate(void (*iterator
)(UAVObjHandle obj
))
1549 PIOS_Assert(iterator
);
1552 xSemaphoreTakeRecursive(mutex
, portMAX_DELAY
);
1554 // Iterate through the list and invoke iterator for each object
1555 UAVO_LIST_ITERATE (obj
)
1556 (*iterator
)((UAVObjHandle
)obj
);
1557 (*iterator
)((UAVObjHandle
) &obj
->metaObj
);
1561 xSemaphoreGiveRecursive(mutex
);
1565 * Send a triggered event to all event queues registered on the object.
1567 int32_t sendEvent(struct UAVOBase
*obj
, uint16_t instId
, UAVObjEventType triggered_event
)
1569 /* Set up the message that will be sent to all registered listeners */
1571 .obj
= (UAVObjHandle
)obj
,
1572 .event
= triggered_event
,
1574 .lowPriority
= false,
1577 // Go through each object and push the event message in the queue (if event is activated for the queue)
1578 struct ObjectEventEntry
*event
;
1580 LL_FOREACH(obj
->next_event
, event
) {
1581 if (event
->eventMask
== 0 || (event
->eventMask
& triggered_event
) != 0) {
1582 // Send to queue if a valid queue is registered
1585 if (xQueueSend(event
->queue
, &msg
, 0) != pdTRUE
) {
1586 ++stats
.eventQueueErrors
;
1587 stats
.lastQueueErrorID
= UAVObjGetID(obj
);
1591 // Invoke callback (from event task) if a valid one is registered
1595 } else if (EventCallbackDispatch(&msg
, event
->cb
) != pdTRUE
) {
1596 // invoke callback from the event task, will not block
1597 ++stats
.eventCallbackErrors
;
1598 stats
.lastCallbackErrorID
= UAVObjGetID(obj
);
1608 * Create a new object instance, return the instance info or NULL if failure.
1610 static InstanceHandle
createInstance(struct UAVOData
*obj
, uint16_t instId
)
1612 struct UAVOMultiInst
*instEntry
;
1614 /* Don't allow more than one instance for single instance objects */
1615 if (IsSingleInstance(&(obj
->base
))) {
1620 /* Don't create more than the allowed number of instances */
1621 if (instId
>= UAVOBJ_MAX_INSTANCES
) {
1625 /* Don't allow duplicate instances */
1626 if (instId
< UAVObjGetNumInstances(&(obj
->base
))) {
1630 // Create any missing instances (all instance IDs must be sequential)
1631 for (uint16_t n
= UAVObjGetNumInstances(&(obj
->base
)); n
< instId
; ++n
) {
1632 if (createInstance(obj
, n
) == NULL
) {
1637 /* Create the actual instance */
1638 uint32_t size
= sizeof(struct UAVOMultiInst
) + obj
->type
->instance_size
;
1639 instEntry
= (struct UAVOMultiInst
*)pios_malloc(size
);
1643 memset(instEntry
, 0, size
);
1644 LL_APPEND(((struct UAVOMulti
*)obj
)->instance0
.next
, instEntry
);
1646 ((struct UAVOMulti
*)obj
)->num_instances
++;
1649 instanceAutoUpdated((UAVObjHandle
)obj
, instId
);
1652 return InstanceDataOffset(instEntry
);
1656 * Get the instance information or NULL if the instance does not exist
1658 InstanceHandle
getInstance(struct UAVOData
*obj
, uint16_t instId
)
1660 if (IsMetaobject(&obj
->base
)) {
1661 /* Metadata Instance */
1667 /* Augment our pointer to reflect the proper type */
1668 struct UAVOMeta
*uavo_meta
= (struct UAVOMeta
*)obj
;
1669 return &(uavo_meta
->instance0
);
1670 } else if (IsSingleInstance(&(obj
->base
))) {
1671 /* Single Instance */
1677 /* Augment our pointer to reflect the proper type */
1678 struct UAVOSingle
*uavo_single
= (struct UAVOSingle
*)obj
;
1679 return &(uavo_single
->instance0
);
1681 /* Multi Instance */
1682 /* Augment our pointer to reflect the proper type */
1683 struct UAVOMulti
*uavo_multi
= (struct UAVOMulti
*)obj
;
1684 if (instId
>= uavo_multi
->num_instances
) {
1688 // Look for specified instance ID
1689 uint16_t instance
= 0;
1690 struct UAVOMultiInst
*instEntry
;
1691 LL_FOREACH(&(uavo_multi
->instance0
), instEntry
) {
1692 if (instance
++ == instId
) {
1694 return &(instEntry
->instance
);
1697 /* Instance was not found */
1703 * Connect an event queue to the object, if the queue is already connected then the event mask is only updated.
1704 * \param[in] obj The object handle
1705 * \param[in] queue The event queue
1706 * \param[in] cb The event callback
1707 * \param[in] eventMask The event mask, if EV_MASK_ALL then all events are enabled (e.g. EV_UPDATED | EV_UPDATED_MANUAL)
1708 * \return 0 if success or -1 if failure
1710 static int32_t connectObj(UAVObjHandle obj_handle
, xQueueHandle queue
,
1711 UAVObjEventCallback cb
, uint8_t eventMask
, bool fast
)
1713 struct ObjectEventEntry
*event
;
1714 struct UAVOBase
*obj
;
1716 // Check that the queue is not already connected, if it is simply update event mask
1717 obj
= (struct UAVOBase
*)obj_handle
;
1718 LL_FOREACH(obj
->next_event
, event
) {
1719 if (event
->queue
== queue
&& event
->cb
== cb
) {
1720 // Already connected, update event mask and return
1721 event
->eventMask
= eventMask
;
1727 // Add queue to list
1728 event
= (struct ObjectEventEntry
*)pios_fastheapmalloc(sizeof(struct ObjectEventEntry
));
1729 if (event
== NULL
) {
1732 event
->queue
= queue
;
1734 event
->eventMask
= eventMask
;
1736 LL_APPEND(obj
->next_event
, event
);
1743 * Disconnect an event queue from the object
1744 * \param[in] obj The object handle
1745 * \param[in] queue The event queue
1746 * \param[in] cb The event callback
1747 * \return 0 if success or -1 if failure
1749 static int32_t disconnectObj(UAVObjHandle obj_handle
, xQueueHandle queue
,
1750 UAVObjEventCallback cb
)
1752 struct ObjectEventEntry
*event
;
1753 struct UAVOBase
*obj
;
1755 // Find queue and remove it
1756 obj
= (struct UAVOBase
*)obj_handle
;
1757 LL_FOREACH(obj
->next_event
, event
) {
1758 if ((event
->queue
== queue
1759 && event
->cb
== cb
)) {
1760 LL_DELETE(obj
->next_event
, event
);
1766 // If this point is reached the queue was not found