Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can't compile/upload for two teensies simultaneously #78

Open
defenestrated opened this issue Sep 24, 2021 · 13 comments
Open

can't compile/upload for two teensies simultaneously #78

defenestrated opened this issue Sep 24, 2021 · 13 comments
Assignees

Comments

@defenestrated
Copy link

defenestrated commented Sep 24, 2021

Description of problem

When uploading to two teensy boards, either a 4.1 & 3.6 or two 3.6's, platformio can't compile / upload for the correct boards, even when explicit upload_ports are set. See https://community.platformio.org/t/one-project-two-boards-two-codebases-with-src-filter/23586/6 for a more thorough explanation.

Sketches build apparently successfully and can be uploaded via TyCommander no problem.

Steps to Reproduce

  1. create two files, primary.cpp and secondary.cpp
  2. set up platformio.ini as below
  3. run platformio-upload

Actual Results

  • with two 3.6's, primary.cpp is uploaded to the first board at /dev/cu.usbmodem102538701, then secondary.cpp is also uploaded to that board.
  • with one 3.6 and one 4.1 (as described in the .ini file above), primary.cpp uploads correctly but secondary.cpp does not, despite printing "SUCCESS" in the compilation output (see here for full output).

Expected Results

PlatformIO builds each env correctly and uploads to the appropriate board. Teensy CLI should be able to figure out which board is which if they're different versions at least.

If problems with PlatformIO Build System:

The content of platformio.ini:

[env:one]
platform = teensy
board = teensy36
framework = arduino
upload_protocol = teensy-cli
upload_port = /dev/cu.usbmodem102538701 ; the 3.6 is on this port
src_filter = +<*> -<.git/> -<.svn/> -<example/> -<examples/> -<test/> -<tests/> -<secondary.cpp*>

[env:two]
platform = teensy
board = teensy41
framework = arduino
upload_protocol = teensy-cli
upload_port = /dev/cu.usbmodem89957801 ; the 4.1 is on this port
src_filter = +<*> -<.git/> -<.svn/> -<example/> -<examples/> -<test/> -<tests/> -<primary.cpp*>

Source file to reproduce issue:

// primary.cpp
int led = LED_BUILTIN;

void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  while(!Serial && millis() < 4000);
  Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
  Serial.println("hi i'm primary");
}

void loop() {
  digitalWrite(led, HIGH);
  delay(100);
  digitalWrite(led, LOW);
  delay(200);
}
// secondary.cpp
int led = LED_BUILTIN;

void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  while(!Serial && millis() < 4000);
  Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
  Serial.println("hi i'm secondary");
}

void loop() {
  digitalWrite(led, HIGH);
  delay(1000);
  digitalWrite(led, LOW);
  delay(2000);
}
@ivankravets ivankravets transferred this issue from platformio/platformio-core Sep 24, 2021
@PaulStoffregen
Copy link

@ivankravets - Maybe PlatformIO is detecting only serial ports for "upload_port" mentioned here?

Teensy's upload process (teensy_post_compile) does not use serial port names. It uses USB location names. For example, on MacOS the name is "usb:#########" where the number encoded the physical USB controller and chain of hubs/ports to reach the actual USB device.

image

The "teensy_ports" program is meant to be run to give a list of all the Teensy devices connected and their port location name.

If you don't do this and just run the upload process without a proper location name, it will attempt to upload to the first device it can find, since you didn't tell it a proper location.

We use location names rather than serial port names because Teensy is capable of many protocols which are not USB serial, like Keyboard, Mouse, Joystick, Audio, RawHID, etc. In those other modes, there is no serial port name at all. The USB location name is the reliable way to specify exactly which USB board to access, regardless of which protocol it is currently implementing.

@valeros
Copy link
Member

valeros commented Sep 28, 2021

Hi @PaulStoffregen ! Could you please elaborate on how to use these tools together? I tried the teensy_ports app but it seems it runs in an infinite loop waiting for boards. Is there any way to control it via timeout or something?

Even if we manage to retrieve the list of connected boards and their port locations, how to pass this data to the Teensy GUI uploader (or Teensy CLI loader )? Is there any documentation on this matter?

@PaulStoffregen
Copy link

Run with -L if you want to just see a list and quit. Otherwise it will continue running indefinitely and print info as ports appear and vanish.

@valeros
Copy link
Member

valeros commented Nov 2, 2021

