Quality RTOS & Embedded Software

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



Posted by vincent on July 2, 2013
I have a 485 task to talk slave device, and need wait some time to receive response data from slave device after sending command, i use following delay function to wait 50ms to be sure master can receive all response data from slave.
void delay1ms(void)
uint32_t i = 0;
for (i = 0; i < 30000; i++) ;

but the polling method waster more cpu resource indeed, i change it to vTaskDelay(50) to wait, the result is wrong data or less data received sometimes. I trace it and find that FreeRTOS call taskENTER_CRITICAL to mask all interrupt to protect some piece code. then taskEXIT_CRITICAL to enable all interrupt again. but it may cause 485 interrupt lose in this case. so master can' t receive all data correctly, Is there a way to avoid this ?

apprecaite you in advance.



Posted by Richard on July 2, 2013
It is doubtful that a critical section in FreeRTOS would cause loss of 485 data.

Which port are you using?
What is configCPU_CLOCK_HZ set to?
What is the 485 baud rate?
How is 485 reception handled (DMA, interrupts placing characters in a RAM buffer, or something else)?



Posted by vincent on July 3, 2013
I define following in freertosconfig.h
#define configCPU_CLOCK_HZ ( ( unsigned long ) 120000000 )
#define configTICK_RATE_HZ ( ( portTickType ) 500 )
the 485 baud rate is 19200
485 reception is deal with in interrrupt which handler routine will put receivce byte in RAM buffer.

when i use delay1ms, everything works well



Posted by Dave on July 3, 2013
You are using a slow baud rate and should not have a problem. The length of the critical section is not related in any way to the length of time you delay. In fact, using a delay of 1ms will mean you enter and exit critical sections at least 50 times more than when using your original 50ms delay. I think something else is wrong.

You are calling vTaskDelay(50) to wait 50ms, but 50 only means 50ms when configTICK_RATE_HS is 1000. If you want to wait 50ms then call vTaskDelay(50/portTICK_RATE_MS), which in this case will be the same as calling vTaskDelay(25).

A common architecture has the task using the RS485 block on a semaphore to wait for reception, then the 485 interrupt gives the semaphore when a complete message has been received. That way the task does not use excess CPU time and unblocks immediately and automatically when data has been received so also does not waste time in the blocked state.


Posted by vincent on July 4, 2013
what confuse me is that what will happen once cpu enter into critical section but 485 interrtupt coming, it will be pending ?

if i use a semaphore to wait for reception, it the 485 transfer error, cpu will always wait now . so, time out feature must need.


Posted by Richard on July 4, 2013
Most MCUs will pend interrupts that arrive when inside a critical section. Newer FreeRTOS ports keep a set of interrupt priorities enabled all the time.

Semaphores have a block time. If the semaphore does not become available before the block time expires the task will unblock and the semaphore take function will return an error so the task knows it does not have the semaphore. There is lots of documentation on this on the http://www.FreeRTOS.org website, as well as API documentation with examples of these functions being used, and lots of demos in the download that shows how this is done.



Posted by vincent on July 22, 2013
i check the sample code for serial, and found that GET or PUT one charactor need call more APIs about QUEUE, is this more lower efficient ? my application need get data via 485 in loop,


Posted by vincent on July 22, 2013
Semaphores have a block time. what value the default block time for semaphore is ?


Posted by Richard on July 22, 2013
A lot of demo applications provide a serial driver that is designed to demonstrate queues being used from interrupts and to test the port layer - they are not intended to be examples of how to write an efficient driver and generally queues should not be used to pass individual characters into and out of an interrupt unless the throughput requirements are very low (for example, so handle key presses). It is much better to use a DMA, or to use the interrupt to buffer characters in a circular RAM buffer.

The block time used by a semaphore is passed into the semaphore give and take functions by the application. There is no default: http://www.freertos.org/a00113.html



Posted by vincent on July 22, 2013
yes, you are really right. but putting all characters in a cricular RAM buffer need some time, in general, i use delay to wait for receiving all data via serial, but cpu can't do anything in it. i just wonder to find a way to solve this .

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

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

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 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