在以下代码中
SendMessage()
是用户通过USB发送消息的API UsbDataReceived()
是在USB Task()
是init()
中创建的线程,它从SendMessage()
填充的队列中读取并调用低级别usb函数发送消息UsbConnected()
是连接USB设备时由另一个线程调用的函数。我需要实现以下行为:
UsbConnected()
时,必须清空所有队列,如果线程Task()
正在等待队列AnswerQueue
,则必须将其解除阻塞,以便它可以返回等待队列CommandQueue
下面列出了我最佳解决方案的一个示例。
我必须在具有特定订单的两个队列上发布EVENT_QUEUE_RESETTED
消息。
是否有可能以不那么麻烦的方式获得相同的结果?
void UsbhOut(Message_t );
int UsbConnected;
QueueHandle_t MessageQueue;
typedef enum
{
EVENT_QUEUE_RESETTED,
EVENT_NEW_MESSAGE,
EVENT_NEW_ANSWER,
} Event_t;
typedef struct
{
Event_t Event;
uint8_t Data[32];
} CommandQueue_t;
typedef struct
{
Event_t Event;
uint8_t Data[32];
} AnswerQueue_t;
void init(void)
{
MessageQueue = xQueueCreate(sizeof(Message_t), 10);
AnswerQueue = xQueueCreate(sizeof(Message_t), 10);
xTaskCreate(Task, "", 200, NULL, 1, NULL);
}
void UsbConnected(void)
{
CommandEvent.Event = EVENT_QUEUE_RESETTED;
AnswerEvent.Event = EVENT_QUEUE_RESETTED;
UsbConnected = 1;
xQueueReset(MessageQueue);
xQueueReset(AnswerQueue);
/* The order here is fundmental */
xQueueSend(AnswerQueue, &AnswerEvent, 0);
xQueueSend(MessageQeueue, &CommandEvent, 0);
}
int SendMessage(uint8_t * Data)
{
CommandQueue_t CommandEvent;
CommandEvent.Event = EVENT_NEW_MESSAGE;
memcpy(&CommandEvent, Message, 32);
if(xQueueSend(MessageQueue, &CommandEvent, 0) == pdTRUE)
return 0;
else
return -1;
}
void UsbDataReceived(uint8_t * Data)
{
AnswerQueue_t AnswerEvent;
AnswerEvent.Event = EVENT_NEW_ANSWER;
memcpy(AnswerEvent.Data, Data, 32);
xQueueSend(AnswerQueue, &AnswerEvent,0);
}
void Task(void *pvParameters)
{
CommandQueue_t CommandEvent;
AnswerQueue_t AnswerEvent;
CommandCallback_t * Callback;
while(1)
{
xQueueReceive(UsbhStaticData.CommandSenderQueue, &CommandEvent, portMAX_DELAY);
if(CommandEvent.Event == CommandSenderQueueData_t::EVENT_QUEUE_RESETTED)
{
continue;
}
/* Low level Usb fucntion used to send Data */
UsbdSendData(Command.Data);
xQueueReceive(UsbhStaticData.AnswerReceivdQueue, &AnswerEvent, portMAX_DELAY);
if(AnswerEvent.Event == AnswerReceivedQueueData_t::EVENT_QUEUE_RESETTED)
{
continue;
}
else if(AnswerEvent.Event == AnswerReceivedQueueData_t::EVENT_ANSWER_RECEIVED)
{
ParseData(AnswerEvent.Data);
}
}
}
答案 0 :(得分:1)
您可以使用队列集 FreeRTOS Queue Set API 这样你就可以创建一个包含队列和信号量的队列集。您的任务将阻止队列集。然后通过从队列接收消息或递增信号量来解除阻塞。