1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-29 07:24:13 +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:
vassilis 2010-03-15 01:54:25 +00:00 committed by vassilis
parent 4e5ce0c772
commit 34811cc16d
4 changed files with 77 additions and 47 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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)
{