nobody wrote on Monday, February 28, 2005:
Hi,
I’m running RTOS on a PIC18F8525.
I got serious problems when reading serial data from a magnet-cardreader at 38400 baud through a queue.
There was too much overhead from the taskswitching, and thus I lost data.
The problem was that the serialISR called taskYIELD if the queue contents changed for example from 5 to 6 items.
I modified my serialISR code to test if the queue was emtpy before sending the serial data to the queue, and then at the end of the serialISR only perform a taskYIELD if the queue had been empty and the cQueueSendFromISR sent a taskwoken signal.
this solved my problem by preventing unneccesary calls to taskYIELD.
The idea is that the queue cannot block a task if the queue is not empty, so adding another item to the queue cannot unblock any task since no task is blocked.
I now solved the problem by adding an additional test to the cQueueSendFromISR in queue.c as follows:
if( pxQueue->ucMessagesWaiting < pxQueue->ucLength )
{
prvCopyQueueData( pxQueue, pvItemToQueue );
// If the queue contains more than 1 item, the receiving task cannot be sleeping/waiting for input,
// because there already WAS data on the queue.
// If the queue just received its first item, this could wake a task.
if( pxQueue->ucMessagesWaiting == 1 )
{ // Just sent first item to the queue, thus it is possible a task has been woken
/* If the queue is locked we do not alter the event list. This will
be done when the queue is unlocked later. */
if( pxQueue->cTxLock == queueUNLOCKED )
{
This will only allow the cQueueuSendFromISR to return a taskwoken=TRUE if the contents of the queue just changed from empty to 1 item.
The same thing goes for cQueueReceiveFromISR, which should only be allowed to unblock a task if the contents change from full to full minus 1
Greetings
Paul van der Hulst