Everything goes wrong trying to work without the Arduino IDE.

Status
Not open for further replies.

Samuel

Member
My goal is to write all my Teensy projects in plain C, no Arduino sketches or the like. Sadly, this is incredibly hard, and I'm running into problems every step of the way. Currently, I have an incredibly minimal source file, morse.c, which just looks like this:

Code:
#include <core_pins.h>

int main()
{
    digitalWrite(11, 1);
    return 0;
}

(Incidentally, I can't find where either things like PORTD or things like PIN_D6 are... it'd be nice if someone could point me in the right direction.)

The way I'm trying to building this is using SCons (mostly because make has no reasonable way to work on Windows), and I'm doing it by compiling everything in [arduino]\hardware\teensy\avr\cores\teensy3 (except main.cpp) to object files, and then linking them together with GCC. All of this compiling and linking is done with the options in the example Makefile, including -Wl,--gc-sections.

There have been loads of errors I've had to step around, but I've managed most of them. Now, however, I've run into a wall. Running this command:

Code:
arm-none-eabi-gcc -o morse.elf -Os -Wl,--gc-sections,--defsym=__rtc_localtime=0 --specs=nano.specs -mcpu=cortex-m4 -mthumb -T"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3\mk20dx256.ld" objects\analog.o objects\eeprom.o objects\keylayouts.o objects\math_helper.o objects\mk20dx128.o objects\nonstd.o objects\pins_teensy.o objects\ser_print.o objects\serial1.o objects\serial2.o objects\serial3.o objects\touch.o objects\usb_desc.o objects\usb_dev.o objects\usb_joystick.o objects\usb_keyboard.o objects\usb_mem.o objects\usb_midi.o objects\usb_mouse.o objects\usb_rawhid.o objects\usb_seremu.o objects\usb_serial.o objects\AudioStream.o objects\DMAChannel.o objects\HardwareSerial1.o objects\HardwareSerial2.o objects\HardwareSerial3.o objects\IPAddress.o objects\IntervalTimer.o objects\Print.o objects\Stream.o objects\Tone.o objects\WMath.o objects\WString.o objects\avr_emulation.o objects\new.o objects\usb_flightsim.o objects\usb_inst.o objects\yield.o morse.o

This error occurs:

