Skip to content
Greg Darke edited this page Jul 23, 2021 · 26 revisions

Contents

Current toolchain

Teensyduino uses the gcc-arm-none-eabi toolchain to compile and build firmware for the ARM based Teensies. Current binaries of the toolchain are hosted by ARM and can be downloaded here. Versions below 6.0 can still be downloaded from Launchpad.

Currently Teensyduino uses the version gcc-arm-none-eabi-5_4 for all ARM based Teensy boards (T3.x and T4.x).

Analyzing compiler output

Compiler explorer

Godbolt is a useful tools which shows you the Assembler-code of short code snippets. You can compare different compiler versions, too.

List and symbol files:

Teensyduino produces additional files, which are useful if you want to dig more in to the internals or for optimizing. In principle this should be possible with any of the build systems.Teensyduino creates an .LST and a .SYM file in the build directory.

But, there is nothing that can't be improved - the generated .SYM file is a bit confusing because the tool nm is not used. We can easily change that:

Arduino IDE
Example for Teensy 4:

  1. Add a line to boards.txt:
    teensy40.build.command.nm=arm-none-eabi-gcc-nm
  2. Add the following line to platform.txt:
recipe.hooks.postbuild.4.pattern="{compiler.path}stdout_redirect" "{build.path}/{build.project_name}.symnm" "compiler.path}{build.toolchain}{build.command.nm}" -n -S --defined-only -C "{build.path}/{build.project_name}.elf"

Now, when we do a new build, an additional .symnm file is created, which is clearer and sorted -- and therefore easier to read.

VisualTeensy
Since version v0.9.7.4 VisualTeensy uses nm.exe to generate symbol files per default. The *.sym file is placed in the usual build folder $(project)/.vsteensy/build.

Fix broken objdump for Teensy 4

The objdump for the current GCC is broken and emits more or less unreadable lst files. Copying an objdump from a newer (GCC 9) toolchain to the GCC folder fixes this. Here the output of a working objdump

00000060 <setup>:
#include "Arduino.h"

void setup()
{
  pinMode(LED_BUILTIN,OUTPUT);
      60:	movs	r1, #1
      62:	movs	r0, #13
      64:	b.w	150 <pinMode>

00000068 <loop>:
			return (CORE_PIN13_PINREG & CORE_PIN13_BITMASK) ? 1 : 0;
      68:	ldr	r3, [pc, #36]	; (90 <loop+0x28>)
      6a:	ldr	r2, [r3, #8]
      6c:	tst.w	r2, #8
				CORE_PIN13_PORTCLEAR = CORE_PIN13_BITMASK;
      70:	mov.w	r2, #8
			return (CORE_PIN13_PINREG & CORE_PIN13_BITMASK) ? 1 : 0;
      74:	bne.n	82 <loop+0x1a>
}

void loop()
{
  digitalWriteFast(LED_BUILTIN,!digitalReadFast(LED_BUILTIN));
  delay(500);
      76:	mov.w	r0, #500	; 0x1f4
				CORE_PIN13_PORTSET = CORE_PIN13_BITMASK;
      7a:	str.w	r2, [r3, #132]	; 0x84
      7e:	b.w	94 <delay>
      82:	mov.w	r0, #500	; 0x1f4
				CORE_PIN13_PORTCLEAR = CORE_PIN13_BITMASK;
      86:	str.w	r2, [r3, #136]	; 0x88
      8a:	b.w	94 <delay>
      8e:	nop
      90:	.word	0x42004000

See https://forum.pjrc.com/threads/58814-Code-generated-for-Teensy40?p=224844&viewfull=1#post224844

Switching between different toolchains

Newer Toolchains are not always better. The one Teensyduino uses (5.4) is quite old - but good. If you want to try a newer one, that's easily doable:

Arduino IDE

  1. There is a directory "arm" under Arduino/hardware/tools - copy the whole directory and name it i.e. "arm9" - in result, you should have two directories now, "arm" and "arm9"
  2. Download (the zip-file) a newer toolchain from https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads
  3. Extract it to the new directory - choose overwrite to overwrite the old version (additional files from the original version will stay)
  4. Edit boards.txt. There is a line teensy40.build.toolchain=arm/bin/ - change that to teensy40.build.toolchain=arm9/bin/
  5. done :)

VisualTeensy

If you are using VisualTeensy as build system, switching between toolchains is pretty simple:

  1. Download any toolchain you want to use to a convenient folder (see above for links to the download pages).
  2. Copy all math libraries libarm_cortexM*.a from the Arduino folder Arduino/hardware/tools/arm/arm-none-eabi/lib to the corresponding folder in your downloaded toolchain.
  3. done :)

To switch between toolchains or Teensyduino versions all you need to do is select the corresponding folders in the expert settings and recompile. (Since these are project scope settings you can easily set up projects using different toolchain versions)

image

Remark: It is always a good idea to collect all build system relevant files in a dedicated folder. I for example use the structure below which contains various compilers, all Teensyduino versions I used in older projects, a clone of the currently worked on Teensyduino core for tests, some known good versions of TyTools etc...

toolchain
├── gcc
│   ├── gcc-arm-none-eabi-4_8-2014q3
│   ├── gcc-arm-none-eabi-5_4-2016q3
|   └── gcc-arm-none-eabi-9-2019-q4
├── Teensyduino
│   ├── current_clone
│   ├── td_141
│   ├── td_142
│   ├── td_146
│   ├── td_147
│   └── td_150
├── TyTools
│   ├── TyTools-0.8.11-16-gc874426-win64
│   ├── TyTools-0.9.0-7-g3825182-win64
│   └── TyTools-0.9.0-win64
└── VisualTeensy

PlatformIO

You can easily switch the version of the toolchain that PlatformIO uses to build. Edit your platformio.ini and add the following to the [env] section: platform_packages = toolchain-gccarmnoneeabi @ =1.70201.0 Obviously you can specify whatever version you want to try using PlatformIO semantic version syntax

Clone this wiki locally