Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use arduino libraries with standard C code

I am using Eclipse kepler for AVR development. The code that I have is C (Open Source), and I've gotten it adjusted so it runs perfectly. My target is an ATmega2560, in the form of an arduino mega2560. Using the arduino board is strictly for hardware convenience; we are developing the hardware to be a custom board with most of the core arduino mega2560 components.

I need to use several libraries with this project that are only available as arduino libraries, namely libraries for an e-paper screen (from seeedstudio) and Nordic's BLE nRF8001.

If I create a new arduino project using the plugin in eclipse, I can build and run the tests for the arduino libraries perfectly.

When I try to merge the 2 code bases together, I can't seem to call the functions in the added arduino libraries - if I call them the compiler throws a linking error.

Building target: Virgin2ManualArdInsert.elf
Invoking: AVR C Linker
avr-gcc -Wl,-Map,Virgin2ManualArdInsert.map -mmcu=atmega2560 -o "Virgin2ManualArdInsert.elf"         ./avr/adc.o ./avr/eeprom.o ./avr/lcd_and_input.o ./avr/main.o ./avr/strings.o ./avr/unimplemented.o ./avr/usart.o  ./aes.o ./baseconv.o ./bignum256.o ./ecdsa.o ./endian.o ./fft.o ./fix16.o ./hash.o ./hmac_sha512.o ./messages.pb.o ./p2sh_addr_gen.o ./pb_decode.o ./pb_encode.o ./pbkdf2.o ./prandom.o ./ripemd160.o ./sha256.o ./statistics.o ./stream_comm.o ./test_helpers.o ./transaction.o ./wallet.o ./xex.o   
./avr/main.o: In function `main':
main.c:(.text.startup.main+0xc): undefined reference to `writeEink'
collect2: error: ld returned 1 exit status
makefile:53: recipe for target 'Virgin2ManualArdInsert.elf' failed
make: *** [Virgin2ManualArdInsert.elf] Error 1

As a test, I'm just trying to call a basic "write to display" call in eInk.cpp from main.c:

extern "C"{
void writeEink()
{

    EPAPER.begin(EPD_SIZE);                             // setup epaper, size
    EPAPER.setDirection(DIRNORMAL);                     // set display direction

    eSD.begin(EPD_SIZE);
    GT20L16.begin();

//    int timer1 = millis();
    EPAPER.drawString("testing", 10, 10);
    EPAPER.drawNumber(12345, 60, 40);
    EPAPER.drawFloat(-1.25, 2, 80, 65);
    EPAPER.display();                                   // use only once

}

Is a static library built from the arduino cores the way to go here? I've tried it (though it seems most of the procedures are outdated) and the libraries do not want to link/be called.

What is the correct procedure for including C++/Arduino calls in my C code? I've tried using extern "C" {function()}; in my .cpp files and .h files but to no use.

Thank you for any help or pointers to where I can figure it out for myself.

like image 425
ThesQuid Avatar asked Nov 10 '22 05:11

ThesQuid


1 Answers

You can try to compile your C code as C++ by simply renaming the files to *.CPP, but chances are that you have to modify your code to make it compile as C++ code. There are things that are allowed for C, but not for C++ (like calling functions that are not declared).

The other solution is to wirte wrappers around the C++ functions that you want to use from C. You have to consider two limitations of C against C++:

  1. C is not object oriented
  2. C does not support overloading of functions

This example for Serial.print() shows how you can handle this with a wrapper:

extern "C" void SerialPrintInteger( int value )
{
    Serial.print( value );
}

In this example you would write similar functions like SerialPrintFloat(), SerialPrintString() etc. The extern "C" prefix tells the compiler to create the function in a way that makes it callable from C.

like image 168
Heinz Kessler Avatar answered Nov 15 '22 08:11

Heinz Kessler