# the float operation got corruption on zynq

**URL:** <https://forums.freertos.org/t/the-float-operation-got-corruption-on-zynq/5978>\
**Category:** Kernel\
**Created:** [May 17, 2016, 12:16pm UTC](https://forums.freertos.org/t/the-float-operation-got-corruption-on-zynq/5978 "2016-05-17T12:16:28Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [May 17, 2016, 12:16pm UTC](https://forums.freertos.org/t/the-float-operation-got-corruption-on-zynq/5978/1 "2016-05-17T12:16:28Z")

</div>

**[fanksting](https://sourceforge.net/u/fanksting/)** wrote on [Tuesday, May 17, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/93769bf6/#1f8e):

hello,

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:

real32\_t fGain = 0.0015f;  
real32\_t 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 adc\_isr(void \*CallbackRef)  
{  
XScuGic\_Disable(pScuGicInst, INTC\_ADC\_INT\_ID);  
… … …  
xQueueSendFromISR(PSMeasEventQueue, &event, &xTaskWoken);  
XScuGic\_Enable(pScuGicInst, INTC\_ADC\_INT\_ID);

portYIELD\_FROM\_ISR(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 portTASK\_USES\_FLOATING\_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!

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [May 17, 2016, 12:37pm UTC](https://forums.freertos.org/t/the-float-operation-got-corruption-on-zynq/5978/2 "2016-05-17T12:37:04Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Tuesday, May 17, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/93769bf6/#1f8e/d245):

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](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/CORTEX\_A9\_Zynq\_ZC702/RTOSDemo/src/main.c](https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Demo/CORTEX_A9_Zynq_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/](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.

Regards.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [May 20, 2016, 2:10pm UTC](https://forums.freertos.org/t/the-float-operation-got-corruption-on-zynq/5978/3 "2016-05-20T14:10:57Z")

</div>

**[fanksting](https://sourceforge.net/u/fanksting/)** wrote on [Friday, May 20, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/93769bf6/#9aba):

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 configUSE\_TASK\_FPU\_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.

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [May 20, 2016, 2:13pm UTC](https://forums.freertos.org/t/the-float-operation-got-corruption-on-zynq/5978/4 "2016-05-20T14:13:13Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Friday, May 20, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/93769bf6/#9aba/90f0):

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.
