Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 4 of 4

Thread: Another teensy 4.x Makefile question

  1. #1
    Junior Member
    Join Date
    Feb 2021
    Posts
    4

    Another teensy 4.x Makefile question

    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");
    }

  2. #2
    Senior Member
    Join Date
    Jul 2014
    Posts
    3,120
    Easiest is to add at top of file "#include "Arduino.h" "
    because that what Arduino precompiler does also.

  3. #3
    Junior Member
    Join Date
    Feb 2021
    Posts
    4
    Quote Originally Posted by WMXZ View Post
    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 by Bookp; 02-28-2021 at 03:46 PM. Reason: added link to main.cpp in template

  4. #4
    Junior Member
    Join Date
    Feb 2021
    Posts
    4
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •