1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-26 15:54:15 +01:00

OP-4 Flight/Telemetry Make objectTransaction() fully reentrant

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@547 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
vassilis 2010-04-25 18:34:03 +00:00 committed by vassilis
parent 8f5ecf399d
commit aaef72955e
2 changed files with 20 additions and 10 deletions

View File

@ -149,9 +149,9 @@ void OpenPilotInit()
/* Initialize modules */ /* Initialize modules */
TelemetryInitialize(); TelemetryInitialize();
//ExampleModPeriodicInitialize(); ExampleModPeriodicInitialize();
//ExampleModThreadInitialize(); //ExampleModThreadInitialize();
ExampleModEventInitialize(); //ExampleModEventInitialize();
GpsInitialize(); GpsInitialize();
} }

View File

@ -46,6 +46,7 @@ typedef enum {STATE_SYNC, STATE_OBJID, STATE_INSTID, STATE_DATA, STATE_CS} RxSta
// Private variables // Private variables
static UAVTalkOutputStream outStream; static UAVTalkOutputStream outStream;
static xSemaphoreHandle lock; static xSemaphoreHandle lock;
static xSemaphoreHandle transLock;
static xSemaphoreHandle respSema; static xSemaphoreHandle respSema;
static UAVObjHandle respObj; static UAVObjHandle respObj;
static uint16_t respInstId; static uint16_t respInstId;
@ -71,6 +72,7 @@ int32_t UAVTalkInitialize(UAVTalkOutputStream outputStream)
{ {
outStream = outputStream; outStream = outputStream;
lock = xSemaphoreCreateRecursiveMutex(); lock = xSemaphoreCreateRecursiveMutex();
transLock = xSemaphoreCreateRecursiveMutex();
vSemaphoreCreateBinary(respSema); vSemaphoreCreateBinary(respSema);
xSemaphoreTake(respSema, 0); // reset to zero xSemaphoreTake(respSema, 0); // reset to zero
UAVTalkResetStats(); UAVTalkResetStats();
@ -159,37 +161,45 @@ static int32_t objectTransaction(UAVObjHandle obj, uint16_t instId, uint8_t type
{ {
int32_t respReceived; int32_t respReceived;
// Lock
xSemaphoreTakeRecursive(lock, portMAX_DELAY);
// Send object depending on if a response is needed // Send object depending on if a response is needed
if (type == TYPE_OBJ_ACK || type == TYPE_OBJ_REQ) if (type == TYPE_OBJ_ACK || type == TYPE_OBJ_REQ)
{ {
xSemaphoreTake(respSema, 0); // non blocking call to make sure the value is zero (binary sema) // Get transaction lock (will block if a transaction is pending)
sendObject(obj, instId, type); xSemaphoreTakeRecursive(transLock, portMAX_DELAY);
// Send object
xSemaphoreTakeRecursive(lock, portMAX_DELAY);
respObj = obj; respObj = obj;
respInstId = instId; respInstId = instId;
xSemaphoreGiveRecursive(lock); // need to release lock since the next call will block until a response is received sendObject(obj, instId, type);
respReceived = xSemaphoreTake(respSema, timeoutMs/portTICK_RATE_MS); // lock on object until a response is received (or timeout) xSemaphoreGiveRecursive(lock);
// Wait for response (or timeout)
respReceived = xSemaphoreTake(respSema, timeoutMs/portTICK_RATE_MS);
// Check if a response was received // Check if a response was received
if (respReceived == pdFALSE) if (respReceived == pdFALSE)
{ {
// Cancel transaction
xSemaphoreTakeRecursive(lock, portMAX_DELAY);
xSemaphoreTake(respSema, 0); // non blocking call to make sure the value is reset to zero (binary sema)
respObj = 0;
xSemaphoreGiveRecursive(lock);
xSemaphoreGiveRecursive(transLock);
return -1; return -1;
} }
else else
{ {
xSemaphoreGiveRecursive(transLock);
return 0; return 0;
} }
} }
else if (type == TYPE_OBJ) else if (type == TYPE_OBJ)
{ {
xSemaphoreTakeRecursive(lock, portMAX_DELAY);
sendObject(obj, instId, TYPE_OBJ); sendObject(obj, instId, TYPE_OBJ);
xSemaphoreGiveRecursive(lock); xSemaphoreGiveRecursive(lock);
return 0; return 0;
} }
else else
{ {
xSemaphoreGiveRecursive(lock);
return -1; return -1;
} }
} }