Quality RTOS & Embedded Software

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


Extensive critical section in xQueueReceive()

Posted by David Hawks on March 14, 2008
I'm posting to share my recent findings. Under certain circumstances, a call to xQueueReceive() can leave interrupts disabled for an extensive period of time. I am running FreeRTOS on a C8051F120 from Silicon Labs. The processor is running at 100 MHz. Here is what I have observed:

If a queue changes from empty to not empty within xQueueReceive() between the return from to prvIsQueueEmpty() and the call to taskENTER_CRITICAL() a few lines later, the resultant critical section lasts for 140 us instead of the normal 11 us.

I made these measurements by setting a pin high just after the taskENTER_CRITICAL() call and clearing the pin just before the calls to taskYIELD() in both xQueueReceive() and xTaskResumeAll().

RE: Extensive critical section in xQueueReceive()

Posted by Richard on March 14, 2008
So the sequence you are commenting about is this:

1) prvIsQueueEmpty() decides the queue is empty.
2) It is determined that you specified a block time so you enter the if() statement and place yourself on the event list of the queue.
3) An interrupt places something in the queue
4) The critical section is entered - start of measurement.
5) The queue is unlocked - removing the task from the event list again due to the interrupt activity.
6) End of measurement, just before the yield.

So effectively it is the unlocking of the queue that is being measured.

You could try using xQueueAltReceive() instead. This uses the 'traditional' approach used by a lot of RTOSes of just using a critical section over the whole function. The code is simpler so will run much faster, but if measuring the critical section length then it will probably do worse in some circumstances and better in others.

If you need greater temporal accuracy in interrupt handling then you can use an interrupt that is of higher priority than those used by the kernel, this is implemented on some ports but not sure about the 8051 port.


RE: Extensive critical section in xQueueRecei

Posted by David Hawks on March 19, 2008
Thanks for the suggestions.

I could use a high priority interrupt, but I want to be able to post a semaphore from my ISR. The xQueueAltReceive() suggestion is interesting, but I have since found other sections of the code that disable interrupts for greater than 90 us.

Because my comm link hardware contains only a one-byte buffer, I cannot run my link at 115,200 bps with my current interrupt latency. I have slowed my comm link down to 57,600 bps and verified that interrupts are not disabled for longer than 180 us. So far, so good.

RE: Extensive critical section in xQueueRecei

Posted by Richard on March 25, 2008
The current head revision in the SourceForge SVN repository has a new version of the send and receive functions that make less use of critical sections. These will be in the next official release too.


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

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

Latest News

Version 10.1.0 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


FreeRTOS and other embedded software careers at AWS.

FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

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

Xilinx Microblaze and Zynq partner