Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

xQueueSendFromISR() and xQueueReceive()

Posted by Vagni on September 28, 2009
I am using FreeRTOS v4.6.1 on my STR75x-based application with IAR EW-ARM v4.41A.

I have an UART-ISR with the following code:



static PDU_STRUCT RxBuf;

static xQueueHandle xQueueRxPdu; // a queue capable of containing pointers to PDU_STRUCT structures

__arm void UART1_Isr(void)

{

portBASE_TYPE xTaskWokenByPost = pdFALSE;

PDU_STRUCT *pRxBuf = &RxBuf;

[...]

if( Received_Valid_PDU )

{

// post the received PDU

xTaskWokenByPost = xQueueSendFromISR( xQueueRxPdu, (void *)&pRxBuf, xTaskWokenByPost );

}

[...]

/* If a task was woken by a message being received
then we may need to switch to another task. */

portEND_SWITCHING_ISR( xTaskWokenByPost );

}



Then I have one my task with the following code:


// coda della PDU ricevuta

static xQueueHandle xQueueRxPdu;


void UartTask( void *pvParameters )

{

portTickType xLastWakeTime,xNextWakeTime;

PDU_STRUCT *pRxPdu;

// Create a queue capable of containing 2 pointers to PDU_STRUCT structures.

xQueueRxPdu = xQueueCreate( 2, sizeof( PDU_STRUCT * ) );

// task loop

for( ; ; Wdog() )

{

// wait for a message

xLastWakeTime = xTaskGetTickCount();

xNextWakeTime = xLastWakeTime + 200;

if( QueueReceive( xQueueRxPdu, &pRxPdu, xNextWakeTime ) == pdTRUE )

{

// received message processing

}

else

{

// do something else

}



}

}



So my task waits for a received message for max 200 ticks (200 msec), then does something else and returns to wait for a received message. Both the message processing time and the alternative processing time are less than 1 msec.

There is an external unit sending a message every 200 msec.

The above task has priority 2, the same of two other my task. Also there is another task with priority 3.

After some minutes or some hours or some days of continuous properly working (this is random time) my task suddenly stops receiving messages from the external unit. I can recover the issue only with an application reset.

What happens if xQueueSendFromISR() and portEND_SWITCHING_ISR() are called when my task is just running and not waiting for a message from the queue? In this case, when my task returns to call xQueueReceive() is it assured to find in the queue the message queued before by the UART_ISR?

Thank you for your help.











RE: xQueueSendFromISR() and xQueueReceive()

Posted by Dave on September 28, 2009
You say you are using IAR compiler, I presume you have an assembly code entry point for the ISR?

xQueueReceive() takes an a relative block time. If you add 200 to the block time on each call the task will block for an extra 200ms each time. 200ms the first time you call it, 400ms the next, 600ms the next, etc. You should not add 200 to the block time because it is just that, a block time not a wake time.

As you are queueing pointers to structures are you sure that the structure being pointed to is not be accessed by the task and the interrupt simultaneously?

RE: xQueueSendFromISR() and xQueueReceive()

Posted by Vagni on September 28, 2009
Yes, you are right.

Threre is an assembly code entry point for the ISR, it is the same for all the IRQ channels inside the STR75x ARM7 microcontroller.

Also, there is a copy error on the task code I reported. The right and actual code for calling xQueueReceive() is the following:

if( xQueueReceive( xQueueRxPdu, &pRxPdu, 200) == pdTRUE )

{

// received message processing

}

else

{

// do something else

}

So the task will always block for 200ms.

What you say regarding to the possible simultaneous access to the same message structure make me think that is maybe wrong to wait for message a time equal to the sending period on the external unit.

But the external unit is sending the same message every 200ms, so the message structure is overwritten with the same data bytes. If task accesses to the message structure while the subsequent message reception is just started, the received message should not be lost. Or not?

If the task should loose a message, it should always receive the subsequent one, not start to loose every message.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS