UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Visitor fetaleksej
Visitor
137 Views
Registered: ‎05-04-2018

Zynq FPU data crushing

Hello, 

I'm using Zynq Z7020 SoC with C++ compiler. 

I was got strange behavior in the following code (brack point line 11):

#include <iostream>

#include "FreeRTOS.h"
#include "task.h"
#include "xparameters.h"


void foo(double first, double second)
{
	if (first != second)
		first += second;
}

void firstTask(void*)
{
	double testValue2 = 0.0;
	while(true) {
		foo(testValue2, testValue2);
		testValue2 += 42.2;
		if (testValue2 > 100)
			testValue2 = 0.0;
	}
}

void secondTask(void*)
{
	double testValue1 = 12.7;
	while(true) {
		vTaskDelay(1000 / portTICK_PERIOD_MS);
		std::cout << testValue1 << std::endl;
	}
}

int main()
{
	xTaskCreate(firstTask, "firstTask", 1024, nullptr, 2, nullptr);
	xTaskCreate(secondTask, "secondTask", 1024, nullptr, 2, nullptr);
	vTaskStartScheduler();
	while(true) continue;
	return 0;
}

The first and second value not equal(first  = 12.7, second = 0.0). Arguments transmit to function foo use registers d0 and d1(see below). This looks like registers weren't restored after interrupt.

From stack call 
brack point here: first += second;

// ----------------------------------------------------------------------------
state from line 18( foo(testValue2, testValue2); )
r11 = 0x001c94b4
[r11, #-12] = 0x001c94a8 
memory: 
    0x001c94a8 : 0x1C94A8 <Hex Integer>
  Address   0 - 3     4 - 7     8 - B     C - F               
  001C94A0  10101010  00000000  00000000  00000000          
  001C94B0  11111111  00000000  00000000  00000000          
  001C94C0  00000000  A5A5A5A5  00000000  80000060          
  001C94D0  001C9454  00000000  001C83A8  001C83A8          
  001C94E0  001C94D0  001C83A0  00000006  00000000          
  001C94F0  00000000  001C94D0  00000000  00000002          
  001C9500  001C84C8  73726966  73615474  0000006B          
  001C9510  00000001  00000000  00000002  00000000          
  001C9520  00000000  00000000  00000000  80001008          
  001C9530  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C9540  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C9550  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C9560  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C9570  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C9580  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C9590  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C95A0  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C95B0  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C95C0  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C95D0  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          

ASM:
          firstTask:
00100d04:   push    {r11,lr}
00100d08:   add     r11, sp, #4
00100d0c:   sub     sp, sp, #16
00100d10:   str     r0, [r11, #-16]
16        	double testValue2 = 0.0;
17        	while(true) {
00100d14:   mov     r2, #0
00100d18:   mov     r3, #0
00100d1c:   strd    r2, r3, [r11, #-12]
18        		foo(testValue2, testValue2);
00100d20:   vldr    d1, [r11, #-12] 
00100d24:   vldr    d0, [r11, #-12]
00100d28:   bl      -116    ; addr=0x00100cbc: foo
19        		testValue2 += 42.2;
00100d2c:   vldr    d16, [r11, #-12]
00100d30:   vldr    d17, [pc, #+40]
00100d34:   vadd.f64 d16, d16, d17
00100d38:   vstr    d16, [r11, #-12]

// ----------------------------------------------------------------------------
state from line 11( first += second; )
r11 = 0x001c949c
[r11, #-12] = 0x001c9490
[r11, #-20] = 0x001c9488
memory: 
    0x001c9488 : 0x1C9488 <Hex Integer>
  Address   0 - 3     4 - 7     8 - B     C - F               
  001C9480  09090909  10101010  00000000  00000000          
  001C9490  66666666  40296666  2000001F  001C94B4          
  001C94A0  10101010  00000000  00000000  00000000          
  001C94B0  11111111  00000000  00000000  00000000          
  001C94C0  00000000  A5A5A5A5  00000000  80000060          
  001C94D0  001C9454  00000000  001C83A8  001C83A8          
  001C94E0  001C94D0  001C83A0  00000006  00000000          
  001C94F0  00000000  001C94D0  00000000  00000002          
  001C9500  001C84C8  73726966  73615474  0000006B          
  001C9510  00000001  00000000  00000002  00000000          
  001C9520  00000000  00000000  00000000  80001008          
  001C9530  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C9540  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C9550  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C9560  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C9570  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C9580  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C9590  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C95A0  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          
  001C95B0  A5A5A5A5  A5A5A5A5  A5A5A5A5  A5A5A5A5          


ASM:
        foo:
    00100cbc:   push    {r11}
    00100cc0:   add     r11, sp, #0
    00100cc4:   sub     sp, sp, #20
    00100cc8:   vstr    d0, [r11, #-12]
    00100ccc:   vstr    d1, [r11, #-20]
    10        	if (first != second)
    00100cd0:   vldr    d17, [r11, #-12]
    00100cd4:   vldr    d16, [r11, #-20]
    00100cd8:   vcmp.f64 d17, d16
    00100cdc:   vmrs    APSR_nzcv, fpscr

I don't have more ideas about what wrong. Maybe somebody has ideas?

0 Kudos
1 Reply
Highlighted
Visitor fetaleksej
Visitor
117 Views
Registered: ‎05-04-2018

Re: Zynq FPU data crushing

I found some information.
https://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html#floating-point

configUSE_TASK_FPU_SUPPORT is set to 2 in FreeRTOSConfig.h.

0 Kudos