Skip to content

Commit b0b70c5

Browse files
committed
telemetry: throttled obj can only be in queue once
This means that different objects using the link get a fair share when there's congestion.
1 parent 570afa3 commit b0b70c5

4 files changed

Lines changed: 45 additions & 11 deletions

File tree

flight/Modules/System/systemmod.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,7 @@ static int32_t eventPeriodicCreate(UAVObjEvent* ev, UAVObjEventCallback cb, stru
950950
objEntry->evInfo.ev.obj = ev->obj;
951951
objEntry->evInfo.ev.instId = ev->instId;
952952
objEntry->evInfo.ev.event = ev->event;
953+
objEntry->evInfo.ev.throttle = NULL;
953954
objEntry->evInfo.cb = cb;
954955
objEntry->evInfo.queue = queue;
955956
objEntry->updatePeriodMs = periodMs;

flight/Modules/Telemetry/telemetry.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,8 @@ static void processObjEvent(telem_t telem, UAVObjEvent * ev)
599599
EV_NONE);
600600
}
601601
}
602+
603+
UAVObjUnblockThrottle(ev->throttle);
602604
}
603605

604606
static bool sendRequestedObjs(telem_t telem)

flight/UAVObjects/inc/uavobjectmanager.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,11 @@ typedef enum {
116116
*/
117117
typedef struct {
118118
UAVObjHandle obj;
119-
uint16_t instId;
120119
UAVObjEventType event;
121-
} UAVObjEvent;
120+
struct ObjectEventEntryThrottled *throttle;
122121

122+
uint16_t instId;
123+
} UAVObjEvent;
123124

124125
/**
125126
* Event callback, this function is called when an event is invoked. The function
@@ -205,6 +206,7 @@ int32_t UAVObjDisconnectQueue(UAVObjHandle obj_handle, struct pios_queue *queue)
205206
int32_t UAVObjConnectQueueThrottled(UAVObjHandle obj_handle, struct pios_queue *queue, uint8_t eventMask, uint16_t interval);
206207
int32_t UAVObjConnectCallback(UAVObjHandle obj_handle, UAVObjEventCallback cb, void *cbCtx, uint8_t eventMask);
207208
int32_t UAVObjConnectCallbackThrottled(UAVObjHandle obj_handle, UAVObjEventCallback cb, void *cbCtx, uint8_t eventMask, uint16_t interval);
209+
void UAVObjUnblockThrottle(struct ObjectEventEntryThrottled *throttled);
208210
int32_t UAVObjDisconnectCallback(UAVObjHandle obj_handle, UAVObjEventCallback cb, void *cbCtx);
209211
void UAVObjUpdated(UAVObjHandle obj);
210212
void UAVObjInstanceUpdated(UAVObjHandle obj_handle, uint16_t instId);

flight/UAVObjects/uavobjectmanager.c

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ extern uintptr_t pios_uavo_settings_fs_id;
5757
*/
5858

5959
/** opaque type for instances **/
60-
typedef void* InstanceHandle;
60+
typedef void* InstanceHandle;
6161

