Microchip-MPLAB-Harmony / core

Harmony 3 Core
https://onlinedocs.microchip.com/v2/keyword-lookup?keyword=MH3_core&redirect=true
Other
15 stars 12 forks source link

System/Command: linker error when adding C++ #22

Closed youpko closed 1 year ago

youpko commented 2 years ago

When I try to use a .cpp file in my harmony project that utilizes the Command module it won't pass the link step. The link errors are all to the sprintf function.

I get the following error (I shorted the file paths for readability.)

pic32m-ld.exe: build/default/production/_ext/1376093119/sys_command.o: in function `_keyEndProcess':
/firmware/src/config/default/system/command/src/sys_command.c:(.text._keyEndProcess+0x40): undefined reference to `_sprintf_cdnopuxX'
pic32m-ld.exe: build/default/production/_ext/1376093119/sys_command.o: in function `_keyHomeProcess':
/firmware/src/config/default/system/command/src/sys_command.c:(.text._keyHomeProcess+0x58): undefined reference to `_sprintf_cdnopuxX'
pic32m-ld.exe: build/default/production/_ext/1376093119/sys_command.o: in function `SYS_CMD_Tasks':
/firmware/src/config/default/system/command/src/sys_command.c:(.text.SYS_CMD_Tasks+0x118): undefined reference to `_sprintf_cdnopsuxX'
pic32m-ld.exe: /firmware/src/config/default/system/command/src/sys_command.c:(.text.SYS_CMD_Tasks+0x578): undefined reference to `_sprintf_cdnopsuxX'
pic32m-ld.exe: /firmware/src/config/default/system/command/src/sys_command.c:(.text.SYS_CMD_Tasks+0x61c): undefined reference to `_sprintf_cdnopsuxX'

I just created a new harmony project and configured the modules I needed, Tried a compile and that was successful. Then I added some C++ code but compiling doesn't finish any more. Then I removed all the C++ code form the project and compiling was fine again. But adding even an empty .cpp file to the project and the above error popped up again. For completeness sake I added a function in the .cpp file that also called sprintf and called that function from the default app, but that doesn't alter the above error log, it is only the sprinft calls in .c files.

I feel like I missed something obvious but can't find the problem.

The project is for a PIC32MZ1024EFK064 XC32 v3.01 Harmony core v3.9.2

jigneshmoradiya1 commented 2 years ago

@youpko ,

Thank you for reporting the issue.

I am able to reproduce this issue on PIC32MZ1024EFK064 device for C++ project (xc32-g++ compiler). We are working with compiler team to root cause and resolve the issue.

youpko commented 2 years ago

I am glad it is not some stupid mistake on my part.

My knowledge of the C/C++ compile/linker pipeline is really meager. But I discovers that all the C files that use sprintf failed to link because the name the g++ compiler uses is wrong name (name wrangling error of some kind). Calls to sprintf in C++ files are fine. But even weirder is that the all the string calls in the same C file are linked correctly unlike the sprintf call.

Below are the nm output I ran for the sys_command.c file and my own C++ library file.

nm sys_command.o
00000000 t CommandHelp
00000000 t CommandQuit
00000000 t CommandReset
00000000 t DisplayNodeMsg
00000000 t GetCommandCharacter
00000000 t IsCommandReady
00000000 T SYS_CMDIO_ADD
00000000 T SYS_CMDIO_GET_HANDLE
00000000 T SYS_CMD_ADDGRP
00000000 T SYS_CMD_DELETE
00000000 T SYS_CMD_Initialize
00000000 T SYS_CMD_MESSAGE
00000000 T SYS_CMD_PRINT
00000000 T SYS_CMD_READY_TO_READ
00000000 T SYS_CMD_Tasks
         U SYS_CONSOLE_Read
         U SYS_CONSOLE_ReadCountGet
         U SYS_CONSOLE_Status
         U SYS_CONSOLE_Write
         U SYS_RESET_SoftwareReset
00000000 t SendCommandCharacter
00000000 t SendCommandMessage
00000000 t SendCommandPrint
00000000 t _builtinCmdTbl
00000000 b _cmdInitData
00000000 t _keyDownProcess
00000000 t _keyEndProcess
00000000 t _keyHomeProcess
00000000 t _keyLeftProcess
00000000 t _keyRightProcess
00000000 t _keyUpProcess
         U _sprintf_cdnopsuxX
         U _sprintf_cdnopuxX
00000000 b _usrCmdTbl
         U calloc
00000008 b cmdIODevList
         U free
00000038 t keySeqTbl
         U memset
