mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-17 02:52:12 +01:00
Merge branch 'stac/stop-wasting-ram' into next
This commit is contained in:
commit
1fbaaddcd4
@ -74,7 +74,6 @@ static void telemetryRxTask(void *parameters);
|
||||
static int32_t transmitData(uint8_t * data, int32_t length);
|
||||
static void registerObject(UAVObjHandle obj);
|
||||
static void updateObject(UAVObjHandle obj, int32_t eventType);
|
||||
static int32_t addObject(UAVObjHandle obj);
|
||||
static int32_t setUpdatePeriod(UAVObjHandle obj, int32_t updatePeriodMs);
|
||||
static void processObjEvent(UAVObjEvent * ev);
|
||||
static void updateTelemetryStats();
|
||||
@ -154,11 +153,31 @@ MODULE_INITCALL(TelemetryInitialize, TelemetryStart)
|
||||
*/
|
||||
static void registerObject(UAVObjHandle obj)
|
||||
{
|
||||
// Setup object for periodic updates
|
||||
addObject(obj);
|
||||
if (UAVObjIsMetaobject(obj)) {
|
||||
/* Only connect change notifications for meta objects. No periodic updates */
|
||||
UAVObjConnectQueue(obj, priorityQueue, EV_MASK_ALL_UPDATES);
|
||||
return;
|
||||
} else {
|
||||
UAVObjMetadata metadata;
|
||||
UAVObjUpdateMode updateMode;
|
||||
UAVObjGetMetadata(obj, &metadata);
|
||||
updateMode = UAVObjGetTelemetryUpdateMode(&metadata);
|
||||
|
||||
// Setup object for telemetry updates
|
||||
updateObject(obj, EV_NONE);
|
||||
/* Only create a periodic event for objects that are periodic */
|
||||
if ((updateMode == UPDATEMODE_PERIODIC) ||
|
||||
(updateMode == UPDATEMODE_THROTTLED)) {
|
||||
// Setup object for periodic updates
|
||||
UAVObjEvent ev = {
|
||||
.obj = obj,
|
||||
.instId = UAVOBJ_ALL_INSTANCES,
|
||||
.event = EV_UPDATED_PERIODIC,
|
||||
};
|
||||
EventPeriodicQueueCreate(&ev, queue, 0);
|
||||
}
|
||||
|
||||
// Setup object for telemetry updates
|
||||
updateObject(obj, EV_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -171,30 +190,35 @@ static void updateObject(UAVObjHandle obj, int32_t eventType)
|
||||
UAVObjUpdateMode updateMode;
|
||||
int32_t eventMask;
|
||||
|
||||
if (UAVObjIsMetaobject(obj)) {
|
||||
/* This function updates the periodic updates for the object.
|
||||
* Meta Objects cannot have periodic updates.
|
||||
*/
|
||||
PIOS_Assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get metadata
|
||||
UAVObjGetMetadata(obj, &metadata);
|
||||
updateMode = UAVObjGetTelemetryUpdateMode(&metadata);
|
||||
|
||||
// Setup object depending on update mode
|
||||
if (updateMode == UPDATEMODE_PERIODIC) {
|
||||
switch (updateMode) {
|
||||
case UPDATEMODE_PERIODIC:
|
||||
// Set update period
|
||||
setUpdatePeriod(obj, metadata.telemetryUpdatePeriod);
|
||||
// Connect queue
|
||||
eventMask = EV_UPDATED_PERIODIC | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
if (UAVObjIsMetaobject(obj)) {
|
||||
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
|
||||
}
|
||||
UAVObjConnectQueue(obj, priorityQueue, eventMask);
|
||||
} else if (updateMode == UPDATEMODE_ONCHANGE) {
|
||||
break;
|
||||
case UPDATEMODE_ONCHANGE:
|
||||
// Set update period
|
||||
setUpdatePeriod(obj, 0);
|
||||
// Connect queue
|
||||
eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
if (UAVObjIsMetaobject(obj)) {
|
||||
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
|
||||
}
|
||||
UAVObjConnectQueue(obj, priorityQueue, eventMask);
|
||||
} else if (updateMode == UPDATEMODE_THROTTLED) {
|
||||
break;
|
||||
case UPDATEMODE_THROTTLED:
|
||||
if ((eventType == EV_UPDATED_PERIODIC) || (eventType == EV_NONE)) {
|
||||
// If we received a periodic update, we can change back to update on change
|
||||
eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
@ -205,19 +229,15 @@ static void updateObject(UAVObjHandle obj, int32_t eventType)
|
||||
// Otherwise, we just received an object update, so switch to periodic for the timeout period to prevent more updates
|
||||
eventMask = EV_UPDATED_PERIODIC | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
}
|
||||
if (UAVObjIsMetaobject(obj)) {
|
||||
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
|
||||
}
|
||||
UAVObjConnectQueue(obj, priorityQueue, eventMask);
|
||||
} else if (updateMode == UPDATEMODE_MANUAL) {
|
||||
break;
|
||||
case UPDATEMODE_MANUAL:
|
||||
// Set update period
|
||||
setUpdatePeriod(obj, 0);
|
||||
// Connect queue
|
||||
eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
if (UAVObjIsMetaobject(obj)) {
|
||||
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
|
||||
}
|
||||
UAVObjConnectQueue(obj, priorityQueue, eventMask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,11 +291,11 @@ static void processObjEvent(UAVObjEvent * ev)
|
||||
// If this is a metaobject then make necessary telemetry updates
|
||||
if (UAVObjIsMetaobject(ev->obj)) {
|
||||
updateObject(UAVObjGetLinkedObj(ev->obj), EV_NONE); // linked object will be the actual object the metadata are for
|
||||
}
|
||||
|
||||
if((updateMode == UPDATEMODE_THROTTLED) && !UAVObjIsMetaobject(ev->obj)) {
|
||||
// If this is UPDATEMODE_THROTTLED, the event mask changes on every event.
|
||||
updateObject(ev->obj, ev->event);
|
||||
} else {
|
||||
if (updateMode == UPDATEMODE_THROTTLED) {
|
||||
// If this is UPDATEMODE_THROTTLED, the event mask changes on every event.
|
||||
updateObject(ev->obj, ev->event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -380,23 +400,6 @@ static int32_t transmitData(uint8_t * data, int32_t length)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup object for periodic updates.
|
||||
* \param[in] obj The object to update
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
*/
|
||||
static int32_t addObject(UAVObjHandle obj)
|
||||
{
|
||||
UAVObjEvent ev;
|
||||
|
||||
// Add object for periodic updates
|
||||
ev.obj = obj;
|
||||
ev.instId = UAVOBJ_ALL_INSTANCES;
|
||||
ev.event = EV_UPDATED_PERIODIC;
|
||||
return EventPeriodicQueueCreate(&ev, queue, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set update period of object (it must be already setup for periodic updates)
|
||||
* \param[in] obj The object to update
|
||||
|
@ -92,7 +92,7 @@ extern "C" {
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portBYTE_ALIGNMENT 4
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
@ -41,6 +41,17 @@
|
||||
// Macros
|
||||
#define SET_BITS(var, shift, value, mask) var = (var & ~(mask << shift)) | (value << shift);
|
||||
|
||||
/* Table of UAVO handles registered at compile time */
|
||||
extern struct UAVOData * __start__uavo_handles[] __attribute__((weak));
|
||||
extern struct UAVOData * __stop__uavo_handles[] __attribute__((weak));
|
||||
|
||||
#define UAVO_LIST_ITERATE(_item) \
|
||||
for (struct UAVOData ** _uavo_slot = __start__uavo_handles; \
|
||||
_uavo_slot && _uavo_slot < __stop__uavo_handles; \
|
||||
_uavo_slot++) { \
|
||||
struct UAVOData * _item = *_uavo_slot; \
|
||||
if (_item == NULL) continue;
|
||||
|
||||
/**
|
||||
* List of event queues and the eventmask associated with the queue.
|
||||
*/
|
||||
@ -98,7 +109,6 @@ struct UAVOData {
|
||||
* inside the payload for this UAVO.
|
||||
*/
|
||||
struct UAVOMeta metaObj;
|
||||
struct UAVOData * next;
|
||||
uint16_t instance_size;
|
||||
} __attribute__((packed));
|
||||
|
||||
@ -164,7 +174,6 @@ static void customSPrintf(uint8_t * buffer, uint8_t * format, ...);
|
||||
#endif
|
||||
|
||||
// Private variables
|
||||
static struct UAVOData * uavo_list;
|
||||
static xSemaphoreHandle mutex;
|
||||
static const UAVObjMetadata defMetadata = {
|
||||
.flags = (ACCESS_READWRITE << UAVOBJ_ACCESS_SHIFT |
|
||||
@ -188,9 +197,12 @@ static UAVObjStats stats;
|
||||
int32_t UAVObjInitialize()
|
||||
{
|
||||
// Initialize variables
|
||||
uavo_list = NULL;
|
||||
memset(&stats, 0, sizeof(UAVObjStats));
|
||||
|
||||
// Initialize the uavo handle table
|
||||
memset(__start__uavo_handles, 0,
|
||||
(uintptr_t)__stop__uavo_handles - (uintptr_t)__start__uavo_handles);
|
||||
|
||||
// Create mutex
|
||||
mutex = xSemaphoreCreateRecursiveMutex();
|
||||
if (mutex == NULL)
|
||||
@ -338,9 +350,6 @@ UAVObjHandle UAVObjRegister(uint32_t id,
|
||||
/* 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);
|
||||
@ -374,8 +383,7 @@ UAVObjHandle UAVObjGetByID(uint32_t id)
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Look for object
|
||||
struct UAVOData * tmp_obj;
|
||||
LL_FOREACH(uavo_list, tmp_obj) {
|
||||
UAVO_LIST_ITERATE(tmp_obj)
|
||||
if (tmp_obj->id == id) {
|
||||
found_obj = (UAVObjHandle *)tmp_obj;
|
||||
goto unlock_exit;
|
||||
@ -1019,15 +1027,13 @@ int32_t UAVObjDelete(UAVObjHandle obj_handle, uint16_t instId)
|
||||
*/
|
||||
int32_t UAVObjSaveSettings()
|
||||
{
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
// Save all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
UAVO_LIST_ITERATE(obj)
|
||||
// Check if this is a settings object
|
||||
if (UAVObjIsSettings(obj)) {
|
||||
// Save object
|
||||
@ -1051,15 +1057,13 @@ unlock_exit:
|
||||
*/
|
||||
int32_t UAVObjLoadSettings()
|
||||
{
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
// Load all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
UAVO_LIST_ITERATE(obj)
|
||||
// Check if this is a settings object
|
||||
if (UAVObjIsSettings(obj)) {
|
||||
// Load object
|
||||
@ -1083,15 +1087,13 @@ unlock_exit:
|
||||
*/
|
||||
int32_t UAVObjDeleteSettings()
|
||||
{
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
// Save all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
UAVO_LIST_ITERATE(obj)
|
||||
// Check if this is a settings object
|
||||
if (UAVObjIsSettings(obj)) {
|
||||
// Save object
|
||||
@ -1115,15 +1117,13 @@ unlock_exit:
|
||||
*/
|
||||
int32_t UAVObjSaveMetaobjects()
|
||||
{
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
// Save all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
UAVO_LIST_ITERATE(obj)
|
||||
// Save object
|
||||
if (UAVObjSave( (UAVObjHandle) MetaObjectPtr(obj), 0) ==
|
||||
-1) {
|
||||
@ -1144,15 +1144,13 @@ unlock_exit:
|
||||
*/
|
||||
int32_t UAVObjLoadMetaobjects()
|
||||
{
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
// Load all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
UAVO_LIST_ITERATE(obj)
|
||||
// Load object
|
||||
if (UAVObjLoad((UAVObjHandle) MetaObjectPtr(obj), 0) ==
|
||||
-1) {
|
||||
@ -1173,15 +1171,13 @@ unlock_exit:
|
||||
*/
|
||||
int32_t UAVObjDeleteMetaobjects()
|
||||
{
|
||||
struct UAVOData *obj;
|
||||
|
||||
// Get lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
int32_t rc = -1;
|
||||
|
||||
// Load all settings objects
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
UAVO_LIST_ITERATE(obj)
|
||||
// Load object
|
||||
if (UAVObjDelete((UAVObjHandle) MetaObjectPtr(obj), 0)
|
||||
== -1) {
|
||||
@ -1787,8 +1783,7 @@ void UAVObjIterate(void (*iterator) (UAVObjHandle obj))
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Iterate through the list and invoke iterator for each object
|
||||
struct UAVOData *obj;
|
||||
LL_FOREACH(uavo_list, obj) {
|
||||
UAVO_LIST_ITERATE(obj)
|
||||
(*iterator) ((UAVObjHandle) obj);
|
||||
(*iterator) ((UAVObjHandle) &obj->metaObj);
|
||||
}
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include "$(NAMELC).h"
|
||||
|
||||
// Private variables
|
||||
static UAVObjHandle handle = NULL;
|
||||
static UAVObjHandle handle __attribute__((section("_uavo_handles")));
|
||||
|
||||
/**
|
||||
* Initialize object.
|
||||
|
Loading…
x
Reference in New Issue
Block a user