6262
struct ObjectEventEntry {
6363
union {
@@ -76,6 +76,7 @@ struct ObjectEventEntryThrottled {
7676

7777
uint32_t due;
7878
uint16_t interval;
79+
volatile uint8_t inhibited;
7980
};
8081

8182
/*
@@ -130,7 +131,7 @@ struct UAVOSingle {
130131
struct UAVOData uavo;
131132

132133
uint8_t instance0[];
133-
/*
134+
/*
134135
* Additional space will be malloc'd here to hold the
135136
* the data for this instance.
136137
*/
@@ -140,7 +141,7 @@ struct UAVOSingle {
140141
struct UAVOMultiInst {
141142
struct UAVOMultiInst * next;
142143
uint8_t instance[];
143-
/*
144+
/*
144145
* Additional space will be malloc'd here to hold the
145146
* the data for this instance.
146147
*/
@@ -345,7 +346,7 @@ static struct UAVOData * UAVObjAllocMulti(uint32_t num_bytes)
345346
* \return Object handle, or NULL if failure.
346347
* \return
347348
*/
348-
UAVObjHandle UAVObjRegister(uint32_t id,
349+
UAVObjHandle UAVObjRegister(uint32_t id,
349350
int32_t isSingleInstance, int32_t isSettings,
350351
uint32_t num_bytes,
351352
UAVObjInitializeCallback initCb)
@@ -1293,7 +1294,7 @@ int32_t UAVObjGetInstanceDataField(UAVObjHandle obj_handle, uint16_t instId, voi
12931294
if ((size + offset) > obj->instance_size) {
12941295
goto unlock_exit;
12951296
}
1296-
1297+
12971298
// Set data
12981299
memcpy(dataOut, InstanceData(instEntry) + offset, size);
12991300
}
@@ -1485,8 +1486,8 @@ void UAVObjSetGcsTelemetryUpdateMode(UAVObjMetadata* metadata, UAVObjUpdateMode
14851486
/**
14861487
* Check if an object is read only
14871488
* \param[in] obj The object handle
1488-
* \return
1489-
* \arg 0 if not read only
1489+
* \return
1490+
* \arg 0 if not read only
14901491
* \arg 1 if read only
14911492
* \arg -1 if unable to get meta data
14921493
*/
@@ -1724,31 +1725,48 @@ static int32_t pumpOneEvent(UAVObjEvent msg, void *obj_data, int len) {
17241725
struct ObjectEventEntry *event;
17251726
LL_FOREACH(msg.obj->next_event, event) {
17261727
if (event->eventMask == 0
1727-
|| (event->eventMask & msg.event) != 0) {
1728+
|| (event->eventMask & msg.event) != 0) {
1729+
struct ObjectEventEntryThrottled *throtInfo =
1730+
(struct ObjectEventEntryThrottled *) event;
1731+
17281732
if (event->hasThrottle) {
17291733
// This is a throttled event (triggered with a spacing of at least "interval" ms)
17301734
struct ObjectEventEntryThrottled *throtInfo =
17311735
(struct ObjectEventEntryThrottled *) event;
17321736

17331737
uint32_t now = PIOS_Thread_Systime();
1734-
if (throtInfo->due > now){
1738+
if (throtInfo->due > now) {
17351739
continue;
17361740
}
17371741

17381742
// Set time for next callback
17391743
throtInfo->due += ((now - throtInfo->due) / throtInfo->interval + 1) * throtInfo->interval;
1744+
1745+
if (throtInfo->inhibited) {
1746+
continue;
1747+
}
1748+
1749+
msg.throttle = throtInfo;
1750+
} else {
1751+
msg.throttle = NULL;
17401752
}
17411753

17421754
// Invoke callback (from event task) if a valid one is registered
17431755
if (event->cb) {
17441756
// invoke callback directly; callbacks must be well behaved
17451757
invokeCallback(event, &msg, obj_data, len);
17461758
} else if (event->cbInfo.queue) {
1759+
if (event->hasThrottle) {
1760+
throtInfo->inhibited = 1;
1761+
}
17471762
// Send to queue if a valid queue is registered
17481763
// will not block
17491764
if (PIOS_Queue_Send(event->cbInfo.queue, &msg, 0) != true) {
17501765
stats.lastQueueErrorID = UAVObjGetID(msg.obj);
17511766
++stats.eventQueueErrors;
1767+
if (event->hasThrottle) {
1768+
throtInfo->inhibited = 0;
1769+
}
17521770
}
17531771
}
17541772

@@ -2154,6 +2172,17 @@ uint32_t UAVObjIDByIndex(uint8_t index)
21542172
return 0;
21552173
}
21562174

2175+
/**
2176+
* Unblocks a throttled event-- allows it to be inserted into queues once
2177+
* again.
2178+
*/
2179+
void UAVObjUnblockThrottle(struct ObjectEventEntryThrottled *throttled)
2180+
{
2181+
if (throttled) {
2182+
throttled->inhibited = 0;
2183+
}
2184+
}
2185+
21572186
/**
21582187
* Registers a new UAVO instance created callback
21592188
*/

0 commit comments

Comments
 (0)