0

I have been working with C on the embedded side and C# on PC side for quite some time. Now I decided to start working with C++ on an embedded target. However the linker tells me that it could not find my function. The complete error looks like this:

   Building target: Cpp_Test.elf
Invoking: MCU G++ Linker
arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -specs=nosys.specs -specs=nano.specs -T"../STM32F429ZITx_FLASH.ld" -Wl,-Map=output.map -Wl,--gc-sections -fno-exceptions -fno-rtti -o "Cpp_Test.elf" @"objects.list"   -lm
Src/freertos.o: In function `StartDefaultTask':
\Cpp_Test\Debug/../Src/freertos.c:127: undefined reference to `calc_values'

The test_cplus.h file looks like this:

#include "stdint.h"

int calc_values();

The test_cplus.cpp file looks like this:

  #include "test_cplus.h"


    #include <iostream>
    using namespace std;

    class Rectangle {
        int width, height;
      public:
        void set_values (int,int);
        int area() {return width*height;}
    };

    void Rectangle::set_values (int x, int y) {
      width = x;
      height = y;
    }


    int calc_values()
    {
        Rectangle rect;
        rect.set_values(1,2);

        int area = rect.area();

        return area;
    }

Could you point me in the right direction?

Edit freertos.c

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os.h"

/* USER CODE BEGIN Includes */     
#include "test_file.h"
#include "test_cplus.h"
/* USER CODE END Includes */

/* Variables -----------------------------------------------------------------*/
osThreadId defaultTaskHandle;

/* USER CODE BEGIN Variables */

/* USER CODE END Variables */

/* Function prototypes -------------------------------------------------------*/
#ifdef __cplusplus
 extern "C" {
#endif
void StartDefaultTask(void const * argument);

extern void MX_USB_DEVICE_Init(void);
extern void MX_FATFS_Init(void);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

#ifdef __cplusplus
}
#endif

/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

/* Hook prototypes */

/* Init FreeRTOS */

void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */
       
  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* Create the thread(s) */
  /* definition and creation of defaultTask */
  osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */
}

/* StartDefaultTask function */
void StartDefaultTask(void const * argument)
{
  /* init code for USB_DEVICE */
  MX_USB_DEVICE_Init();

  /* init code for FATFS */
  MX_FATFS_Init();

  /* USER CODE BEGIN StartDefaultTask */
  /* Infinite loop */
  for(;;)
  {

   run_test();

   calc_values();
    osDelay(100);
  }
  /* USER CODE END StartDefaultTask */
}

/* USER CODE BEGIN Application */

/* USER CODE END Application */
JuliusCaesar
  • 341
  • 3
  • 14
  • 1
    Use C++ syntax, remove the `void` inside the parameter list – smac89 Mar 11 '18 at 22:09
  • 4
    Why does the linker complain about a file called `freertos.c` that you don't show here? Are you trying to link C and C++ code? – UnholySheep Mar 11 '18 at 22:10
  • 2
    Reading this might help: It is my guess anyway as to what your problem is https://stackoverflow.com/questions/3789340/combining-c-and-c-how-does-ifdef-cplusplus-work – Tim Seguine Mar 11 '18 at 22:17
  • Thx guys,first of all i removed the `void`inside the parameter list. I added the contents of the freertos.c in my first post. The project was generated as a c project with STMs code initialiser. I did not modify the freertos.c file except adding the extern c blocks around the function prototypes. But this still doesn't work. Could you give me another hint? – JuliusCaesar Mar 12 '18 at 22:11
  • I think you misunderstood what we were trying to say. Your cpp file is generating a function with a mangled name, the exact name doesn't matter, only that it isn't "calc_values". The C part of your program is looking for a function with exactly that name though. The way to fix that is to tell the cpp compiler that it needs to generate functions compatible with C. You need to modify your cpp stuff to be compatible with C, not the other way around. The extern C block belong either in test_cplus.h or in test_cplus.cpp. The ifdef __cplusplus block is dead code if you put it in a C source file. – Tim Seguine Mar 18 '18 at 21:20

0 Answers0