En el siguiente código
-
SendMessage()
es la API llamada por el usuario para enviar un mensaje a través de USB -
Task()
es el hilo creado eninit()
que lee la cola y llama a la función usb de bajo nivel para enviar un mensaje -
UsbConnected()
eUsbDisconnecte()
son dos funciones llamadas por otro hilo cuando un dispositivo USB está conectado y desconectado respectivamente.
Quiero implementar el siguiente comportamiento:
- Cuando la función UsbDisconnet()
sale, la cola QueueA
debe estar vacía y no se pueden publicar más mensajes en la cola llamando a SendMessage()
Mi mejor solución que utiliza FreeRTOS API se lista a continuación.
Hay dos cosas que no me gustan de mi solución
- Utiliza un
xQueueSend()
dentro de un Mutex. - El bucle while se utiliza para borrar la cola.
¿Existe una mejor solución?
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);
}