Quality RTOS & Embedded Software

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


the float operation got corruption on zynq

Posted by fanksting on May 17, 2016


I am working on 150825 version of tcp lab code package, and now found an tricky issue, that is, the float operation got corruption when an fpga interrupt occurs periodically whose period is about 3ms. FreeRTOS is running on Zynq. The code snippets are as below:

float operation running in one task:

real32t fGain = 0.0015f; real32t fValue = 0.0f; int32_t iValue = 0;

for (idx = 0; idx < uiLen; idx ++) { iValue = puiSampBuf[idx]; fValue = (real32_t) iValue; pAdcSamp[idx] = fValue * fGain; }

ISR routine:

void adcisr(void *CallbackRef) { XScuGicDisable(pScuGicInst, INTCADCINTID); ... ... ... xQueueSendFromISR(PSMeasEventQueue, &event, &xTaskWoken); XScuGicEnable(pScuGicInst, INTCADCINT_ID);

portYIELDFROMISR(xTaskWoken); } ----------------------------------.

By some logging, I found some corruption, for example, iValue = 6517, but fValue = 1105510016.000000. The float operation is not triggered by interrupt, where they are running independently to each other.

If I add "volatile" on float variable, I notice the corruption occurring frequency go down, but still occur. If I add the macro definition of portTASKUSESFLOATING_POINT() at the beginning of task entry function (not add into all tasks with float operation, but add into the task that capture float corruption), the issue still occur.

Really an tricky issue, I don't know how to handle it so far. Please give me help. Thank you!

the float operation got corruption on zynq

Posted by rtel on May 17, 2016

Search for "Note for GCC (and possibly other compiler) users" on the following page: http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html - I think this is most likely your problem.

xQueueSendFromISR() will call memcpy(), and it is likely the GCC implementation of memcpy() is using FPU registers - hence your corruption.

There are a couple of ways around this:

1) Provide your own basic implementations of the library functions that are used. For example, this file, which is from the official FreeRTOS distribution, contains basic and unoptimised implementations of memcpy, memset and memcmp which you could copy: https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Demo/CORTEXA9Zynq_ZC702/RTOSDemo/src/main.c

2) Use the head revision FreeRTOS code from the repository, found here:

https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/portable/GCC/ARM_CA9/. In that code, if you rename your vApplicationIRQHandler() to vApplicationFPUSafeIRQHandler() (that is the callback function provided by your application) then all interrupts will be given a floating point context too.


the float operation got corruption on zynq

Posted by fanksting on May 20, 2016

It is now quite stable, my compress test has already run stably for about 30 minutes and now is still running, after doing the following updates as you pointed out:

1) update three functions of memcpy(), memcpy() and memset(); 2) set configUSETASKFPU_SUPPORT = 2; 3) update three files, port.c, portASM.c and portmacro.h 4) rename to vApplicationFPUSafeIRQHandler()

When I rename to vApplicationFPUSafeIRQHandler(), I compare the latest version with my version, and found there two additional lines of code in latest version as below:

/* Re-enable interrupts. */ __asm ( "cpsie i" );

I don't understand why they are here and copied to my code, and the float corruption still occur, after I remove the two additional lines, no float corruption occur. So, what's the meaning of that two lines of code? Thanks.

the float operation got corruption on zynq

Posted by rtel on May 20, 2016

Are these lines in the callback function, or in the port layer itself?

The line re-enables interrupts (that much is obvious from the comment ;o) - I think that was always done to allow interrupts to nest, the difference is the callback is now called before interrupts are re-enabled to allow the application writer the option of using nested interrupts or now. If you re-enable interrupts in the interrupt handler callback (by including the line) then interrupts can nest. If you omit the line then interrupts won't nest.

Note that interrupts nesting or not does not change the fact that corruption will occur if the interrupt uses FPU registers. Defining your own memcpy(), etc., prevents the library from doing that though.

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

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

Latest News

FreeRTOS v10.2.1 is available for immediate download. MIT licensed, includes 64-bit RISC-V, NXP Cortex-M33 demo & Nuvoton Cortex-M23 demo.

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

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

Cadence Tensilica Cortes

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