Thanks @PaulStoffregen , could you please also shed some light on the upload process and how it should be implemented to distinguish two simultaneously connected boards? Let's imagine we managed to get USB locations, how to pass this data to the Teensy GUI uploader (or Teensy CLI loader )?

@PaulStoffregen
Copy link

PaulStoffregen commented Nov 2, 2021

The basic idea is you give the location info you got from "teensy_ports" to "teensy_post_compile".

The teensy_post_compile program will first tell Teensy Loader to open the file and go into Auto mode. Auto mode means Teensy Loader will automatically reprogram and reboot the next Teensy it finds. Then once Teensy Loader is ready, teensy_post_compile finds the Teensy you specified and sends it a message requesting reboot into bootloader mode. If the USB communication is not successful, which can indeed fail if Teensy has interrupts disable or is stuck in sleep mode or has disabled its USB port, then after several seconds a message is printed asking the user to manually press the pushbutton. But the normal flow is Teensy still runs whatever code was previously programmed, so it can hear the request teensy_post_compile sends, and as soon as your PC detect the device, Teensy Loader see it and does the upload because it was set to Auto mode.

@valeros
Copy link
Member

valeros commented Nov 2, 2021

@PaulStoffregen

The basic idea is you give the location info you got from "teensy_ports" to "teensy_post_compile".

Am I missing something or the teensy_post_compile tool doesn't accept any arguments regarding USB locations?

teensy_post_compile.exe --help

teensy_post_compile - inform the Teensy Loader of freshly compiled code

Usage:
   teensy_post_compile -file=<file> -path=<path> -tools=<toolspath>

       <file> - The code to program (without .hex) to your Teensy board
       <path> - The directory where <file.hex> is located
       <toolspath> - The directory where the Teensy Loader is located

@PaulStoffregen
Copy link

The usage info was not updated as more options were added. Sadly, this stuff just isn't documented well. Best source for info right now is to run Arduino with "verbose info during compilation" turned on from File > Preferences. Then you can see the actual command line usage.

@PaulStoffregen
Copy link

I will update the usage info for version 1.56. Here is the updated info.

teensy_post_compile - inform the Teensy Loader of freshly compiled code

Usage:
   teensy_post_compile [-v] -file=<file> -path=<path> [-tools=<toolspath>]
                       [-board=<board>] [-port=<port>] [-portlabel=<name>]
                       [-reboot]

      -file=<file>        Code to program (without .hex) to your Teensy board
      -path=<path>        Directory where <file.hex> is located
      -tools=<toolspath>  Directory where Teensy Loader is located
      -board=<board>      Board expected to be found
      -port=<port>        USB location (from teensy_ports)
      -portlabel=<name>   User visiable name for port
      -reboot             Send request to go into bootloader mode
      -v                  Show verbose info

@valeros
Copy link
Member

valeros commented Nov 2, 2021

Many thanks for the updates! I also checked the output of teensy_ports -L and it seems there is no info about USB locations, only some generic specs:

Port_#0002.Hub_#0008 COM44 (Teensy 3.2) Serial

If I run it in continuous mode I can see the address field:

{
  "address": "usb:0/140000/0/6/2",
  "online": true,
  "label": "COM44 (Teensy 3.2) Serial",
  "vid": "16C0",
  "pid": "0483",
  "iserial": "167924",
  "boardName": "Teensy 3.2",
  "protocol": "Teensy"
}

Any hints?

@PaulStoffregen
Copy link

You might also think about running teensy_secure to create the EHEX file for people who have an encryption key.

Good news is this does have documentation. Scroll to the end for "Integration with Non-Arduino Development Tools".

https://www.pjrc.com/teensy/td_code_security.html

The short version: just run "teensy_secure encrypthex <file.hex> [key.pem]" after running objdump to create the HEX file. It will create a EHEX file, using the HEX file.

Teensy Loader will automatically use the EHEX file if you opened the HEX file and hardware is found which supports use of encryption.

@PaulStoffregen
Copy link

Oh no, looks like teensy_ports -L is indeed broken on Windows. I will fix -L in the next version, but at least for now, the JSON output for Arduino is the only way. :(

@PaulStoffregen
Copy link

Here is a Windows build of teensy_ports with the -L bug fixed.

https://www.pjrc.com/tmp/teensy_ports.exe

Also updated usage info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants