mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-01 09:24:10 +01:00
Minor updates in object manager and UAVTalk
git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@318 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
parent
4e5ce0c772
commit
34811cc16d
@ -28,14 +28,14 @@
|
||||
// Private constants
|
||||
#define MAX_QUEUE_SIZE 20
|
||||
#define STACK_SIZE 100
|
||||
#define TASK_PRIORITY 100
|
||||
#define TASK_PRIORITY (tskIDLE_PRIORITY + 2)
|
||||
#define REQ_TIMEOUT_MS 500
|
||||
#define MAX_RETRIES 2
|
||||
#define MAX_RETRIES 3
|
||||
|
||||
// Private types
|
||||
|
||||
// Private variables
|
||||
static COMPortTypeDef TelemetryPort;
|
||||
static COMPortTypeDef telemetryPort;
|
||||
static xQueueHandle queue;
|
||||
static xTaskHandle telemetryTaskHandle;
|
||||
|
||||
@ -59,7 +59,7 @@ int32_t TelemetryInitialize(void)
|
||||
queue = xQueueCreate(MAX_QUEUE_SIZE, sizeof(UAVObjEvent));
|
||||
|
||||
// TODO: Get telemetry settings object
|
||||
TelemetryPort = COM_USART1;
|
||||
telemetryPort = COM_USART1;
|
||||
|
||||
// Initialise UAVTalk
|
||||
UAVTalkInitialize(&transmitData);
|
||||
@ -100,34 +100,44 @@ void updateObject(UAVObjHandle obj)
|
||||
UAVObjGetMetadata(obj, &metadata);
|
||||
|
||||
// Setup object depending on update mode
|
||||
if(metadata.telemetryUpdateMode == UPDATEMODE_PERIODIC) {
|
||||
if(metadata.telemetryUpdateMode == UPDATEMODE_PERIODIC)
|
||||
{
|
||||
// Set update period
|
||||
setUpdatePeriod(obj, metadata.telemetryUpdatePeriod);
|
||||
// Connect queue
|
||||
eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
if(UAVObjIsMetaobject(obj)) {
|
||||
if(UAVObjIsMetaobject(obj))
|
||||
{
|
||||
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
|
||||
}
|
||||
UAVObjConnectQueue(obj, queue, eventMask);
|
||||
} else if(metadata.telemetryUpdateMode == UPDATEMODE_ONCHANGE) {
|
||||
}
|
||||
else if(metadata.telemetryUpdateMode == UPDATEMODE_ONCHANGE)
|
||||
{
|
||||
// Set update period
|
||||
setUpdatePeriod(obj, 0);
|
||||
// Connect queue
|
||||
eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
if(UAVObjIsMetaobject(obj)) {
|
||||
if(UAVObjIsMetaobject(obj))
|
||||
{
|
||||
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
|
||||
}
|
||||
UAVObjConnectQueue(obj, queue, eventMask);
|
||||
} else if(metadata.telemetryUpdateMode == UPDATEMODE_MANUAL) {
|
||||
}
|
||||
else if(metadata.telemetryUpdateMode == UPDATEMODE_MANUAL)
|
||||
{
|
||||
// Set update period
|
||||
setUpdatePeriod(obj, 0);
|
||||
// Connect queue
|
||||
eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ;
|
||||
if(UAVObjIsMetaobject(obj)) {
|
||||
if(UAVObjIsMetaobject(obj))
|
||||
{
|
||||
eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events)
|
||||
}
|
||||
UAVObjConnectQueue(obj, queue, eventMask);
|
||||
} else if(metadata.telemetryUpdateMode == UPDATEMODE_NEVER) {
|
||||
}
|
||||
else if(metadata.telemetryUpdateMode == UPDATEMODE_NEVER)
|
||||
{
|
||||
// Set update period
|
||||
setUpdatePeriod(obj, 0);
|
||||
// Disconnect queue
|
||||
@ -146,38 +156,47 @@ static void telemetryTask(void* parameters)
|
||||
int32_t success;
|
||||
|
||||
// Loop forever
|
||||
while(1) {
|
||||
while(1)
|
||||
{
|
||||
// Wait for queue message
|
||||
if(xQueueReceive(queue, &ev, portMAX_DELAY) == pdTRUE) {
|
||||
if(xQueueReceive(queue, &ev, portMAX_DELAY) == pdTRUE)
|
||||
{
|
||||
// Get object metadata
|
||||
UAVObjGetMetadata(ev.obj, &metadata);
|
||||
// Act on event
|
||||
if(ev.event == EV_UPDATED || ev.event == EV_UPDATED_MANUAL) {
|
||||
if(ev.event == EV_UPDATED || ev.event == EV_UPDATED_MANUAL)
|
||||
{
|
||||
// Send update to GCS (with retries)
|
||||
retries = 0;
|
||||
while(retries < MAX_RETRIES && success == -1) {
|
||||
while(retries < MAX_RETRIES && success == -1)
|
||||
{
|
||||
success = UAVTalkSendObject(ev.obj, ev.instId, metadata.ackRequired, REQ_TIMEOUT_MS); // call blocks until ack is received or timeout
|
||||
++retries;
|
||||
}
|
||||
} else if(ev.event == EV_UPDATE_REQ) {
|
||||
}
|
||||
else if(ev.event == EV_UPDATE_REQ)
|
||||
{
|
||||
// Request object update from GCS (with retries)
|
||||
retries = 0;
|
||||
while(retries < MAX_RETRIES && success == -1) {
|
||||
while(retries < MAX_RETRIES && success == -1)
|
||||
{
|
||||
success = UAVTalkSendObjectRequest(ev.obj, ev.instId, REQ_TIMEOUT_MS); // call blocks until update is received or timeout
|
||||
++retries;
|
||||
}
|
||||
}
|
||||
// If this is a metadata object then make necessary telemetry updates
|
||||
if(UAVObjIsMetaobject(ev.obj)) {
|
||||
// If this is a metaobject then make necessary telemetry updates
|
||||
if(UAVObjIsMetaobject(ev.obj))
|
||||
{
|
||||
updateObject(UAVObjGetLinkedObj(ev.obj)); // linked object will be the actual object the metadata are for
|
||||
}
|
||||
}
|
||||
|
||||
/* This blocks the task until there is something on the buffer */
|
||||
if(PIOS_COM_ReceiveBufferUsed(TelemetryPort) > 0)
|
||||
if(PIOS_COM_ReceiveBufferUsed(telemetryPort) > 0)
|
||||
{
|
||||
UAVTalkProcessInputStream(PIOS_COM_ReceiveBuffer(TelemetryPort));
|
||||
} else if(PIOS_COM_ReceiveBufferUsed(COM_USB_HID) > 0)
|
||||
UAVTalkProcessInputStream(PIOS_COM_ReceiveBuffer(telemetryPort));
|
||||
}
|
||||
else if(PIOS_COM_ReceiveBufferUsed(COM_USB_HID) > 0)
|
||||
{
|
||||
UAVTalkProcessInputStream(PIOS_COM_ReceiveBuffer(COM_USB_HID));
|
||||
}
|
||||
@ -195,9 +214,12 @@ static int32_t transmitData(uint8_t* data, int32_t length)
|
||||
COMPortTypeDef OutputPort;
|
||||
|
||||
/* If USB HID transfer is possible */
|
||||
if(!PIOS_USB_HID_CheckAvailable()) {
|
||||
if(!PIOS_USB_HID_CheckAvailable())
|
||||
{
|
||||
OutputPort = COM_USART1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputPort = COM_USB_HID;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#define UAVOBJECTMANAGER_H
|
||||
|
||||
#define UAVOBJ_ALL_INSTANCES 0xFFFF
|
||||
#define UAVOBJ_MAX_INSTANCES 1000
|
||||
|
||||
typedef uint32_t UAVObjHandle;
|
||||
|
||||
@ -35,9 +36,9 @@ typedef uint32_t UAVObjHandle;
|
||||
*/
|
||||
typedef enum {
|
||||
UPDATEMODE_PERIODIC = 0, /** Automatically update object at periodic intervals */
|
||||
UPDATEMODE_ONCHANGE, /** Only update object when its data changes */
|
||||
UPDATEMODE_MANUAL, /** Manually update object, by calling the updated() function */
|
||||
UPDATEMODE_NEVER /** Object is never updated */
|
||||
UPDATEMODE_ONCHANGE = 1, /** Only update object when its data changes */
|
||||
UPDATEMODE_MANUAL = 2, /** Manually update object, by calling the updated() function */
|
||||
UPDATEMODE_NEVER = 3 /** Object is never updated */
|
||||
} UAVObjUpdateMode;
|
||||
|
||||
/**
|
||||
@ -46,11 +47,11 @@ typedef enum {
|
||||
*/
|
||||
typedef struct {
|
||||
int8_t ackRequired; /** Defines if an ack is required for the transactions of this object (1:acked, 0:not acked) */
|
||||
UAVObjUpdateMode telemetryUpdateMode; /** Update mode used by the telemetry module */
|
||||
int8_t telemetryUpdateMode; /** Update mode used by the telemetry module (UAVObjUpdateMode) */
|
||||
int32_t telemetryUpdatePeriod; /** Update period used by the telemetry module (only if telemetry mode is PERIODIC) */
|
||||
UAVObjUpdateMode gcsTelemetryUpdateMode; /** Update mode used by the GCS */
|
||||
int8_t gcsTelemetryUpdateMode; /** Update mode used by the GCS (UAVObjUpdateMode) */
|
||||
int32_t gcsTelemetryUpdatePeriod; /** Update period used by the GCS (only if telemetry mode is PERIODIC) */
|
||||
UAVObjUpdateMode loggingUpdateMode; /** Update mode used by the logging module */
|
||||
int8_t loggingUpdateMode; /** Update mode used by the logging module (UAVObjUpdateMode) */
|
||||
int32_t loggingUpdatePeriod; /** Update period used by the logging module (only if logging mode is PERIODIC) */
|
||||
} __attribute__((packed)) UAVObjMetadata;
|
||||
|
||||
|
@ -370,30 +370,42 @@ int32_t UAVObjInitData(UAVObjHandle obj, const char* init)
|
||||
int32_t UAVObjUnpack(UAVObjHandle obj, uint16_t instId, const uint8_t* dataIn)
|
||||
{
|
||||
ObjectList* objEntry;
|
||||
uint16_t n;
|
||||
|
||||
// Lock
|
||||
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
|
||||
|
||||
// Unpack
|
||||
// Cast handle to object
|
||||
objEntry = (ObjectList*)obj;
|
||||
if (!objEntry->isSingleInstance)
|
||||
|
||||
// If instance does not exist, create it and any other instances before it
|
||||
if (!objEntry->isSingleInstance && !hasInstance(objEntry, instId))
|
||||
{
|
||||
// If instance does not exist, create it
|
||||
if (!hasInstance(objEntry, instId))
|
||||
// Create any missing instances (all instance IDs must be sequential)
|
||||
for (n = objEntry->numInstances; n < instId; ++n)
|
||||
{
|
||||
createInstance(objEntry, instId);
|
||||
if ( createInstance(objEntry, n) < 0 )
|
||||
{
|
||||
// Error, unlock and return
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// Set data
|
||||
if (setInstanceData(objEntry, instId, dataIn) < 0)
|
||||
// Create the actual instance
|
||||
if ( createInstance(objEntry, instId) < 0 )
|
||||
{
|
||||
// Error, unlock and return
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
// Set data
|
||||
if (setInstanceData(objEntry, instId, dataIn) < 0)
|
||||
{
|
||||
memcpy(objEntry->data.instance, dataIn, objEntry->numBytes);
|
||||
// Error, unlock and return
|
||||
xSemaphoreGiveRecursive(mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Fire event
|
||||
@ -824,7 +836,7 @@ int32_t createInstance(ObjectList* obj, uint16_t instId)
|
||||
ObjectInstList* elemEntry;
|
||||
|
||||
// Create new instance
|
||||
if (!obj->isSingleInstance)
|
||||
if (!obj->isSingleInstance && instId < UAVOBJ_MAX_INSTANCES)
|
||||
{
|
||||
elemEntry = (ObjectInstList*)malloc(sizeof(ObjectInstList));
|
||||
if (elemEntry == NULL) return -1;
|
||||
|
@ -78,7 +78,7 @@ int32_t UAVTalkInitialize(UAVTalkOutputStream outputStream)
|
||||
* Request an update for the specified object, on success the object data would have been
|
||||
* updated by the GCS.
|
||||
* \param[in] obj Object to update
|
||||
* \param[in] instId The instance ID of UAVOBJ_ALL_INSTANCES for all instances.
|
||||
* \param[in] instId The instance ID or UAVOBJ_ALL_INSTANCES for all instances.
|
||||
* \param[in] timeout Time to wait for the response, when zero it will return immediately
|
||||
* \return 0 Success
|
||||
* \return -1 Failure
|
||||
@ -91,7 +91,7 @@ int32_t UAVTalkSendObjectRequest(UAVObjHandle obj, uint16_t instId, int32_t time
|
||||
/**
|
||||
* Send the specified object through the telemetry link.
|
||||
* \param[in] obj Object to send
|
||||
* \param[in] instId The instance ID
|
||||
* \param[in] instId The instance ID or UAVOBJ_ALL_INSTANCES for all instances.
|
||||
* \param[in] acked Selects if an ack is required (1:ack required, 0: ack not required)
|
||||
* \param[in] timeoutMs Time to wait for the ack, when zero it will return immediately
|
||||
* \return 0 Success
|
||||
@ -99,11 +99,6 @@ int32_t UAVTalkSendObjectRequest(UAVObjHandle obj, uint16_t instId, int32_t time
|
||||
*/
|
||||
int32_t UAVTalkSendObject(UAVObjHandle obj, uint16_t instId, uint8_t acked, int32_t timeoutMs)
|
||||
{
|
||||
// Make sure a valid instance id is requested
|
||||
if (instId == UAVOBJ_ALL_INSTANCES)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
// Send object
|
||||
if (acked == 1)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user