Another teensy 4.x Makefile question

Bookp

New member
Hi there, I've been lurking a while but this is my first post - just want to say I absolutely love Teensy and all the work Paul has done to make this amazing community and product line.

My problem is that I'm trying my best to work outside of the Arduino ecosystem. I am working with a TEENSY41 and managed to get the sample Makefile to compile simple code, with NO_ARDUINO=true set - yay!

My issue is that when I try to compile more complicated code, i.e. a sample I found in these forums that uses MQS (code listed at bottom), I get errors. I'm manually adding in the lib -I args to the CXX command, for Audio, SerialFlash, SPI etc, since those are not in the core. This seems to be what arduino does as well, from what I gathered from some process grepping.

Anyway, I get this error from manually compiling:

Code:
...
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: levi.o: in function `AudioOutputMQS::AudioOutputMQS()':
/home/levi/Downloads/arduino-1.8.13/hardware/teensy/avr/libraries/Audio/output_mqs.h:38: undefined reference to `AudioOutputMQS::begin()'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: levi.o: in function `AudioStream::AudioStream(unsigned char, audio_block_struct**)':
/home/levi/teensy/helloworld/./AudioStream.h:133: undefined reference to `vtable for AudioSynthToneSweep'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /home/levi/teensy/helloworld/./AudioStream.h:133: undefined reference to `vtable for AudioAmplifier'
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: /home/levi/teensy/helloworld/./AudioStream.h:133: undefined reference to `vtable for AudioOutputMQS'

I'll note that this compiles fine from arduino. I tried the Makefile from the latest beta too but had the same result. I'm likely doing something stupid here? I'm not ultra familiar with gcc/g++ toolchains, though I'm very willing to learn more.

Code in question:

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthToneSweep tonesweep1; //xy=102,174
AudioAmplifier    amp1;   //xy=324,172
AudioOutputMQS    mqs1;   //xy=538,168
AudioConnection   patchCord1 (tonesweep1, amp1);
AudioConnection   patchCord2 (amp1, 0, mqs1, 0);

// GUItool: end automatically generated code

const float t_ampx  = 0.8;
const int t_lox = 10;
const int t_hix = 22000;
const float t_timex = 10;   // Length of time for the sweep in seconds

void run(void)
{
  // Wait for at least 3 seconds for the USB serial connection
  Serial.begin (9600);
  while (!Serial && millis () < 3000)
    ;

  delay (3000);

  AudioMemory (2);
  amp1.gain (0.5);

  Serial.println("setup done");

  if (!tonesweep1.play (t_ampx, t_lox, t_hix, t_timex)) {
    Serial.println ("ToneSweep - play failed");
    while (1)
      ;
  }

  // wait for the sweep to end
  Serial.println ("Tonesweep up started");
  while (tonesweep1.isPlaying ())
    ;

  // and now reverse the sweep
  Serial.println ("Tonesweep down started");
  if (!tonesweep1.play (t_ampx, t_hix, t_lox, t_timex)) {
    Serial.println("ToneSweep - play failed");
    while (1)
      ;
  }

  // wait for the sweep to end
  while (tonesweep1.isPlaying ())
    ;
  Serial.println("Done");
}
 
Easiest is to add at top of file "#include "Arduino.h" "
because that what Arduino precompiler does also.
 
Easiest is to add at top of file "#include "Arduino.h" "
because that what Arduino precompiler does also.

Yeah I am already doing that as it's part of the core Makefile template setup:

Code:
#include <Arduino.h>
#include "levi.h"

extern "C" int main(void)
{
	run();
}
 
Last edited:
So I took another stab at this for a couple hours tonight and actually made it work! (My C buildchain skills are slowly incrementing).

Here's a rough dump of the steps I took to get things compiling:

1. The example Makefile in the teensy4 library explicitly notes there is no Arduino library support yet. I gather this includes not supporting the teensy supplied libraries too (such as Audio)

2. I could compile all of the Audio library files to .o by copying the main Makefile over and adding a few -I args in the mix for the Audio lib to find relevant headers (these were the teensy4 core, Wire, SPI, SD and SerialFlash)

3. There is some assembly in the Audio lib (memcpy_audio.S) - I got caught on this because I started by telling the linker about all the .o files that I'd compiled. To include this I simply had to add it to the list of object files and add a -I to LDFLAGS var.

4. I hit another linker issue after all this - that is when I realized the ref that was missing was in Audio/utility - so I had to go and compile those down to .o files and pass them to the linker too.

5. Success!!! I compiled the original code from the post and uploaded it to the T40. It made a cruddy little speaker make some wails :)

This was a really fun exercise, since it ended in things working. What I would love to be able to do at this point would be to make a library of the Audio .o files that I can port around my projects. This might be my next step, just trying to really simple path has worked out for me:

Code:
[ww Audio]$ /opt/arduino/hardware/tools/arm/bin/arm-none-eabi-gcc -shared -o libaudio.o *.o 
...
/fast/opt/arduino-1.8.13/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: cannot find crt0.o: No such file or directory
/fast/opt/arduino-1.8.13/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: cannot find -lgcc
collect2: error: ld returned 1 exit status

It looks like I need to do a bit of work to make the arm gcc work for me here.

Finally, I'll end on a note that maybe I'm just doing this wrong - but if this is in fact what Arduino does for us behind the scenes, with all of the libraries you include.... Well I have to give it some credit for that. One of my end goals here would be to make some Rust bindings for some of the teensy libraries. I have no idea how hard or possibly that will be (I've been successful so far only with making bindings on x86!!!), but all of this is pretty interesting to figure out anyway.

If you read all of this, power to you - I'll update here with more info next time I progress.
 
Back
Top