Path problem or Wrong configuration?

Hello Community,
I’m discovering PlatformIO for some serious development and I’m trying to build an application for a Teensy++ 2.0 device, something like a keyboard macro handler.
I’ve installed Platform as an Extension of VisualStudioCode (v1.45, AMD64, Linux Arch) and I’ve some troubles with a global teensy variable that cannot be found inside the PlatformIO project. To summarize and focus on the point here’s my platform.ini:

; PlatformIO Project Configuration File
;...
; https://docs.platformio.org/page/projectconf.html
[env:teensy]
platform = teensy
board = teensy2pp
framework = arduino

and to simplify my code here’s something that doesn’t work in my main.cpp file:

#include <Arduino.h>
#include "usb_private.h"
extern volatile uint8_t keyboard_leds;
void setup() {
    Serial.begin(9600);
    Serial.println(keyboard_leds);
}
void loop() {
    Serial.println("Loop");
}

I need an external variable named keyboard_leds that contains current keyboard’s led status, this seems to be something I can use in each Teensy board, I’ve googled around for a while and I’ve seen folks on stackoverflow adding #include "usb_private.h" to solve the problem with PlatformIO. This code in my Arduino IDE works (test.ino):

extern volatile uint8_t keyboard_leds;
void setup() {
    Serial.begin(9600);
    Serial.println(keyboard_leds);
}
void loop() {
    Serial.println("Loop");
}

So I was basically trying to reproduce the same with PlatformIO. Using the #include statement doesn’t seems to be effective at all, I’m getting the same compilation error with or without it.
here’s the error:

> Executing task: platformio run <

Processing teensy (platform: teensy; board: teensy2pp; framework: arduino)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/teensy/teensy2pp.html
PLATFORM: Teensy 4.8.0 > Teensy++ 2.0
HARDWARE: AT90USB1286 16MHz, 8KB RAM, 127KB Flash
PACKAGES: 
 - framework-arduinoteensy 1.151.0 (1.51) 
 - toolchain-atmelavr 1.50400.190710 (5.4.0)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 96 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Linking .pio/build/teensy/firmware.elf
.pio/build/teensy/src/main.cpp.o: In function `setup':
main.cpp:(.text.setup+0x10): undefined reference to `keyboard_leds'
collect2: error: ld returned 1 exit status
*** [.pio/build/teensy/firmware.elf] Error 1
======================================================================== [FAILED] Took 0.53 seconds ========================================================================
The terminal process terminated with exit code: 1

Is it something related to paths or some sort of PlatformIO misconfiguration (or missing setup) on my side ?
Do you need additional information about it ?

Thank you in advance for your reply
Ben

#include "usb_private.h"

Will include a header which, based on other defines, includes the actual usb_private.h for the sub-function, e.g. USB Serial, HID, disk, midi… The documentation (and code) gives you the possible actions for that value.

The keyboard_leds you’re looking for is not in the USB serial (CDC) thing, but e.g. in the USB HID stuff (and others. So you have to choose the correct subclass here. E.g. for the USB HID, as the docs says, adding

build_flags = -D USB_HID

together with first including usb_private.h an then Arduino.h (there’s a weird C/C++ linkage error with a joystick variable otherwise) makes the code

#include "usb_private.h"
#include <Arduino.h>

void setup() {
    Serial.begin(9600);
    Serial.println(keyboard_leds);
}
void loop() {
    Serial.println("Loop");
}

compile. (Also for style, since usb_private.h already declares the extern volatile uint8_t keyboard_leds;, you shouldn’t double declare it).

2 Likes

I’ve looked at usb_private.h file and saw its content but I didn’t realized inner workings and your explanation is absolutely crisp and clear. Honestly never thought I’d make it with build_flags.
Final solution is elegant and clear as well, moving the include before Arduino.h is not that difficult and as you’ve already mentioned it’s not necessary to use keyboard_leds as extern. build_flags statement inside my platformio.ini file and that simple code seems to solve everything.
I need to take a look at the official documentation in order to undestand how everything works, it’s not just a real c++ make with spare libs, there’s so much under the hood.

Thank you so much, now it works

1 Like