qmk / qmk_firmware

Open-source keyboard firmware for Atmel AVR and Arm USB families
https://qmk.fm
GNU General Public License v2.0
18.02k stars 38.73k forks source link

Linking C++/Arduino code files into build #2558

Closed r4dr3fr4d closed 4 years ago

r4dr3fr4d commented 6 years ago

Getting "undefined reference" errors when trying to link arduino code used by a .cpp file, inside of the let's split code.

I've tried inserting extern "C" into some of the used functions but I'm not sure if I'm doing that the correct way.

Anyone else try to mix c and c++ code as part of a hack?

``Compiling: ./tmk_core/common/command.c [OK] Linking: .build/lets_split_rev2_default.elf [ERRORS] .build/obj_lets_split_rev2_default/serial.o: In function `__vector_1': /home/rayce/builds/qmk_firmware-master/keyboards/lets_split/serial.c:124: multiple definition of `__vector_1' .build/obj_lets_split_rev2_default/WInterrupts.o:/usr/share/arduino/hardware/archlinux-arduino/avr/cores/arduino/WInterrupts.c:290: first defined here .build/obj_lets_split_rev2_default/keyboards/lets_split/rev2/rev2.o: In function `pointing_device_task': /home/rayce/builds/qmk_firmware-master/keyboards/lets_split/rev2/rev2.c:78: undefined reference to `UpdatePointer' .build/obj_lets_split_rev2_default/adns_test_serial.o: In function `adns_upload_firmware()': /home/rayce/builds/qmk_firmware-master/keyboards/lets_split/adns_test_serial.cpp:127: undefined reference to `Serial' /home/rayce/builds/qmk_firmware-master/keyboards/lets_split/adns_test_serial.cpp:127: undefined reference to `Serial' .build/obj_lets_split_rev2_default/adns_test_serial.o: In function `performStartup()': /home/rayce/builds/qmk_firmware-master/keyboards/lets_split/adns_test_serial.cpp:180: undefined reference to `Serial' /home/rayce/builds/qmk_firmware-master/keyboards/lets_split/adns_test_serial.cpp:180: undefined reference to `Serial' .build/obj_lets_split_rev2_default/adns_test_serial.o: In function `dispRegisters()': /home/rayce/builds/qmk_firmware-master/keyboards/lets_split/adns_test_serial.cpp:213: undefined reference to `Serial' .build/obj_lets_split_rev2_default/adns_test_serial.o:/home/rayce/builds/qmk_firmware-master/keyboards/lets_split/adns_test_serial.cpp:213: more undefined references to `Serial' follow .build/obj_lets_split_rev2_default/wiring.o: In function `delay': /usr/share/arduino/hardware/archlinux-arduino/avr/cores/arduino/wiring.c:111: undefined reference to `yield' collect2: error: ld returned 1 exit status

make[1]: [tmk_core/rules.mk:286: .build/lets_split_rev2_default.elf] Error 1 Make finished with errors make: [Makefile:543: lets_split/rev2:default:avrdude] Error 1``

higherorderfunctor commented 6 years ago

I have linked against FastLED which is a C++ library. The fastled_entry.* files have the C/C++ wrapping code in it. The bootstrap directory does the necessary work to include the Arduino headers. All code I was playing with is in the directory below. The readme.md has where I imported the libraries, all other code is the keymap space.

Note: I implemented Timer3 as a stand in for Timer0 for the Arduino includes to get a sub millisecond resolution. Timer0 setup by QMK uses the overflow method to increment the clock at about a 1ms resolution.

https://github.com/kcal-io/qmk_firmware/tree/master/keyboards/9key/keymaps/split_fastled/

r4dr3fr4d commented 6 years ago

Thanks @higherorderfunctor - will give that a look. I was about to give up and program the board entirely in Arduino.

drashna commented 6 years ago

@higherorderfunctor I'm just curious, why use the FastLED library over the RGB Underglow feature?

higherorderfunctor commented 6 years ago

I am trying to do per key RGB on an Iris with RGB underglow. FastLED was attractive for its power management and dithering functions for the amount of LEDs I want to power. It is on my TODO list to go back and try the native RGB functions and do some measurements now that I have tools to read the draw. The project has stalled since school has started back up and it takes around 30 minutes per LED due to the glue melting on the solder mask dots and copper tape which causes everything to shift under heat.

https://www.reddit.com/r/olkb/comments/7r7fpy/mod_through_hole_led_to_rgb_smd/

drashna commented 6 years ago

Well, for power management, RGBLIGHT_LIMIT_VAL was added recently, and that will limit the current draw for the LEDs.

r4dr3fr4d commented 6 years ago

@higherorderfunctor, I messed around with my code some more, but I actually already had the correct __cplusplus and extern statements in every spot.

I'm wondering if my code is all of the issue here. Grep'ing through the qmk directory, avr-g++ isn't used anywhere, and from what I've researched regarding integrating c++ files into a c project (example), all of the code needs to be linked by the c++ compiler, or have a bunch of different linker options. Changing the CC var in avr.mk to 'avr-g++' causes warnings and redefinition/declaration erros in otherwise working code.

Any thoughts? Is QMK fully set up to handle linking code from either/both languages?

higherorderfunctor commented 6 years ago

@drashna, thank you for the heads up; congrats on collaborator too!

@raycewest, FastLED is written in C++ and I did not have to do anything with avr-g++. From the original output you posted, I see a familiar error in wiring.c. I had a lot of trouble with that one. I believe I eventually got it to compile, but I wasn't getting a fast timer, the only thing I needed from wiring.c upon inspection. The Arduino library defaults to using Timer0 like QMK, so I ended up just writing my own implementation of Timer3 as a stand in. This allowed me to drop wiring.c.

If you want, you can toss your repo up on GitHub someplace and I can try to get it to compile and link over the next week.

r4dr3fr4d commented 6 years ago

@higherorderfunctor Thanks man, I'll take you up on that. Let me look at it soon.

stale[bot] commented 4 years ago

This issue has been automatically marked as resolved because it has not had activity in the last 90 days. It will be closed in the next 30 days unless it is tagged properly or other activity occurs.

r4dr3fr4d commented 4 years ago

Saw that this got closed by the bot...looks like I let it slip away. @higherorderfunctor would you perhaps still be willing to guide on how to integrate arduino APIs into QMK? I can point you to a repo or give you the function names here, or email you.

higherorderfunctor commented 4 years ago

It's been awhile since I last played with this, so it might take me awhile to get my bearings, but I don't mind taking a look. Full repo would be best to work though. Usually one compiler error fixed would expose another.

r4dr3fr4d commented 4 years ago

I'd have to dig for that and see if I still have it. For now, if it's okay, I can point to some code I was trying to work into QMK: https://github.com/mrjohnk/PMW3360DM-T2QU/blob/master/Arduino Examples/PMW3360DM-Interrupt/PMW3360DM-Interrupt.ino

This is for a sensor - the main issues here are the SPI class, Serial class, and all of the Arduino APIs (setPinMode, digitalRead/Write, etc). Having access to those from the QMK APIs is the goal.