Code:
c:/program files (x86)/arduino/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/bin/ld.exe: section .ARM.extab.text._ZN14HardwareSerial5writeEm loaded at [0000a134,0000a13f] overlaps section .data loaded at [0000a134,0000a283]
objects\HardwareSerial1.o:(.rodata._ZTI6Stream[_ZTI6Stream]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
objects\HardwareSerial1.o:(.rodata._ZTI14HardwareSerial[_ZTI14HardwareSerial]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
objects\HardwareSerial2.o:(.rodata._ZTI15HardwareSerial2[_ZTI15HardwareSerial2]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
objects\HardwareSerial3.o:(.rodata._ZTI15HardwareSerial3[_ZTI15HardwareSerial3]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
objects\IPAddress.o:(.rodata._ZTI9Printable[_ZTI9Printable]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
objects\IPAddress.o:(.rodata+0x18): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
objects\Print.o:(.rodata+0xc): undefined reference to `vtable for __cxxabiv1::__class_type_info'
objects\usb_inst.o:(.rodata._ZTI16usb_serial_class[_ZTI16usb_serial_class]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
c:/program files (x86)/arduino/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7e-m\libc_s.a(lib_a-signalr.o): In function `_kill_r':
signalr.c:(.text._kill_r+0xe): undefined reference to `_kill'
c:/program files (x86)/arduino/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7e-m\libc_s.a(lib_a-signalr.o): In function `_getpid_r':
signalr.c:(.text._getpid_r+0x0): undefined reference to `_getpid'

To me, the things that stick out in this error is the "undefined reference to `_kill'" and "undefined reference to `_getpid'".

Looking around on the internet, other people have suggested switching "--specs=nano.specs" for "--specs=nosys.specs". Doing that, however, I still get this error:

Code:
objects\HardwareSerial1.o:(.rodata._ZTI6Stream[_ZTI6Stream]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
objects\HardwareSerial1.o:(.rodata._ZTI14HardwareSerial[_ZTI14HardwareSerial]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
objects\HardwareSerial2.o:(.rodata._ZTI15HardwareSerial2[_ZTI15HardwareSerial2]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
objects\HardwareSerial3.o:(.rodata._ZTI15HardwareSerial3[_ZTI15HardwareSerial3]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
objects\IPAddress.o:(.rodata._ZTI9Printable[_ZTI9Printable]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
objects\IPAddress.o:(.rodata+0x18): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
objects\Print.o:(.rodata+0xc): undefined reference to `vtable for __cxxabiv1::__class_type_info'
objects\usb_inst.o:(.rodata._ZTI16usb_serial_class[_ZTI16usb_serial_class]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'

These "undefined reference to `vtable for blah blah blah" errors also occur using nano.specs, it seems.

How do I fix this? I just... want to compile anything at all, hahah. I'm not trying to do anything weird; just using the vanilla Teensy 3 core that ships with Teensyduino, so I'm assuming this isn't something that always happens with the core (since, you know, shipping a broken core would be weird).

In addition, I am definitely open to suggestions for better ways to work without Arduino sketches and the Arduino IDE. Perhaps there's a better way than compiling the entire core (that doesn't involve having to hand-pick .c files from the core).
 
Last edited:
Have you started with a working Arduino environment? All the needed files are brought in with the TeensyDuino install. If you want to do this you should have a tool or way to grep/search the installed sources and related glue and example files. My 20+ year old editor searches to show this: "Core_pins.h (i:\teensy165\hardware\teensy\avr\cores\teensy):#define PIN_D6 11"

There are other posts - with details you might find with a BING/google search - but I think the following is good advice - the rest on the thread.
 
i:\teensy165\hardware\teensy\avr\cores\teensy

That's the Teensy 2.0 core, though, as far as I know. The core I'm using (and am supposed to be using) is "teensy3", not "teensy".

And yep, I started with a working Arduino environment, as far as I know. I installed Arduino, at least, and then Teensyduino.
 
Yep - it sure is - the ARM version will be there just the same when using an ARM named pin.

[hint: I:\Teensy165\hardware\teensy\avr\cores\teensy3]
 
I'm not entirely certain I know what you're trying to convey. I am already compiling everything in the teensy3 core; finding it isn't the problem. I guess maybe the PORT[letter] and PIN_[letter][number] approaches simply aren't there on Teensy 3, and I was reading Teensy 2 stuff? Is the approach for pins on Teensy 3 simply using digitalWrite with numbers corresponding to pins, and 0 and 1 corresponding to LOW and HIGH respectively?

Tried building and uploading the Blink example from the Arduino IDE, by the way, and it worked. So there shouldn't be a problem with the install - and not with the upload either. The errors are during compiling.
 
Last edited:
Sounds like you have the tools to start set up. Find some usable samples and they'll show you the ways to use the ARM and pins. The AVR info and tools are a distraction.

Sorry appearing being obtuse - but I was hoping if you were in to doing this I'd give you enough to get going so I could move on. Good Luck.

Look at : \hardware\teensy\avr\cores\teensy3\pins_arduino.h and follow LED_BUILTIN and other items in this sample and you can experiment and grow from there:

Code:
#define qBlink() (digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) ))  // Pin13 on T3.x & LC
void setup() {
  Serial.begin(38400);
  digitalWrite(LED_BUILTIN, HIGH);
  pinMode(LED_BUILTIN, OUTPUT);
  qBlink();
  delay(200);
  while (!Serial && (millis() <= 4000))
    qBlink();
  Serial.println(millis());
  Serial.println("OK");
}

elapsedMillis emilBlink;
void loop() {
  if ( emilBlink > 1000 ) {
    qBlink();
    emilBlink = 0;
    // Serial.print(".");
  }
}
 
I don't think you're really understanding what I'm saying here...? The problem is not that I don't know how to use pins or anything like that, the problem is that I can't compile without the Arduino IDEM; I just get a load of errors, which I want to know how to fix. Using the Arduino IDE is not a solution to this.
 
- You can't use "plain c" together with teensyduino-libs. they are not "plain c". you should decide what you want... :eek:
- There are several makefiles around, several IDEs, so it might be a good idea to use google or a forum-search - but, again, this is not the solution you want, because they use Teensyduino with not "plain c" libs too.
- a "Sketch" is a not more than a file containing sourcecode.
- if you don't want arduino, just use the arm-gcc compiler (download it somewhere) and write your own libs.
 
Last edited:
Apparently a lack of understanding. With verbose on the IDE will show you how it builds everything without error. If I wanted to make it work I would emulate that as noted on the linked thread above. Once you cross some line toward 'bare metal' you will end up recreating the wheel.

The Teensy infrastructure is built to work with Arduino - when you leave that you are in for learning and work to split the difference. The source is all there - I haven't done this as working in the IDE brings so much and I don't see where it will hurt my efforts. It is just a well refined tool and you have the source to exclude or customize away stuff you don't need building within it with whatever coding style you choose.
 
- You can't use "plain c" together with teensyduino-libs. they are not "plain c". you should decide what you want... :eek:
- There are several makefiles around, several IDEs, so it might be a good idea to do use google or a forum-search - but, again, and this is not the solution you want, because they use Teensyduino with not "plain c" libs too.
- a "Sketch" is a not more than a file containing sourcecode.
- if you don't want arduino, just use the arm-gcc compiler (download it somewhere) and write your own libs.

I do want to use things like core_pins.h, though, so I do want to use some parts of Teensyduino.

Basically, I want to meet these requirements:

  • Not use the Arduino IDE
  • Write my project as files with a .c extension, as you would any other C project
  • Be able to include things from the Teensy core library, in order to be able to do things like digitalWrite() and delay()

What approach should I take to do this? Perhaps trying to compile the entire core to object files and linking together with --gc-sections isn't the way to go?
 
- There are other IDEs
- Why is the extension important ? Just write a "dummy sketch" and #include your *.c -file ? (you can't use main(), because this is arduino-internal. use setup() instead. )
- Take a look at the core-library, at first mk20dx128.c
 
If you can use Windows, the free Visual Micro tools support the peculiar Arduino build concept, with T2/T3 as an option. As well as the conventional C/C++ builds, using a state of the art IDE. It's a plugin for the new free MS Visual Studio. The compiler is GCC.

http://www.visualmicro.com/

If you cannot use Windows, then Eclipse for Arduino is a way to go. But with this, plan on quite some time tool-building rather than project focused.
 
Last edited:
Search for Teensyduino makefiles.
I've already looked at the Teensyduino makefile that is supplied with Teensyduino. That one seems to compile the entire core, as far as I can tell - I can't use that, however, since I'm on Windows.

The thing is, I want to be able to transition to a non-Teensy (and non-Arduino) platform later, which means I don't want to be using the Arduino IDE, but instead build with a SConstruct file (basically a makefile) and plain ol' GCC. Can anyone actually tell me how to best do this? Or at the very least, how to fix the errors I was getting?
 
I've already looked at the Teensyduino makefile that is supplied with Teensyduino. That one seems to compile the entire core, as far as I can tell - I can't use that, however, since I'm on Windows.

Why can't you use the makefile on Windows?
 
Why can't you use the makefile on Windows?

Because I've got a path that involves a bunch of spaces, and Makefile variables definitely don't like that. Though, now that I'm saying this, I realize I may be able to get around that by putting it in an environment variable...

Perhaps I'll try again getting the Makefile working, and if that works I'll look at the difference between the commands it executes and the commands my SConstruct file executes.

'Til I've tried that, I'm still very much interested in suggestions on how to best compile the (parts that I need of) the core and how to get around the bucketful of errors.
 
The shortest path to success may be creating a new development directory that doesn't have spaces anywhere in the path. I've always done this for my C coding on Windows platforms, spaces never seemed necessary (maybe because I started with DOS...)
 
The shortest path to success may be creating a new development directory that doesn't have spaces anywhere in the path.

I'd rather not, for a few reasons. Besides, the Arduino install location contains spaces too (although I guess that could be reinstalled). Will be back with news of what will almost certainly be more trouble once I've tried to get the standard makefile to work.
 
I started on DOS too - and helped ship v6.x - I avoid filename spaces.

As shown above I partitioned my HDD to create "I:" and I unzip installed the Arduino and TeensyDuino on the drive so it is fully outside any system folders and I controlled all the names. On that drive I can have multiple independent installations - right now 1.6.3 and 1.6.5 - and 1.6.3 can go away when 1.6.6 goes on. In fact yesterday I copied the 1.6.5 to a second "1.6.5_copy" folder that works as without the Arduino installer involved - it just runs where it is.

You are going down a difficult path for your own reasons - not starting with limitations like 'spaces' would remove one more up front obstacle.
 
I'm definitely not an expert in writing Makefiles but the one I use works nicely under Windows (see attachment, had to add a .txt extension to upload it). I use it with "Visual Studio 2015 community edition" but it should work regardless of the IDE you are using. It doesn't use any file from the Arduino folders (in fact I didn't even istall it). You just need Pauls core files which you can download from Github and gcc which you can downlod here https://launchpad.net/gcc-arm-embedded/+download (make sure to use the version "4.8-2014-q3-update release")

I have some bad experiences with old code of mine which was not compiling a couple of years later since the underlying libraries changed. I therefore prefer to make the project self contained by copying all required library and core files in a subdirectory of the project directory. The makefile uses the following directory structure.

my_project
my_project/lib/core122 <- teensyduino 1.22 files go here
my_project/lib/misc <- all other used libraries go here (optional)
my_project/src <- source files (may be in subdirectories)
my_project/toolchain <- make.exe and the teensy tools

If you are interested I can send you a zipped "blink" skeleton project file which will compile under VS2015.
 

Attachments

  • makefile.txt
    4 KB · Views: 168
Whoa, luni, this is exactly the kind of stuff I'm looking for! I really appreciate it, will look at that makefile.

And Paul may be interested to know a few more reasons why it doesn't really work on Windows: "abspath" doesn't work, so $(abspath $(COMPILERPATH))/arm-none-eabi-whatever just turns into "/arm-none-eabi-whatever", which for obvious reasons doesn't work. This, plus adding some quotes here and there ("teensy-post-compile -path=$(shell pwd)" should probably be "teensy-post-compile -path="$(shell pwd)"", for example, though for some reason that still gets me a "No such file or directory" error) may be a worthwhile fix for the next core release.
 
Last edited:
I linked the morse.c program on my win8.1 Makefile system without problems together with cores/teensy3/*.* (excluding main.cpp obviously).

OK, I had no spaces in the T path.
To check if the problem is due to the spaces, simply copy the ld file to your working directory (e.g. objects) and change linker command

other difference is that morse.o was first in list, but this may not matter as no libraries are involved

I had also -larm_cortexM4l_math -lm at the end

getting Linux style Makefile working in Windows is obviously another issue and depends which Makefile.environment (MinGW or Cygwin) you are using
(I use MinGW and had to do some standard 'tricks' to handle the '/' issue)
 
I fixed the problem, everyone! Yaaaay!

Turns out what was giving me both the _kill and vtable errors were two missing CXXFLAGS while compiling objects from .cpp files: -fno-exceptions and -fno-rtti, respectively.

I found this out by fixing the Makefile to work on my system, and changing around the commands I was using in SCons until they matched the ones in the Makefile. I'm up and running now. Thanks, everyone!
 
I thought I perhaps ought to mention for posterity that compiling a bare-bones program to the Teensy using this method (compiling the entire core to objects with the -ffunction-sections flag and linking with --gc-sections), only 4% of the Teensy's memory is used. That's pretty freakin' great. Compare that to the guy who compiled only the files he needed, substituting functions he didn't need with noop aliases: he got down to 3% using that method. So not having to think about which C files from the core to use, and not having to do any sidestepping, 4% is fantastic. As it stands now, I'd definitely recommend this approach!

Attaching my Teensy SConstruct files, in case anyone else wants to build for Teensy using SCons.
 

Attachments

  • SConstruct_Teensy.zip
    2.3 KB · Views: 136
Just compiled "blink" with Arduino-IDE: 3%
But..what's the point ? Is there any advantage having small programs ?
 
Status
Not open for further replies.
Back
Top