The Freescale Kinetis Design Studio (KDS) V1.0.1 beta is using a different GNU ARM toolchain than the ARM Inc. supported one on launchpad (GCC ARM Embedded). Additionally, KDS is using newlib 1.19 and newlib-nano 1.0, while there just has been a new release of the GCC ARM Embedded a month ago with the 4.8.4 update 2 release in June this year. So how to upgrade KDS to the latest and greatest GCC ARM Embedded?
In this post you can learn
- How the tool chain is setup in Freescale Kinetis Design Studio (V1.0.1 beta at this time)
- How you can swap in and out the latest and greatest GNU toolchain from ARM Inc. (Launchpad)
- What you need to now about switching projects from one tool chain to another.
Changing Toolchain and Libraries?
A benefit of using open source tools and libraries which are actively maintained is that I can freely pick and choose what I want and need (see “Constructing a Classroom IDE with Eclipse for ARM“). On the other side, distributions like the Freescale Kinetis Design Studio has the advantage that a lot of this customization has been done, and comes with an installer. But if there is a newer GNU toolchain from ARM Inc., it often makes sense to get to that latest and greatest version. But changing the toolchain of a distribution makes sense too if there is a new IDE, but I want to keep the tool chain, e.g.not to introduce any risk in the code generated, but I want to benefit for example from other new parts in the IDE. In any case, what I’m proposing here is way that I can switch back and forward the toolchain, without changing the Kinetis Design Studio IDE. That way the risk of using a new compiler and new libraries can be minimized.
💡 The Eclipse build system has as well the concept of multiple tool chains. Honestly, I have not explored it much. It might be a more elegant solution, but I think it does not work for KDS (or not well enough) to be considered here.
Additionally, both the KDS supplied gcc and libraries have some pros and cons compared with the GNU GCC ARM Embedded version, see “printf() and scanf() with GNU ARM Libraries“. Especially I noticed that the increased RAM usage of the KDS libraries compared to the GNU GCC ARM Embedded one is a reason to switch the toolchain for memory constraint devices. Code size however is in some cases smaller with the KDS default tool chain, sometimes larter. But if RAM is king, then it makes sense to consider the newer ARM toolchain instead of the default KDS one.
In any case: The good thing with this tool chain swapping is: it is reversible, so it is rather easy to switch back and forward the tool chain.
Tool Chain Integration in KDS
The first thing to look at is where the toolchain is installed within KDS. It is (surprise, surprise!) inside the ‘toolchain’ of the installation folder:
The directory structure is compatible with the GNU ARM version from the launchpad, more about this later one. The binaries (compiler/linker/etc) are in the bin subfolder, for example the gcc compiler as arm-none-eabi-gcc.exe:
How to call the compiler (or all the other parts of the tool chain) is specified in the Eclipse project options. KDS is using the GNU ARM Eclipse plugins, and how to find the compiler is specified in the project settings as below:
For the above (default KDS) settings it means that the compiler is named ‘gcc‘, with a prefix ‘arm-none-eabi-‘. So it will call ‘arm-none-eabi-gcc’ as compiler. The ‘use global toolchain path’ it means it will search the system PATH (on Windows) variable to call that executable.
So this means that you need to have the gcc executable present in the system PATH. I know that many toolchains and IDE’s are modifying the PATH for this, but if you have multiple toolchains and IDE’s, this gets really, really messy. KDS instead is pretty smart: instead that the installer does a system PATH modification, it modifies the system PATH just for Eclipse at the time when I start it. So that change is only and only for that Eclipse instance.
For this, KDS adds to the beginning the path to the toolchain\bin to the system PATH variable (under Windows). Have a look at the Eclipse system variables (menu Window > Preferences > C/C++ > Build > Build Variables):
With the knowledge how things are working, it is pretty easy now to switch the toolchain: as I cannot change the way how KDS is adding the path in an easy way, the simplest way is to swap out the folders and use my different toolchain instead.
Swapping Tool Chains
To be able to easily swap the tool chains, I rename the existing toolchain folder inside KDS e.g. to ‘toolchain.orig’ and place the GNU GCC ARM launchpad release into the normal toolchain folder. The latest GNU GCC ARM can be downloaded as zip file from https://launchpad.net/gcc-arm-embedded.
To easily differentiate the versions, I have a text file inside the folder to identify the tool chain.
There is one thing left: Eclipse uses a make to build the project, and the launchpad tools. The KDS v2.0.0 toolchain\bin includes such a make. The easiest way is to copy that make into the launchpad toolchain\bin folder:
Different Linker Options
While the directory structure is compatible, the linker options are not. If using the newlib-nano, then the linker options are different between the default KDS toolchain and GNU GCC ARM Embedded. KDS is using -nanolibc linker option, while the ARM Inc. launchpad toolchain is using -specs=nano.specs. So that option needs to be changed if switching tool chains. Additionally, I have to switch off the usage of the system library (for file operations) with -specs=nosys.specs (see “Tutorial: DIY Kinetis SDK Project with Eclipse – Startup” about more information on this subject).
The positive effect of using the latest GNU GCC ARM Embedded and libraries is that my application needs less RAM. With the default GNU libraries in KDS the library needs at least around 0x200 bytes of HEAP, otherwise it will crash in the library startup code. This problem was present in earlier versions of the ARM newlib-nano, and has been discussed in the Launchpad forum:
Since then, this has been improved in the latest newlib-nano release from ARM Inc. And because the libraries in KDS do not include that improvement, they need at least around 400 bytes of RAM allocated for the heap as a minimum:
If not using Processor Expert, such an amount of heap needs to be allocated in the linker file:
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0200; STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;
I created with the wizard a project for the FRDM-K64F with both SDK and Processor Expert enabled. With KDS and default GNU tools and libraries I get:
text data bss dec hex filename 7744 680 1252 10176 27c0 kds_sdk_test.elf
While with the new GNU GCC and libraries from launchpad/ARM Inc. no HEAP memory is needed (unless I use the heap, of course), so this greatly reduces the needed RAM for the same application:
text data bss dec hex filename 6544 112 1072 7728 1e30 kds_sdk_test.elf
So with the new libs we have greatly reduced the footprint of the application :-).
That overhead with the heap space in KDS can be avoided with using the normal newlib (not the newlib-nano). However, for this case in KDS, the code size increases, and while there is no heap needed, the RAM size is about the same because now instead of dynamic memory allocation global buffers seem to be used:
text data bss dec hex filename 11908 2160 1288 15356 3bfc kds_sdk_test.elf
With the knowledge how the toolchain is working in KDS, is it is not very difficult to switch to a newer ARM Inc. tool chain, or later to switch back to a earlier version as needed. This is possible as long the compiler and linker switches are compatible. Right now the KDS default toolchain uses a different linker option for the newlib-nano libraries, so this option needs to be updated. Otherwise, things are compatible or I have not seen any issues. As a huge benefit switching to the latest ARM libraries and tool chain is that they need much less RAM, so are better suited for smaller microcontroller.
Happy Switching 🙂