00000080 b printBuff
00000004 b printBuffPtr
         U strchr
         U strcmp
         U strcpy
         U strlen
         U strncmp
         U strncpy
         U strtok
00000024 T sysConsoleApi
         U vsnprintf
nm Library.o
         U DRV_SPI_Close
         U DRV_SPI_Open
         U DRV_SPI_TransferSetup
         U DRV_SPI_WriteTransfer
         U SYS_CMD_ADDGRP
         U SYS_CMD_MESSAGE
         U _Unwind_SjLj_Register
         U _Unwind_SjLj_Resume
         U _Unwind_SjLj_Unregister
00000000 T _ZN3Lib6WS281211init_ws2812Ev
00000000 T _ZN3Lib6WS281214commandHandlerEP19SYS_CMD_DEVICE_NODEiPPc
00000000 B _ZN3Lib6WS28124ledsE
00000000 t _ZN3Lib6WS2812L6cmdTblE
         U _ZN3Lib7WS2812B6setRGBEhj
         U _ZN3Lib7WS2812B7fillRGBEj
         U _ZN3Lib7WS2812BC1Ej
         U _ZN3Lib7WS2812BD0Ev
         U _ZdlPvj
         U _Znwj
         U __gxx_personality_sj0
00000000 T library_init
         U memcmp
         U sprintf
         U strlen
         U strtoul
jigneshmoradiya1 commented 2 years ago

Project builds successfully with -mno-smart-io xc32-gcc option. image

youpko commented 2 years ago

I added the option and the project compiles fine now.

What is the effect of this parameter? are there things I should keep in mind using this fix?

jigneshmoradiya1 commented 2 years ago

smart-io option is not available for C++ as it is not implemented in C++ libraries.

youpko commented 2 years ago

I have not been able to test the project effectively have problem with MPLAB IDE and programming (MPLAB IPE programs just fine but hard to debug without a debugger).

But I found another issue with the command module. When calling SYS_CMD_PRINT the MCU throws a _simple_tbl_refill_exception After stepping throught the code it happens at:

 sys_command.c:561:
len = vsnprintf(tmpBuf, SYS_CMD_PRINT_BUFFER_SIZE, format, args);

On the vsnprintf the mcu jumps to the void __attribute__((noreturn)) _simple_tlb_refill_exception_handler(void) in the exception.c file.

youpko commented 2 years ago

I found some more information why have trouble starting the debugger. I installed the latest XC32 and the loading of symbols is really slow so when I press the Program+debug button i have to wait for >5minutes, but after that it works like expected. On the microchip forum I saw a post that some one else has a similar problem, I have to try the older version of XC32 to see if the problem exists there as well.

youpko commented 2 years ago

Also found an other bug in the SYS_Command. If i open the serial port and just press [enter] on the computer a stack overflows occurs. With the debugger in the FreeRTOS stack overflow hook I see that the it occurs in the SYS_CMD_TASK.

And that was with default settings in harmony. To remedy this issue i just doubled the RTOS stack size in the harmony configuration.

weehaukang commented 1 year ago

I have not been able to test the project effectively have problem with MPLAB IDE and programming (MPLAB IPE programs just fine but hard to debug without a debugger).

But I found another issue with the command module. When calling SYS_CMD_PRINT the MCU throws a _simple_tbl_refill_exception After stepping throught the code it happens at:

sys_command.c:561:
len = vsnprintf(tmpBuf, SYS_CMD_PRINT_BUFFER_SIZE, format, args);

On the vsnprintf the mcu jumps to the void __attribute__((noreturn)) _simple_tlb_refill_exception_handler(void) in the exception.c file.

I am also experiencing the same issues after migrating my C++ project from harmony v2 to v3. First, the compiler produced "undefined reference to `_sprintf_cdnopuxX' when compiling, but the problem went away after adding -mno-smart-io. The next problem is the program crashed at _simple_tlb_refill_exception_handler(void) at n = vsnprintf(buffer, sizeof(buffer)-1, format, args); only when floating point variables are passed as parameters.

Do you know the solution to this problem?

youpko commented 1 year ago

It has been a while so I don't remember all the details.

Do you use FreeRTOS? If so did you enable the Floating point support for the task that calls the vsnprintf? If I remember correctly you need to call portTASK_USES_FLOATING_POINT at the beginning of the task.

jigneshmoradiya1 commented 1 year ago

Yes, FreeRTOS floating point context is supported in H3. User has to enable "Use Floating point unit (FPU) context" MCC configuration option to generate portTASK_USES_FLOATING_POINT() at the beginning of the task.

vishalnxt commented 1 year ago

@youpko , we are closing this issue. Please feel free to open it again if the issue still exists.