Author Topic: Using a Tasks Message Queue to cache messages for later processing  (Read 7624 times)

Offline mhoneywill

  • Full Member
  • ***
  • Posts: 173
    • View Profile
Hi Mark,

I'd like your advice on how to handle the following scenario in uTasker.

I have a task TASK_COMMS_TX which formats a message packet which is then sent out of a serial port using fnWrite(SerialPortID......  as well as sending a packet out on the serial port it also Starts a time-out timer using  

    uTaskerMonoTimer(TASK_COMMS_TX, (DELAY_LIMIT)(0.25*SEC), E_COMMS_TIMEOUT);     // Set Timeout timer for 250ms

I have another task TASK_COMMS_RX which handles the serial reception from the remote device, this task parses the received message. If it receives a valid reply then I want TASK_COMMS_TX to process the next message that may be waiting in its Queue. The reception of a valid message should also stop the above time-out timer using
    
    uTaskerStopTimer(TASK_COMMS_TX);                                     // stop timeout timer

TASK_COMMS_TX is configured to be in the state UTASKER_STOP, so it should only be woken by events.

What I want to do is use the input queue of TASK_COMMS_TX to cache incoming messages, that will be processed either after a valid reply to a previous message is received or a time-out from a previously transmitted message occurs. Am I correct in saying that if TASK_COMMS_TX is in the state UTASKER_SUSPENDED nothing can wake it, where as if its in the state UTASKER_STOP. Any event will wake it including the reception of another packet to be transmitted.

One way around this would be to have another task, to handle the Time out event and switch TASK_COMMS_TX into the UTASKER_STOP state when a timeout occurs, but this seems a bit untidy, 3 Tasks to handle a comms protocol.

Is the above the way to do this or is there a simpler way?

I hope the above makes sense

Cheers

Martin Honeywill

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Using a Tasks Message Queue to cache messages for later processing
« Reply #1 on: August 18, 2009, 02:10:42 AM »
Hi Martin

The UTASKER_SUSPENDED state is used by the monostable timers and doesn't stop a task from receiving events. This state should not (normally) be used by the application.

In fact there is no way to stop a task from being scheduled by events. Also, all events (messages, interrupts, timers etc.) arrive via a FIFO input message queue. This means that if a task is not reading its queue it can not respond to any types of message at all, such as a timer event arriving behind a waiting message.

With these points in mind I think that you can solve it as follows.

1)The rx task (being woken by rx) can also perform the tx timeout on its input queue. This will mean that the tx task can stop reading its own queue if it wants to form a simple message queue. It will however still be scheduled when these messages arrive - its state-event machine can however set a state which simply returns until either the rx task receives a reply or the timeout (the rx task will need to have access to the state event machine to change the state when one of these occur). There is also no reason why these 2 tasks are not put into one file, sharing the state-event machine as local object. The rx task can then activate the tx task (schedule it once by setting its UTASKER_ACTIVATE state) when it can process its next waiting input.

2) When the tx task is scheduled, and its state indicates that it may read its input queue again it can process the next input. In fact it will only have message inputs waiting in this case (no timer or interrupt events) and its input queue is being used simply as a buffer for messages waiting to be sent. Make sure that its input queue is however large enough for the maximum possible messages that it could receive!

Regards

Mark


2)