GCC - TeensyUser/doc GitHub Wiki
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).
Godbolt is a useful tools which shows you the Assembler-code of short code snippets. You can compare different compiler versions, too.
- https://godbolt.org/z/i4dL_i (GCC 5.4, AVR - Teensy 2.x)
- https://godbolt.org/z/y4oh33 (GCC 5.4.1, Arm-Cortex M0+ - Teensy LC)
- https://godbolt.org/z/uVo6fG (GCC 5.4.1, Arm-Cortex M4 - Teensy 3.x)
- https://godbolt.org/z/uQdXdM (GCC 5.4.1, Arm-Cortex M7 - Teensy 4.x)
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:
- Add a line to boards.txt:
teensy40.build.command.nm=arm-none-eabi-gcc-nm
- 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
.
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
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:
- 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" - 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
- Extract it to the new directory - choose overwrite to overwrite the old version (additional files from the original version will stay)
- Edit boards.txt. There is a line
teensy40.build.toolchain=arm/bin/
- change that toteensy40.build.toolchain=arm9/bin/
- done :)
If you are using VisualTeensy as build system, switching between toolchains is pretty simple:
- Download any toolchain you want to use to a convenient folder (see above for links to the download pages).
- Copy all math libraries
libarm_cortexM*.a
from the Arduino folderArduino/hardware/tools/arm/arm-none-eabi/lib
to the corresponding folder in your downloaded toolchain. - 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)
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
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