Table of contents:
- Introduction
- Crosstoolchain
- Building
- Flashing
- Debugging
Despite a fair amount of tuning parameters is required to be passed to the builder, conceptually the process of building proper ARM executables for FRDM-KL25Z board is virtually the same as every other software building based on compilation and linking:
- Preprocessing, where preprocessor symbols are resolved for each source code file (
.c
) of the project; - Compilation, where the results of preprocessing are parsed and an object code file (
.o
) is generated for each source code file. Object files contain machine code descriptions of functions written by the programmer; - Linking, where all object code files of the project are combined among themselves and with system libraries for resolution of function call dependencies. Typically the main result of the linking stage is an executable file for the target CPU architecture.
As an example of building I wrote a simple RGB LED blinking program for FRDM-KL25Z; please unpack it somewhere in your filesystem: frdm-kl25z-blink3-1.0.tar.gz
frdm-kl25z-blink3 was originally developed with CodeWarrior 10.4 for Windows, the official IDE from Freescale for development on kinetis and other products at the time of this writing. Codewarrior is delivered as an Eclipse based bundle and has a free (as in “free beer”) release for Windows that allows quick initial setup of board resources using Freescale Processor Expert technology. For Linux building of this CodeWarrior project I grabbed the following directories of the project’s workspace:
Generated_Code
(allocation of board resources)Project_Settings/Linker_Files
(linker definitions)Project_Settings/Startup_Code
(registration of external function calls for program startup and termination)Sources
(event callbacks and main program entry point, this is where virtually all further development takes place after board resource configuration)
Moreover, as these files were generated by Processor Expert, for proper preprocessing and linking they depend on additional CodeWarrior system headers and ARM libraries. You need the following directories from a (Windows) CodeWarrior installation:
MCU/ARM_GCC_Support/ewl
(Freescale Embedded Warrior Libraries)MCU/ProcessorExpert/lib/Kinetis/pdd/inc
(Kinetis PDD headers)
If you don’t have access to a Windows installation of CodeWarrior, you can as well download the free CodeWarrior for Microcontrollers 10.4 (Eclipse, offline) installer from Freescale, open it with file-roller (or other archive manager of your choice) and:
- unzip
com.freescale.mcu10_4.kinetis.updatesite.zip
, unzipbinary/com.freescale.kinetis.gcc_root_1.0.2
, and copy MCU/ARM_GCC_Support/ewl - unzip
Setup.exe
, and copy $_OUTDIR/ProcessorExpert/lib/Kinetis/pdd/inc
The frdm-kl25z-blink3 project comes with a configuration script for checking the existence of these system directories as well as other issues that may affect the building. Edit build.sh
for updating PDD_HEADERS_DIR and EWL_DIR with the correct locations of the above mentioned directories, and execute it for building the frdm_kl25z_blink3
ELF file for ARM:
user@localhost /tmp/frdm-kl25z-blink3-1.0 $ ./build.sh checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for arm-none-eabi-strip... arm-none-eabi-strip checking for a thread-safe mkdir -p... /bin/mkdir -p checking for gawk... gawk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking for arm-none-eabi-gcc... arm-none-eabi-gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... yes checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether arm-none-eabi-gcc accepts -g... yes checking for arm-none-eabi-gcc option to accept ISO C89... none needed checking for style of include used by make... GNU checking dependency style of arm-none-eabi-gcc... gcc3 checking if Generated_Code/IO_Map.h exists in sources... yes checking for Kinetis PDD headers location... /opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc checking for GPIO_PDD.h... yes checking for LPTMR_PDD.h... yes checking for EWL headers location... /opt/Freescale/MCU/ARM_GCC_Support/ewl checking how to run the C preprocessor... arm-none-eabi-gcc -E checking for grep that handles long lines and -e... /bin/grep checking for egrep... /bin/grep -E checking for ANSI C header files... yes checking for sys/types.h... no checking for sys/stat.h... no checking for stdlib.h... yes checking for string.h... yes checking for memory.h... no checking for strings.h... no checking for inttypes.h... yes checking for stdint.h... yes checking for unistd.h... no checking ansi_parms.h usability... yes checking ansi_parms.h presence... yes checking for ansi_parms.h... yes checking CWCPlusLib.h usability... yes checking CWCPlusLib.h presence... yes checking for CWCPlusLib.h... yes checking runtime_configuration.h usability... yes checking runtime_configuration.h presence... yes checking for runtime_configuration.h... yes checking if Project_Settings/Linker_Files/ProcessorExpert.ld exists in sources... yes checking for __init_registers in -lrt... yes checking that generated files are newer than configure... done configure: creating ./config.status config.status: creating Makefile config.status: creating config.h config.status: executing depfiles commands make all-am make[1]: Entering directory `/tmp/frdm-kl25z-blink3-1.0' arm-none-eabi-gcc -DHAVE_CONFIG_H -I. -I./Sources -I./Generated_Code -I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT BlueLED.o -MD -MP -MF .deps/BlueLED.Tpo -c -o BlueLED.o `test -f 'Generated_Code/BlueLED.c' || echo './'`Generated_Code/BlueLED.c mv -f .deps/BlueLED.Tpo .deps/BlueLED.Po arm-none-eabi-gcc -DHAVE_CONFIG_H -I. -I./Sources -I./Generated_Code -I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT Cpu.o -MD -MP -MF .deps/Cpu.Tpo -c -o Cpu.o `test -f 'Generated_Code/Cpu.c' || echo './'`Generated_Code/Cpu.c mv -f .deps/Cpu.Tpo .deps/Cpu.Po arm-none-eabi-gcc -DHAVE_CONFIG_H -I. -I./Sources -I./Generated_Code -I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT GreenLED.o -MD -MP -MF .deps/GreenLED.Tpo -c -o GreenLED.o `test -f 'Generated_Code/GreenLED.c' || echo './'`Generated_Code/GreenLED.c mv -f .deps/GreenLED.Tpo .deps/GreenLED.Po arm-none-eabi-gcc -DHAVE_CONFIG_H -I. -I./Sources -I./Generated_Code -I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT LEDTimer.o -MD -MP -MF .deps/LEDTimer.Tpo -c -o LEDTimer.o `test -f 'Generated_Code/LEDTimer.c' || echo './'`Generated_Code/LEDTimer.c mv -f .deps/LEDTimer.Tpo .deps/LEDTimer.Po arm-none-eabi-gcc -DHAVE_CONFIG_H -I. -I./Sources -I./Generated_Code -I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT PE_LDD.o -MD -MP -MF .deps/PE_LDD.Tpo -c -o PE_LDD.o `test -f 'Generated_Code/PE_LDD.c' || echo './'`Generated_Code/PE_LDD.c mv -f .deps/PE_LDD.Tpo .deps/PE_LDD.Po arm-none-eabi-gcc -DHAVE_CONFIG_H -I. -I./Sources -I./Generated_Code -I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT RedLED.o -MD -MP -MF .deps/RedLED.Tpo -c -o RedLED.o `test -f 'Generated_Code/RedLED.c' || echo './'`Generated_Code/RedLED.c mv -f .deps/RedLED.Tpo .deps/RedLED.Po arm-none-eabi-gcc -DHAVE_CONFIG_H -I. -I./Sources -I./Generated_Code -I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT TU1.o -MD -MP -MF .deps/TU1.Tpo -c -o TU1.o `test -f 'Generated_Code/TU1.c' || echo './'`Generated_Code/TU1.c mv -f .deps/TU1.Tpo .deps/TU1.Po arm-none-eabi-gcc -DHAVE_CONFIG_H -I. -I./Sources -I./Generated_Code -I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT Vectors.o -MD -MP -MF .deps/Vectors.Tpo -c -o Vectors.o `test -f 'Generated_Code/Vectors.c' || echo './'`Generated_Code/Vectors.c mv -f .deps/Vectors.Tpo .deps/Vectors.Po arm-none-eabi-gcc -DHAVE_CONFIG_H -I. -I./Sources -I./Generated_Code -I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT __arm_end.o -MD -MP -MF .deps/__arm_end.Tpo -c -o __arm_end.o `test -f 'Project_Settings/Startup_Code/__arm_end.c' || echo './'`Project_Settings/Startup_Code/__arm_end.c mv -f .deps/__arm_end.Tpo .deps/__arm_end.Po arm-none-eabi-gcc -DHAVE_CONFIG_H -I. -I./Sources -I./Generated_Code -I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT __arm_start.o -MD -MP -MF .deps/__arm_start.Tpo -c -o __arm_start.o `test -f 'Project_Settings/Startup_Code/__arm_start.c' || echo './'`Project_Settings/Startup_Code/__arm_start.c mv -f .deps/__arm_start.Tpo .deps/__arm_start.Po arm-none-eabi-gcc -DHAVE_CONFIG_H -I. -I./Sources -I./Generated_Code -I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT Events.o -MD -MP -MF .deps/Events.Tpo -c -o Events.o `test -f 'Sources/Events.c' || echo './'`Sources/Events.c mv -f .deps/Events.Tpo .deps/Events.Po arm-none-eabi-gcc -DHAVE_CONFIG_H -I. -I./Sources -I./Generated_Code -I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT ProcessorExpert.o -MD -MP -MF .deps/ProcessorExpert.Tpo -c -o ProcessorExpert.o `test -f 'Sources/ProcessorExpert.c' || echo './'`Sources/ProcessorExpert.c mv -f .deps/ProcessorExpert.Tpo .deps/ProcessorExpert.Po arm-none-eabi-gcc -DHAVE_CONFIG_H -I. -I./Sources -I./Generated_Code -I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include -I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT sa_mtb.o -MD -MP -MF .deps/sa_mtb.Tpo -c -o sa_mtb.o `test -f 'Sources/sa_mtb.c' || echo './'`Sources/sa_mtb.c mv -f .deps/sa_mtb.Tpo .deps/sa_mtb.Po arm-none-eabi-gcc -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -Xlinker --gc-sections -n -L/opt/Freescale/MCU/ARM_GCC_Support/ewl/lib/armv6-m -T./Project_Settings/Linker_Files/ProcessorExpert.ld -o frdm_kl25z_blink3 BlueLED.o Cpu.o GreenLED.o LEDTimer.o PE_LDD.o RedLED.o TU1.o Vectors.o __arm_end.o __arm_start.o Events.o ProcessorExpert.o sa_mtb.o -lrt make[1]: Leaving directory `/tmp/frdm-kl25z-blink3-1.0' frdm_kl25z_blink3: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped
Next in Flashing we record the frdm_kl25z_blink3 ELF to the FRDM-KL25Z board for execution.