【发布时间】:2015-06-15 03:18:43
【问题描述】:
在下面的代码中
-
SendMessage()是用户调用的 API,用于通过 USB 发送消息 -
UsbDataReceived()是USB接收数据时另一个线程调用的函数 -
Task()是init()中创建的线程,从SendMessage()填充的队列中读取,调用底层usb函数发送消息 -
UsbConnected()是USB设备连接时另一个线程调用的函数。
我需要实现以下行为:
- 一旦发送了一条消息,直到最后一条消息的答复到达时,才能发送新消息
- 当
UsbConnected()被调用时,所有的队列都必须被清空,如果线程Task()正在队列AnswerQueue上等待,它必须被解除阻塞,以便它可以返回等待队列@ 987654330@
下面列出了我的最佳解决方案示例。
我必须以特定顺序在两个队列上发布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);
}
}
}
【问题讨论】:
标签: task message-queue rtos freertos