task - How to interrupt an xQueueReceive() API in FreeRTOS? -
in following code
sendmessage()
api called user send message on usbusbdatareceived()
function called thread when data received on usbtask()
thread created ininit()
reads queue filledsendmessage()
, calls low level usb function send messageusbconnected()
function called thread when usb device connected.
i need implement following behaviour:
- once message has been sent, no new messages can sent when answer last message has arrived
- when
usbconnected()
called, of queues must emptied , if threadtask()
waiting on queueanswerqueue
, has unblocked can go wait on queuecommandqueue
an example of best solution listed below.
i had post event_queue_resetted
message on both of queues particular order.
is possible achieve same result in less cumbersome way?
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); /* order here 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 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); } } }
you use queue sets freertos queue set api way create queue set containing queue , semaphore. task block on queue set. unblocked either receiving message queue or incrementing semaphore.
Comments
Post a Comment