Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

PIC32MX: passing 64bit in a va_list doesnt work when the kernel is started

Posted by iweindesmedt on February 27, 2017

Hi guys,

When creating a va_list containing a 64bit number, and later on popping this number off, it isnt the same value anymore. Doing this before the kernel is started works like expected, but doing the same thing from within a thread fails.

The routine is something like this: ~~~

define BIGNUMBER ( 1ULL << 63 )

void step2(int ignoreme, valist args){ unsigned long long n = vaarg(args, unsigned long long);

if(n == BIGNUMBER){
    LED_GREEN();
}else{
	LED_RED();
}

}

void step1(int ignoreme, ...){ valist args; vastart(args, ignoreme); step2(ignoreme, args); va_end(args); }

... step1(1234, BIGNUMBER); ~~~

So all this does is passing a 64bit number through var args to a processing function that checks if the received value equals the value that was passed to it.

Attached is a quickly made MPLABX project demonstrating this if it's not clear.

CPU is the PIC32MX695F512L, compiler XC32.

I think it has to be a FreeRTOS problem (or at least in its PIC32MX port) because again, it does work like expected when doing this if FreeRTOS is not used. Also it works when using another RTOS.

Anyone has ideas about what could be wrong?


PIC32MX: passing 64bit in a va_list doesnt work when the kernel is started

Posted by rtel on February 27, 2017

The MZ port had a problem with byte alignment in an interrupt, but not in a task. Is the code you post being called from a task? Please check the stack alignment inside the task is 8-byte aligned and report back. Check the stack alignment on the first instruction in the task - before anything has been pushed to the stack by the compiler.

Attachments

va_list.zip (621249 bytes)

PIC32MX: passing 64bit in a va_list doesnt work when the kernel is started

Posted by iweindesmedt on February 27, 2017

When that code is being called from a task, it doesn't work like expected. When that code is NOT being called from a task, it does work like expected.

The addresses of an int in both the working and broken version: working version: ->a0010b18 (% 8 is 0) broken version: ->a0010b04 (%8 is 4)

Also when declaring the affected functions as static, the problem goes away.

You mention the MZ port, but I'm using the MX port. Not sure if that's related.

Attachments

va_list.zip (621249 bytes)

PIC32MX: passing 64bit in a va_list doesnt work when the kernel is started

Posted by heinbali01 on February 27, 2017

You are showing this test:

~~~ unsigned long long n = vaarg(args, unsigned long long); if(n == BIGNUMBER){ LEDGREEN(); }else{ LED_RED(); } ~~~ But you do not tell what happens. Do you see an exception (alignment), or a red or a green LED?

And also: are you able to make a work-around, by calling va_arg() two times for the type unsigned long?

If I'm not mistaken:

~~~ unsigned long n1 = vaarg( args, unsigned long ); unsigned long n2 = vaarg( args, unsigned long );

if( ffconfigBYTEORDER == pdFREERTOSBIG_ENDIAN )
unsigned long long n = ( ( ( unsigned long long )n1 ) << 32 ) | ( unsigned long long ) n2;
elif( ffconfigBYTEORDER == pdFREERTOSLITTLE_ENDIAN )
unsigned long long n = ( ( ( unsigned long long )n2 ) << 32 ) | ( unsigned long long ) n1;
else
#error ffconfigBYTE_ORDER not defined
endif

~~~

Attachments

va_list.zip (621249 bytes)

PIC32MX: passing 64bit in a va_list doesnt work when the kernel is started

Posted by iweindesmedt on February 27, 2017

What happens: - If the code is running from a task, the LED is RED, meaning the test failed. - If the code is NOT running from a task, the LED is GREEN, meaning the test passed. The LED_ functions arent really relevant here, its just to have visual feedback on the if statement.

No runtime exceptions happen.

I ran your suggestion, but the behaviour is the same (as in: test fails when running from a task, passes when not running from a task). With BIGNUMBER set to 0xFFFFFFFFFFFFFFFFUL, debugger shows the following at the if statement:

From within a task With the 1x unsigned long long: <-- FAILS n = 0xFFFFFFFFA5A5A5A5

With the 2x unsigned long: <-- FAILS n1 = 0xA5A5A5A5 n2 = 0xFFFFFFFF n = 0xFFFFFFFFA5A5A5A5

Could the 0xA5 come from #define tskSTACK_FILL_BYTE ( 0xa5U ) (in tasks:c) ?

From outside a task (before starting kernel) With the 1x unsigned long long: <-- PASSES n = 0xFFFFFFFFFFFFFFFF

With the 2x unsigned long: <-- FAILS n1 = 0x00000000 n2 = 0xFFFFFFFF n = 0xFFFFFFFF00000000

Hope this is clear now

Attachments

va_list.zip (621249 bytes)

PIC32MX: passing 64bit in a va_list doesnt work when the kernel is started

Posted by iweindesmedt on February 28, 2017

Think i found it... in this thread from 2011 http://www.freertos.org/FreeRTOSSupportForumArchive/April2011/freertosFreeRTOS7.0.0PIC32alignmentofstack_4480228.html), Richard suggests to add this line /* Ensure byte alignment is maintained when leaving this function. */ pxTopOfStack--; as the first line in the function pxPortInitialiseStack from tasks.c

In the current version (FreeRTOS 9.0.0), it is already there so I commented it, and the test passed. The 64bit parameter seems to be correctly aligned on the stack now.

I'm not sure which one of the two (pxTopOfStack-- or not) is correct, but in the project I'm using this in (lots of hardware, libraries, modules,...) nothing is breaking so far. This makes me quite confident that this fix is okay, at least for the project I'm working on. But it might not be guaranteed for everyone...

What do you guys think? Is this compiler-related (I'm on XC32 v1.42) or even an error in the PIC32MX port?

Attachments

va_list.zip (621249 bytes)

PIC32MX: passing 64bit in a va_list doesnt work when the kernel is started

Posted by rtel on February 28, 2017

This is what the second post in this thread is referring to. If you put a break point on the first instruction in a task (by which I mean the first assembly instruction - the function entry point - before any function pre-able added by the compiler) then stop on the break point - what is the stack pointer value? The alignment is the important bit.

Attachments

va_list.zip (621249 bytes)

PIC32MX: passing 64bit in a va_list doesnt work when the kernel is started

Posted by iweindesmedt on February 28, 2017

Not too familiar with this but Disassembly view shows: ~~~ !portTASK_FUNCTION(vTaskCode, vParams){ 0x9D007B80: ADDIU SP, SP, -24 <-- BREAKPOINT HERE ... ~~~

and in the Variables view, adding a watch on sp shows: address: 0x74 value: 0xA00017AC

Doing the same with pxTopOfStack-- commented gives: address: 0x74 value: 0xA0001798

Attachments

va_list.zip (621249 bytes)


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




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists