Page 1 of 1

ESP IDF and C++ linker problem with xRingbufferReceive

Posted: Mon Feb 27, 2017 9:38 am
by peter_
Hello together,
I want to port the Infrared Nec example to CPP. I have a linker problem when I include the xRingbufferReceive function.
I have made a small example with the Hello World program.

Code: Select all


#include <stdio.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"

#include "driver/rmt.h"
#include "driver/periph_ctrl.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "freertos/ringbuf.h"

void hello_task(void *pvParameter)
{
    while(1)
    {
        RingbufHandle_t rb = NULL;
        size_t rx_size = 0;
        rmt_item32_t* item = (rmt_item32_t*) xRingbufferReceive(rb, &rx_size, 1000);
        vTaskDelay(1000 / portTICK_PERIOD_MS);

    }
}
extern "C"
{
void app_main()
{
    nvs_flash_init();
    xTaskCreate(&hello_task, "hello_task", 2048, NULL, 5, NULL);
}
}
If I compile this, I get a linker error:

LD hello-world.elf
/home/peter/Eigene_dateien/Programmieren/ESP32/hello_world/build/main/libmain.a(hello_world_main.o):(.literal._Z10hello_taskPv+0x0): undefined reference to `xRingbufferReceive(void*, unsigned int*, unsigned int)'
/home/peter/Eigene_dateien/Programmieren/ESP32/hello_world/build/main/libmain.a(hello_world_main.o): In function `hello_task(void*)':
/home/peter/Eigene_dateien/Programmieren/ESP32/hello_world/main/./hello_world_main.cpp:30: undefined reference to `xRingbufferReceive(void*, unsigned int*, unsigned int)'
collect2: error: ld returned 1 exit status

I have just looked into the ringbuf header and I have seen, that there is no extern "C" guard. Can I add it without further problems?

Regards
Peter

Re: ESP IDF and C++ linker problem with xRingbufferReceive

Posted: Mon Feb 27, 2017 10:06 am
by rudi ;-)
peter_ wrote:Hello together,
I want to port the Infrared Nec example to CPP. I have a linker problem when I include the xRingbufferReceive function.
I have made a small example with the Hello World program.

Code: Select all


#include <stdio.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"

#include "driver/rmt.h"
#include "driver/periph_ctrl.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "freertos/ringbuf.h"

void hello_task(void *pvParameter)
{
    while(1)
    {
        RingbufHandle_t rb = NULL;
        size_t rx_size = 0;
        rmt_item32_t* item = (rmt_item32_t*) xRingbufferReceive(rb, &rx_size, 1000);
        vTaskDelay(1000 / portTICK_PERIOD_MS);

    }
}
extern "C"
{
void app_main()
{
    nvs_flash_init();
    xTaskCreate(&hello_task, "hello_task", 2048, NULL, 5, NULL);
}
}
If I compile this, I get a linker error:

LD hello-world.elf
/home/peter/Eigene_dateien/Programmieren/ESP32/hello_world/build/main/libmain.a(hello_world_main.o):(.literal._Z10hello_taskPv+0x0): undefined reference to `xRingbufferReceive(void*, unsigned int*, unsigned int)'
/home/peter/Eigene_dateien/Programmieren/ESP32/hello_world/build/main/libmain.a(hello_world_main.o): In function `hello_task(void*)':
/home/peter/Eigene_dateien/Programmieren/ESP32/hello_world/main/./hello_world_main.cpp:30: undefined reference to `xRingbufferReceive(void*, unsigned int*, unsigned int)'
collect2: error: ld returned 1 exit status

I have just looked into the ringbuf header and I have seen, that there is no extern "C" guard. Can I add it without further problems?

Regards
Peter
hi beda,
principal have no problem with your code
( have delete extern "C" )

Code: Select all


#include <stdio.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"

#include "driver/rmt.h"
#include "driver/periph_ctrl.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "freertos/ringbuf.h"

void hello_task(void *pvParameter)
{
    while(1)
    {
        RingbufHandle_t rb = NULL;
        size_t rx_size = 0;
        rmt_item32_t* item = (rmt_item32_t*) xRingbufferReceive(rb, &rx_size, 1000);
        vTaskDelay(1000 / portTICK_PERIOD_MS);

    }
}

 void app_main()
{
    nvs_flash_init();
    xTaskCreate(&hello_task, "hello_task", 2048, NULL, 5, NULL);
}


$ make -j5 all
CC test_rb.o
C:/testings/ringbuffer/main/test_rb.c: In function 'hello_task':
C:/testings/ringbuffer/main/test_rb.c:22:23: warning: unused variable 'item' [-Wunused-variable]
rmt_item32_t* item = (rmt_item32_t*) xRingbufferReceive(rb, &rx_size, 1000);
^
AR libmain.a
LD ringbuffertest.elf
esptool.py v2.0-beta1
To flash all build output, run 'make flash' or:
python /c/sdk32/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port com27 --baud 921600 --before default_reset --after hard_reset write_flash -u --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 /c/testings/ringbuffer/build/bootloader/bootloader.bin 0x10000 /c/testings/ringbuffer/build/ringbuffertest.bin 0x8000 /c/testings/ringbuffer/build/partitions_singleapp.bin

cause
the extern "C" { void app_main() ... } makes at my desk some problems
usually it would be without the { }this

Code: Select all


extern "C" void app_main()
{
    nvs_flash_init();
    xTaskCreate(&hello_task, "hello_task", 2048, NULL, 5, NULL);
}
me-no-dev wrote: this is probably cpp file so you need to add extern "C" before void app_main()
info

hope this helps

best wishes
rudi ;-)

Re: ESP IDF and C++ linker problem with xRingbufferReceive

Posted: Mon Feb 27, 2017 10:22 am
by ESP_igrr
Thanks for pointing this out. When we have added ringbuf.h to FreeRTOS, we have forgot to include c++ guards, like

Code: Select all

#ifdef __cplusplus
extern "C" {
#endif

// rest of the file


#ifdef __cplusplus
}
#endif

As a workaround, you can change the include directive as follows:

Code: Select all

extern "C" {
#include "freertos/ringbuf.h"
}

Re: ESP IDF and C++ linker problem with xRingbufferReceive

Posted: Mon Feb 27, 2017 10:26 am
by peter_
Hello Rudi,
thanks for testing.
But if I see it right you have tested it with a .c file. My problem only occurs when I use the .cpp ending.
If I don't have the extern "C" before the app_main() it don't compiles.
(I think the reason is that this function is called by a C function.)
Unfortunately it is very new for me to mix C and C++ so maybe I'm totally wrong.
Regards
Peter

Re: ESP IDF and C++ linker problem with xRingbufferReceive

Posted: Mon Feb 27, 2017 10:36 am
by rudi ;-)
peter_ wrote:Hello Rudi,
thanks for testing.
But if I see it right you have tested it with a .c file. My problem only occurs when I use the .cpp ending.
If I don't have the extern "C" before the app_main() it don't compiles.
(I think the reason is that this function is called by a C function.)
Unfortunately it is very new for me to mix C and C++ so maybe I'm totally wrong.
Regards
Peter
yes you are right,
thats the sence of this ( using a .cpp file ) :oops:
and i am fanatic c coder too :mrgreen: and have not noted this.

@ivan ( ESP_igrr ) is full right here! @txs
sry for confuse :oops:

best wishes
rudi ;-)