µTasker Forum
µTasker Forum => µTasker general => Topic started by: hervé on November 28, 2010, 05:43:54 PM
-
Hello Mark,
When sending a message to a task we can test if it fits the buffer size allocated, by pointing the message to null.
fnWrite( TASK_TEST, 0, MSG_LENGTH); // test if we can write
How to do when sending to INTERNAL_ROUTE, as the message is used to find the correct heap in this case ?
In fact I don't want to start writing a message if I could not complete ( it will be misinterpreted by the listener)
-
Hi Hervé
This is something that can't be done at the moment but it is quite easy to add:
In the driver function static QUEUE_TRANSFER fnWriteInternal(unsigned char *output_buffer, QUEUE_TRANSFER nr_of_bytes) locate the following code (it is at the end of the subroutine).
ptQUEQue = (struct stQUEQue *)(que_ids[newDestID - 1].input_buffer_control); // set to input control block - write directly to input
nr_of_bytes = fnFillBuf(ptQUEQue, output_buffer, nr_of_bytes);
uTaskerStateChange(NewWakeTask, UTASKER_ACTIVATE);
return (nr_of_bytes);
Now make the following change:
ptQUEQue = (struct stQUEQue *)(que_ids[newDestID - 1].input_buffer_control); // set to input control block - write directly to input
if (output_buffer[MSG_SOURCE_TASK] == 0) { // check on destination's queue
return (ptQUEQue->buf_length - ptQUEQue->chars); // remaining space in queue (before adding new message)
}
nr_of_bytes = fnFillBuf(ptQUEQue, output_buffer, nr_of_bytes);
uTaskerStateChange(NewWakeTask, UTASKER_ACTIVATE);
return (nr_of_bytes);
This will allow you to call using something like:
unsigned char int_message[HEADER_LENGTH];
int_message[MSG_DESTINATION_NODE] = INTERNAL_ROUTE;
int_message[MSG_SOURCE_NODE] = INTERNAL_ROUTE;
int_message[MSG_DESTINATION_TASK] = TASK_DEBUG;
int_message[MSG_SOURCE_TASK] = 0; // setting the source task to zero causes the write to return the available queue size (before any extra data is entered)
return (fnWrite(INTERNAL_ROUTE, int_message, HEADER_LENGTH));
Also the following can be generally used to cause the same return value:
fnEventMessage(TASK_DEBUG, 0, 0);
The only thing to bear in mind is the fact that the value returned may not always be correct if an interrupt were to post a message to the same task just after (or during) the call. This is because the interrupt's message would reduce the available space. Either calls can be protected by disabling interrupts (if it is known that interrupts may also be posting messages to the same task) or else the queue can be increased a little in size and the check be made for larger message size to take in account such a possible occurrance.
Regards
Mark
-
Thank you Mark,
It looks fine.
But as I'm only interested in knowing if I could write or not I will change the test
if (output_buffer[MSG_SOURCE_TASK] == 0) { // check on destination's queue
return (ptQUEQue->buf_length - ptQUEQue->chars); // remaining space in queue (before adding new message)
}
to
if (output_buffer[MSG_SOURCE_TASK] == 0) { // check on destination's queue
return ((ptQUEQue->buf_length - ptQUEQue->chars)>=nr_of_bytes); // check remaining space in queue (before adding new message)
}
Thanks for help again.
-
Hi Mark,
I made the following changes :
#define SIZE_TEST 0xFF
....
if (output_buffer[MSG_SOURCE_TASK] == SIZE_TEST) { // check on destination's queue
return (ptQUEQue->buf_length - ptQUEQue->chars); // remaining space in queue (before adding new message)
}
and also
....
int_message[MSG_SOURCE_TASK] = SIZE_TEST; // setting the source task to SIZE_TEST causes the write to return the available queue size (before any extra data is entered)
because in fact the function fnWrite( INTERNAL_ROUTE....
is called with ucMessage[ MSG_SOURCE_TASK ] = TIMER_EVENT;
which is defined as null....
-
Hi Hervé
Thanks. I didn't realsie that but you are correct.
However I suggest adding the following to uTasker.h
#define CHECK_QUEUE 0x03 // task reference used to check input queues
This is because there are in fact already three task references defined which are handles spcially:
#define TIMER_EVENT 0x00 // message from task 0x00 can only be timer
#define INTERRUPT_EVENT 0x01 // message from task 0x01 can only be interrupt
#define FUNCTION_EVENT 0x02 // message from task 0x02 is a function event, specifying handling by a function rather than a task
This will then keep all of these special task references together.
This means that my reference now looks like this:
if (output_buffer[MSG_SOURCE_TASK] == CHECK_QUEUE) { // check on destination's queue
return (ptQUEQue->buf_length - ptQUEQue->chars); // remaining space in queue (before adding new message)
}
Note that I don't return a check with the value because this returns the remaining queue space (rather than a comparison result). This is then compatible with the return value declaration and also its use is more compatible with the fnWrite() call with zero pointer. The caller can simply compare the returned value with the data size that it wants to send to see whether it fits or not.
It also allows the following to work (which is not possible when a comarison is made since it ois always made with a fixed header length):
if (fnEventMessage(TASK_DEBUG, CHECK_QUEUE, 0) >= message_length) { // check that the message will fit in the receiver's input queue
// send message to task's input queue
}
Regards
Mark
-
Hi Mark,
In fact :
if (fnEventMessage(TASK_DEBUG,CHECK_QUEUE, 0) >= message_length) { // check that the message will fit in the receiver's input queue
// send message to task's input queue
}
-
Hi Hervé
Thanks - corrected in the last post.
Regards
Mark
-
Marc,
I was searching for this solution myself. E need this to check if there is still some space available on my serial port buffer before adding extra messages.
I tried to do this but get not the serial buffer size. This is set to 1024 in the fnOpenUart.
tInterfaceParameters.Rx_tx_sizes.TxQueueSize = 1024; // output buffer size
I always get 37 back. Is there an other solution to check this for the serial port?
I did the request like this: fnEventMessage(TASK_SERIAL, CHECK_QUEUE, 0);
Thanks, Tim
-
Hi
fnEventMessage(TASK_SERIAL, CHECK_QUEUE, 0); can be used to check the amunt of remaining space in the input queue of the tsk named "TASK_SERIAL".
To check the remaining space in the output buffer of a UART you need to use:
fnWrite(UART_Handle, 0, SIZE_TO_CHECK);
and it will return 0 if SIZE_TO_CHECK would not fit.
Note: See debug.c for some examples of its useage since the command line menu can be generated even if there is quite a small UART output buffer by writing the menu as a series of smaller blocks.
Regards
Mark
-
Hi Marc,
This works perfect for me.
Thanks
-
Great!
Thanks for the confirmation.
Mark