How to flush an RTOS queue and prevent further posting on a device disconnect event

freertosrtos

In the following code

  • SendMessage() is the API called by the user to send a message over USB
  • Task() is the thread created in init() that reads the queue and calls the low level usb function to send a message
  • UsbConnected() e UsbDisconnecte() are two functions called by another thread when the a USB device is connected and disconnected respectively.

I want to implement the following behaviour:
– When the UsbDisconnet() function exits, the queue QueueA must be empty and no further messages can be post on the queue by calling SendMessage()

My best solution that uses FreeRTOS API is listed below.

There are two things that I do not like of my solution

  • It uses an xQueueSend() inside a Mutex.
  • The while loop used to clear the queue.

Does a better solution exists?

void UsbhOut(Message_t );
int UsbConnected;
SemaphoreHandle_t MutexA;
QueueHandle_t QueueA;

void init(void)
{
  MutexA = xSemaphoreCreateMutex();
  QueueA = xQueueCreate(sizeof(Message_t), 10);
  UsbConnected = 0;

  xTaskCreate(Task, "", 200, NULL, 1, NULL);
}

void UsbConnected(void)
{
  UsbConnected = 1;
}


int SendMessage(Message_t Message)
{
  xSemaporeTake(MutexA, portMAX_DELAY);

  if(!UsbConnected)
  {
    xSemaphoreGive(MutexA);
    return -1;
  }

  xQueueSend(QueueA, &Message, portMAX_DELAY);
  xSemaporeGive(MutexA);
  return 0;
}

void Task(void * pvParameters)
{
  Message_t Message;
  while(1)
  {
    xQueueReceive(QueueA, &Message, portMAX_DELAY);

    UsbhOut(Message);

  }
}


void UsbDisconneted(void)
{
  Message_t DummyMessage;

  xSemaporeTake(MutexA, portMAX_DELAY);
  UsbConnected = 0;
  xSemaporeGive(MutexA);

  while(xQueueReceive(QueueA, &DummyMessage, 0) == pdTRUE);

}

Best Answer

Have you seen the xQueueReset() API function - it might help: http://www.freertos.org/a00018.html#xQueueReset