Skip to main content
SpinKernel
Associate III
March 3, 2022
Solved

Another undefined reference issues with MC SDK and C++

  • March 3, 2022
  • 1 reply
  • 1560 views

I've been trying to develop a C++ application which uses the C based MC SDK (would really be nice if STM would provide a supported wrapper).

I'm getting:

arm-none-eabi-g++ -o "nucleo_demo_y4.elf" @"objects.list" -mcpu=cortex-m4 -T"C:\Users\dustin\repos\wheel\nucleo_demo_y4\STM32CubeIDE\STM32F302R8TX_FLASH.ld" --specs=nosys.specs -Wl,-Map="nucleo_demo_y4.map" -Wl,--cref -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -lstdc++ -lsupc++ -Wl,--end-group
c:\st\stm32cubeide_1.8.0\stm32cubeide\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.9-2020-q2-update.win32_2.0.0.202105311346\tools\arm-none-eabi\bin\ld.exe: ./Application/User/wheel_ctrl.o: in function `Wheel::WheelCtrl::GetParam(Driver::CANDataPacket*)':
C:/Users/dustin/repos/wheel/nucleo_demo_y4/STM32CubeIDE/Debug/../Application/User/wheel_ctrl.cpp:62: undefined reference to `RI_GetRegCommandParser(MCP_Handle_t*, unsigned short)'
collect2.exe: error: ld returned 1 exit status

Searching the .map file I can see the issue, which seems to be a compatibility problem with the way C generates its references and the way C++ does.

.text.RI_GetRegCommandParser
 0x0000000008003cc0 0x8bc ./Application/User/register_interface.o
 0x0000000008003cc0 RI_GetRegCommandParser
 
...
RI_GetRegCommandParser ./Application/User/register_interface.o
 ./Middlewares/MotorControl/mcp.o
RI_GetRegCommandParser(MCP_Handle_t*, unsigned short) ./Application/User/wheel_ctrl.o

As you can see my wheel_ctrl.o references RI_GetRegCommandParser with the whole function call where as C only specifies the name. What's odd is other calls to MCI_ functions like MCI_ExecSpeedRamp and MCI_StartMotor seem to be referenced the same... I've tried a number of ways of calling RI_GetRegCommandParser and they call get the full (MCP_Handle_t*, unsigned short) reference in the .map.

Here's how I'm using it (last of various methods of storing MCP_Handle_t)

 MCP_Handle_t* param = new MCP_Handle_t
 {
 .pTransportLayer = nullptr,
 .rxBuffer = msg->data,
 .txBuffer = msg->data + MCP_ID_SIZE,
 .rxLength = MCP_ID_SIZE,
 .txLength = 0,
 };
 
 uint8_t retval = MCP_CMD_OK;
 retval = RI_GetRegCommandParser(param, MCP_FREE_TX_SPACE);

Really appreciate any advice to try, this is my final error and really trying to get this done so I can test on hardware.

This topic has been closed for replies.
Best answer by SpinKernel

Problem solved! :grinning_face_with_sweat:

The register_interface.h didn't have:

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
...
#ifdef __cplusplus
}
#endif /* __cpluplus */

Ooops! I thought I checked all the headers!

1 reply

SpinKernel
SpinKernelAuthorBest answer
Associate III
March 3, 2022

Problem solved! :grinning_face_with_sweat:

The register_interface.h didn't have:

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
...
#ifdef __cplusplus
}
#endif /* __cpluplus */

Ooops! I thought I checked all the headers!

Andrew Neil
Super User
March 3, 2022

Please mark the solution:

0693W000008y9fZQAQ.png 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.