Smartphone Robot

Posted: Oct 10, 2016 in Uncategorized

Hey!

Finally the prototype robot I’ve been developing during my Master’s Degree in Rehabilitation Engineering at Unicamp is coming to life. Despite I cannot tell much at this time as it’s still an ongoing project inside university’s boundaries, here goes a few pictures of the prototype:

still_publish

workout1_publish

waving_publish

Cheers

Advertisements

Watermark

Posted: Oct 10, 2016 in Uncategorized

github.com/coolparadox/watermark is a collection of small scripts I wrote for applying ImageMagick tools to my images prior to publication in the wild.

For example, processing this image:

sample

Can yield this smaller, watermarked and labeled result:

sample_publish

Cheers

Do you have an Android smartphone and would like to go run with it?

This post tracks my adventures setting up a Go builder environment in a Samsung Galaxy S3, no rooting required. Despite the environment is not full featured as a computer’s, it can run the go command fine enough to build and run native arm binaries from Go code.

1. Cross Build Go for Android

Here we’ll compile the Go builder for the Android OS , arm architecture, and have it tested in your smartphone.

Setup ADB

Install Android Debug Bridge in your computer, enable usb debugging in your smartphone, connect computer and smartphone via usb, and make sure adb can see the smartphone.

user@computer ~ $ adb devices -l
List of devices attached
4df173935a2e5fd7 device product:m0ub model:GT_I9300 device:m0
user@computer ~ $ adb shell
shell@m0:/ $ exit
user@computer ~ $

Feel free to disconnect your device now if you want; we’ll reconnect it later.

Setup NDK Toolchain

As building Go for Android requires cgo, there are some bits of C code to be cross compiled also. We need a C cross toolchain for Android.

Download Android Native Development Kit for your system and unpack it somewhere. Optionally, if you use Android Studio and have NDK already installed, you’ll find it under directory ~/Android/Sdk/ndk-bundle.

Create a standalone toolchain package for Android by running NDK’s make-standalone-toolchain script:

user@computer ~ $ mkdir ~/src
user@computer ~ $ cd ~/Android/Sdk/ndk-bundle
user@computer ~/Android/Sdk/ndk-bundle $ ./build/tools/make-standalone-toolchain.sh --arch=arm --install-dir=/home/user/src/ndk-toolchain
WARNING: make-standalone-toolchain.sh will be removed in r13. Please try make_standalone_toolchain.py now to make sure it works for your needs.
HOST_OS=linux
HOST_EXE=
HOST_ARCH=x86_64
HOST_TAG=linux-x86_64
HOST_NUM_CPUS=4
BUILD_NUM_CPUS=8
Auto-config: --toolchain=arm-linux-androideabi-4.9
Auto-config: --platform=android-9
Copying prebuilt binaries...
Copying sysroot headers and libraries...
Copying c++ runtime headers and libraries...
Copying files to: /home/user/src/ndk-toolchain
Cleaning up...
Done.
user@computer ~/Android/Sdk/ndk-bundle $ cd ~/src/ndk-toolchain
user@computer ~/src/ndk-toolchain $ ./bin/arm-linux-androideabi-gcc --version
arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 

Setup Go Bootstrap

As Go is required for building Go, we need a Go compiler installed. I assume your computer has a recent version of Go installed already, so you don’t have to download a binary release of it. If so, just mark down where is the root of your Go system.

user@computer ~ $ go version
go version go1.6.1 linux/amd64
user@computer ~ $ go env GOROOT
/usr/lib/go

Optionally, download and unpack a binary release of Go for your computer, and use it as the Go bootstrap.

Download Go Sources

Download the source package of the latest stable version of Go, and unpack it.

user@computer ~ $ tar -C ~/src -xzf go1.6.1.src.tar.gz 
user@computer ~ $ ls ~/src/go
api AUTHORS CONTRIBUTING.md CONTRIBUTORS doc favicon.ico lib LICENSE misc PATENTS README.md robots.txt src test VERSION

 

Cross Build & Test Go for Android

The Go creators presented us with a script for automating the build of a Go build system for Android. It also transfers the results of the compilation to a temporary location in the target smartphone using adb, and tests all standard packages of the Go build system in the target.

user@computer ~ $ adb devices
List of devices attached
4df173935a2e5fd7 device

user@computer ~ $ cd ~/src/go/src
user@computer ~/src/go/src $ CC_FOR_TARGET=~/src/ndk-toolchain/bin/arm-linux-androideabi-gcc GOROOT_BOOTSTRAP=/usr/lib/go GOARCH=arm ./androidtest.bash
##### Building Go bootstrap tool.
cmd/dist

##### Building Go toolchain using /usr/lib/go.
bootstrap/internal/obj
bootstrap/compile/internal/big
[...]

##### Building go_bootstrap for host, linux/amd64.
runtime/internal/sys
runtime/internal/atomic
[...]

##### Building packages and commands for host, linux/amd64.
runtime/internal/sys
runtime/internal/atomic
[...]

##### Building packages and commands for android/arm.
runtime/internal/sys
runtime/internal/atomic
[...]

# Syncing test files to android device

real 0m17.281s
user 0m0.033s
sys 0m0.130s
[100%] /data/local/tmp/cleaner
2016/07/12 02:57:04 removing /data/local/tmp/goroot/pkg/android_arm64

##### Testing packages.
ok archive/tar 2.877s
ok archive/zip 3.655s
[...]

It pays to check what tests are ok and what failed, as these are standard Go packages prone to be imported by Go applications you build in your Android device. (In my smartphone package runtime/pprof failed.)

Finished androidtest script, optionally remove test files from your device to save storage:

user@computer ~ $ adb shell rm -r /data/local/tmp/goroot

 

Tune Go Root for Android

At this point a Go root for arm coexists in Go sources:

user@computer ~ $ cd ~/src/go/bin
user@computer ~/src/go/bin $ file go android_arm/go
go: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, not stripped
android_arm/go: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, not stripped

As Go by default expects its tools to be found in $GOROOT/bin, let’s tune it for the Android device:

user@computer ~/src/go/bin $ rm *
rm: cannot remove ‘android_arm’: Is a directory
user@computer ~/src/go/bin $ mv android_arm/* .
user@computer ~/src/go/bin $ rmdir android_arm
user@computer ~/src/go/bin $ file *
go: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, not stripped
gofmt: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, not stripped

Later we’ll transfer the arm Go root to the Android device; for now just keep it.

2. Install a Terminal Emulator for Android

I gave Terminal IDE a try. On the first opening, choose Install System button to have the base C / binary system installed.

The Help button shows extensive documentation about this application.

Open a terminal session (Terminal IDE button) to get a prompt where you can run commands. Issuing telnetd in Terminal IDE opens a telnet daemon in port 8080 of your device, so you can access it remotely.

By default Terminal IDE’s prompt shows the full path of the current working directory. I find this cumbersome when I’m deep down into a directory hierarchy, specially in screens with small character width like when running in my smartphone. I prefer adding the following to ~/.bash_aliases,

PS1='\[\033[01;32m\]terminal\[\e[1;31m\]++\[\e[1;33m\]@\[\e[1;35m\]$HOSTNAME\[\033[00m\]:\[\033[01;34m\]\W\[\033[00m\]\$ '

, so the prompt shows only the last piece of my current working directory.

Access Github

Generate a RSA identity for you:

terminal++@192.168.0.102:~$ mkdir -p ~/.ssh
terminal++@192.168.0.102:~$ dropbearkey -t rsa -f ~/.ssh/id_rsa
Will output 1024 bit rsa secret key to '/data/data/com.spartacusrex.spartacuside/files/.ssh/id_rsa'
Generating key, this may take a while...
Public key portion is:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgn/D5RlQauJxTz52CyolrUHhysG4rRN1Gj5ZwF+m06EJoqqiiCdsWDYibrUETSZK/iPCgzPSNFFZQY0RFCb30Ovxa5iIIj8lcdBg/9abB26UoFgPsT49IBfrwpboZHfnMStEyZdMVyRvd0LbenxqdfWD14CuX4vcaK2jkGg5GLeet5E= u0_a138@localhost
Fingerprint: md5 22:e9:32:5a:d7:35:7b:35:69:6b:66:5f:7c:b8:55:b7

Import the public key portion to your github account to identify ssh connections from this terminal. To retrieve the public key at any time, run dropbearkey -y -f ~/.ssh/id_rsa.

Instruct git client to use this identity when accessing repositories through ssh. You can do this by creating file ~/local/bin/ssh-git with the following content:

#!/data/data/com.spartacusrex.spartacuside/files/system/bin/bash
exec ssh -i ~/.ssh/id_rsa "$@"

Make sure the file is executable. Then add the following to ~/.bash_aliases, replacing with your name and email:

export GIT_SSH=~/local/bin/ssh-git
export GIT_AUTHOR_NAME="Your Name"
export GIT_AUTHOR_EMAIL="youremail@provider.com"
export GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
export GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL

Restart your terminal session. Cloning from github should work fine now:

terminal++@192.168.0.102:~$ cd tmp
terminal++@192.168.0.102:tmp$ git clone git@github.com:coolparadox/go 
Cloning into 'go'...
remote: Counting objects: 989, done.
remote: Total 989 (delta 0), reused 0 (delta 0), pack-reused 989
Receiving objects: 100% (989/989), 174.42 KiB | 55 KiB/s, done.
Resolving deltas: 100% (559/559), done.

 

Setup Go Root

Let’s transfer the Android Go root that was cross built in the previous chapter to the device. In terminal:

terminal++@192.168.0.102:~$ mkdir -p ~/opt/go ~/opt/bin
terminal++@192.168.0.102:~$ chmod 0777 ~/opt/go ~/opt
terminal++@192.168.0.102:~$ mkdir ~/sdcard/go

In computer:

user@computer ~ $ adb push ~/src/go /data/data/com.spartacusrex.spartacuside/files/opt/go/root
adb: warning: skipping empty directory '/home/lorandi/src/go/pkg/obj/linux_amd64/'
adb: warning: skipping empty directory '/home/lorandi/src/go/pkg/android_arm/'
/data/data/com.spartacusrex.spartacuside/files/opt/go/root/: 5832 files pushed. 2 files skipped. 3.4 MB/s (438423127 bytes in 124.141s)

Also add the following to ~/.bash_aliases:

export GOROOT=~/opt/go/root
export GOPATH=~/sdcard/go
export GOBIN=~/opt/go/bin

And make symlinks to go commands:

terminal++@192.168.0.102:~$ ln -s ~/opt/go/root/bin/go* ~/local/bin/

Restart terminal. Go command should be reachable by now.

terminal++@192.168.0.102:~$ go version 
go version go1.6.1 android/arm
terminal++@192.168.0.102:~$ go doc fmt.Printf 
func Printf(format string, a ...interface{}) (n int, err error)
 Printf formats according to a format specifier and writes to standard
 output. It returns the number of bytes written and any write error
 encountered.

 

Try to Build hello.go

For testing, you can follow the official instructions for first timers, or optionally retrieve a hello world sample application from my github account:

terminal++@192.168.0.102:~$ cd $GOPATH 
terminal++@192.168.0.102:go$ cd src 
terminal++@192.168.0.102:src$ mkdir -p github.com/coolparadox 
terminal++@192.168.0.102:src$ cd github.com/coolparadox/ 
terminal++@192.168.0.102:coolparadox$ git clone git@github.com:coolparadox/go 
Cloning into 'go'...
remote: Counting objects: 994, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 994 (delta 1), reused 0 (delta 0), pack-reused 989
Receiving objects: 100% (994/994), 175.08 KiB | 73 KiB/s, done.
Resolving deltas: 100% (560/560), done.
terminal++@192.168.0.102:coolparadox$ cd go/hello 
terminal++@192.168.0.102:hello$ ls 
hello.go
terminal++@192.168.0.102:hello$ cat hello.go 
package main

import "fmt"

func main() {
 fmt.Println("Hello world!")
}

Let’s build and run it with go run command. If it goes fine,

terminal++@192.168.0.102:hello$ go run hello.go 
Hello world!

, then we’re all set and you can skip to the next chapter. Chances are however that the compilation fails due to a missing linker:

terminal++@192.168.0.102:hello$ go run hello.go 
# command-line-arguments
/data/data/com.spartacusrex.spartacuside/files/opt/go/root/pkg/tool/android_arm/link: running /home/lorandi/src/ndk-toolchain/bin/arm-linux-androideabi-gcc failed: fork/exec /home/lorandi/src/ndk-toolchain/bin/arm-linux-androideabi-gcc: no such file or directory

If so, keep reading.

Setup an External Linker for Go

Install the GNU compiler,

terminal++@192.168.0.102:~$ install_gcc
Extracting GCC.. Please wait..
GCC 4.4.0 Installed

, and make sure it works:

terminal++@192.168.0.102:tmp$ cat hello.c 
#include <stdio.h>

int main() {
 printf("Hello world!\n");
}
terminal++@192.168.0.102:tmp$ arm-eabi-gcc -mandroid -o hello hello.c 
terminal++@192.168.0.102:tmp$ ./hello 
Hello world!

Back to hello.go, let’s try again instructing Go to make use of the external linker:

terminal++@192.168.0.102:hello$ CC=arm-eabi-gcc go run -ldflags '-extldflags=-mandroid' hello.go 
Hello world!

Yay it works!!

Obviously we don’t want to type this ugly long line on each go run invocation. Add the following to ~/.bash_aliases:

export CC=arm-eabi-gcc
export CXX=arm-eabi-g++

And restart. Getting rid of -ldflags part is trickier, as I haven’t found a way of doing this using environment variables. I came up creating a wrapper script for the go command that appends this option when building, and replaced ~/local/bin/go with it:

terminal++@192.168.0.102:~$ cat ~/local/bin/go
set -e
GO=$GOROOT/bin/go
test $# -gt 0 || {
    set -x
    exec $GO
}
COMMAND=$1
shift
BUILD_OPT=''
case $COMMAND in
    build|clean|get|install|list|run|test)
        BUILD_OPT=-ldflags\ -extldflags=-mandroid
        ;;
esac
set -x
exec $GO $COMMAND $BUILD_OPT $*

Testing everything again:

terminal++@192.168.0.102:hello$ go env CC
++ exec /data/data/com.spartacusrex.spartacuside/files/opt/go/root/bin/go env CC
arm-eabi-gcc
terminal++@192.168.0.102:hello$ go run hello.go 
++ exec /data/data/com.spartacusrex.spartacuside/files/opt/go/root/bin/go run -ldflags -extldflags=-mandroid hello.go
Hello world!

(Later you’ll probably want to remove both set -x lines from go wrapper script.)

My Own ~/.bash.aliases

terminal++@quark:~$ cat ~/.bash_aliases
export HOSTNAME=quark

export GIT_SSH=~/local/bin/ssh-git
export GIT_AUTHOR_NAME="Rafael Lorandi"
export GIT_AUTHOR_EMAIL="coolparadox@gmail.com"
export GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
export GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL

export CC=arm-eabi-gcc
export CXX=arm-eabi-g++

export GOROOT=~/opt/go/root
export GOPATH=~/sdcard/go
export GOBIN=~/opt/go/bin

alias gst='git status'
alias gbr='git branch'

PS1='\[\033[01;32m\]terminal\[\e[1;31m\]++\[\e[1;33m\]@\[\e[1;35m\]$HOSTNAME\[\033[00m\]:\[\033[01;34m\]\W\[\033[00m\]\$ '

 

3. Pain Spots

Despite doing Go in Android smartphone is awesome and can genuinely aid with your Go developments, the solution showed here is not all roses.

It’s a Small Screen

As you can imagine, a smartphone is not exactly the most enjoyable environment to develop software.

No DNS Resolution

Terminal IDE does not resolve names. You must workaround it by making use of its jping utility and replace IP addresses manually.

Old Git

terminal++@quark:~$ git --version
git version 1.7.8.163.g9859a.dirty

Git deployed with Terminal IDE doesn’t support https protocol nor submodules. Although the former can be worked around, the latter renders impossible to go get stuff:

terminal++@quark:~$ go get -d github.com/coolparadox/go 
# cd /data/data/com.spartacusrex.spartacuside/files/sdcard/go/src/github.com/coolparadox/go; git submodule update --init --recursive
fatal: cannot exec 'git-submodule': Permission denied
package github.com/coolparadox/go: exit status 255

As a workaround, use -x option with go get to trace internal commands, and manually clone Go repositories.

Moreover I cannot push to my github repos through Terminal IDE’s git:

terminal++@quark:go$ git push 
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 274 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
fatal: The remote end hung up unexpectedly
fatal: The remote end hung up unexpectedly

A workaround is clone Go repositories in a public of your Android device (eg. ~/sdcard/go/src), and use another git app for pushing.

4. Issues to Be Addressed Someday

Despite Terminal IDE is a fantastic app for the developer, it’s not being actively updated anymore (lastest release at the moment of writing was March 3 2013).

5. References

português

While developing for the FRDM-KL25Z board using my own compilation of a gcc crosstoolchain, I’ve noticed a weirdness when my code makes use of integer division (/) or modulus (%) operations.

My arm-none-eabi crosstoolchain is based in binutils 2.24, gcc 4.8.2 and newlib 2.1.0. When executing / or % operations, execution crashes in one of ____aeabi_[u]idiv[mod]_from_thumb() runtime AEABI calls. This is a gdb backtrace of a tentative of %:

(gdb) bt
#0  Cpu_Interrupt () at Generated_Code/Cpu.c:85
#1  <signal handler called>
#2  0x0000236c in ____aeabi_uidivmod_from_thumb ()
#3  0x000021aa in LEDTimer_OnInterrupt (UserDataPtr=0x0 <__vect_table>) at Sources/Events.c:80
#4  0x00001f98 in TU1_OnCounterRestart (UserDataPtr=0x0 <__vect_table>) at Generated_Code/LEDTimer.c:149
#5  0x00002126 in TU1_Interrupt () at Generated_Code/TU1.c:185
#6  <signal handler called>
#7  main () at Sources/ProcessorExpert.c:66

This behavior is persistent even when compiling and linking with Cortex-M0 tuned options such as -mcpu=cortex-m0 -mthumb -mfloat-abi=soft.

It has been reported that gcc is generating wrong opcodes for Cortex-M0 when linking these aeabi runtime calls. One workaround is to link your code with an external, Cortex-M0 compatible aeabi such as libaeabi-cortexm0 by Jörg Mische.

When using libaeabi-cortexm0 in a Processor Expert project for FRDM-KL25Z in Linux, compile the library without crt.S in order to avoid duplicate symbols in the linking stage.

I updated my led blinking application for using a % operation in LEDTimer_OnInterrupt(), and also linking with libaeabi-cortexm0: frdm-kl25z-blink3-1.1.tar.gz. For details in how to build this application in Gentoo Linux, see Developing for FRDM-KL25Z platform in Linux.

português

Table of contents:

  1. Introduction
  2. Crosstoolchain
  3. Building
  4. Flashing
  5. Debugging

Previously in Flashing a led blinking application was recorded to FRDM-KL25Z board for execution. Here we use the GNU debugger for debugging this application during execution.

Build a cross debugger for ARM

localhost ~ # crossdev --ex-gdb -t arm-none-eabi
...

This should leave in your Gentoo system a cross gdb for the intended architecture:

localhost ~ # arm-none-eabi-gdb -ex quit
Python Exception  name 'os' is not defined: 

warning: 
Could not load the Python gdb module from `/usr/share/gdb/python'.
Limited Python support is available from the _gdb module.
Suggest passing --data-directory=/path/to/gdb/data-directory.

GNU gdb (Gentoo 7.7 vanilla) 7.7
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word".

Use OpenOCD as a remote end for gdb

OpenOCD has the ability of serving as the remote end of a gdb session, allowing debug commands to be sent to the board’s on-chip debugger. The Makefile in frdm-kl25z-blink3 sources has a target for setting up a cross gdb session with openocd as the remote for debugging frdm_kl25z_blink3:

user@localhost /tmp/frdm-kl25z-blink3-1.0 $ make debug
arm-none-eabi-gdb -ex "target remote | openocd -c \"gdb_port pipe; log_output debug.log; interface cmsis-dap\"
 -f ./support/openocd/kl25_init.cfg" -ex "monitor reset init" -ex "break main" -ex "continue" frdm_kl25z_blink3
Python Exception  name 'os' is not defined: 

warning: 
Could not load the Python gdb module from `/usr/share/gdb/python'.
Limited Python support is available from the _gdb module.
Suggest passing --data-directory=/path/to/gdb/data-directory.

GNU gdb (Gentoo 7.7 vanilla) 7.7
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from frdm_kl25z_blink3...done.
Remote debugging using | openocd -c "gdb_port pipe; log_output debug.log; interface cmsis-dap" -f ./support/openocd/kl25_init.cfg
Open On-Chip Debugger 0.8.0-dev-00350-g6c74255 (2014-02-14-16:00)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.sourceforge.net/doc/doxygen/bugs.html
warning: Can not parse XML target description; XML support was disabled at compile time
0x00000000 in __vect_table ()
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x00002038 msp: 0x20003000
Breakpoint 1 at 0x2114: file Sources/ProcessorExpert.c, line 53.
Continuing.

Breakpoint 1, main () at Sources/ProcessorExpert.c:53
53        PE_low_level_init();
(gdb)

As currently written, the debug target should restart execution of the application and stop in function main() due to a breakpoint. So at this state the execution is stopped (RGB led ceases to blink) and gdb is awaiting for debug commands.

Debug 🙂

Well it’s gdb; feel free to poke around for insightful debugging. The following is an example of catching the timer interruption handler where led colors are cycled:

(gdb) clear
Deleted breakpoint 1 
(gdb) break LEDTimer_OnInterrupt
Breakpoint 2 at 0x2078: file Sources/Events.c, line 80.
(gdb) continue
Continuing.

Breakpoint 2, LEDTimer_OnInterrupt (UserDataPtr=0x0 ) at Sources/Events.c:80
80              switch (led_state++) {
(gdb) list
75      /* ===================================================================*/
76      void LEDTimer_OnInterrupt(LDD_TUserData *UserDataPtr)
77      {
78        /* Write your code here ... */
79              static int led_state = 0;
80              switch (led_state++) {
81              case 0:
82                      RedLED_SetVal(RedLED_DeviceData);
83                      GreenLED_SetVal(GreenLED_DeviceData);
84                      BlueLED_SetVal(BlueLED_DeviceData);
(gdb) display led_state
1: led_state = 0
(gdb) continue
Continuing.

Breakpoint 2, LEDTimer_OnInterrupt (UserDataPtr=0x0 ) at Sources/Events.c:80
80              switch (led_state++) {
1: led_state = 1
(gdb) next
87                      RedLED_ClrVal(RedLED_DeviceData);
1: led_state = 2
(gdb) next
88                      break;
1: led_state = 2
(gdb) continue
Continuing.

Breakpoint 2, LEDTimer_OnInterrupt (UserDataPtr=0x0 ) at Sources/Events.c:80
80              switch (led_state++) {
1: led_state = 2
(gdb) continue
Continuing.

Breakpoint 2, LEDTimer_OnInterrupt (UserDataPtr=0x0 ) at Sources/Events.c:80
80              switch (led_state++) {
1: led_state = 3
(gdb) clear
Deleted breakpoint 2 
(gdb) continue
Continuing.
^C
Program received signal SIGINT, Interrupt.
main () at Sources/ProcessorExpert.c:66
66        for(;;){}
1: led_state = 6
(gdb) quit
A debugging session is active.

        Inferior 1 [Remote target] will be detached.

Quit anyway? (y or n) y
Detaching from program: /tmp/frdm-kl25z-blink3-1.0/frdm_kl25z_blink3, Remote target
Ending remote debugging.

user@localhost /tmp/frdm-kl25z-blink3-1.0 $ 

português

Table of contents:

  1. Introduction
  2. Crosstoolchain
  3. Building
  4. Flashing
  5. Debugging

Previously in Building we generated an ELF executable file as the result of building the frdm-kl25z-blink3 application:

user@localhost /tmp/frdm-kl25z-blink3-1.0 $ file frdm_kl25z_blink3 
frdm_kl25z_blink3: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped

Here we manage to record this file to the board’s flash memory for execution.

Update FRDM-KL25Z board with a CMSIS-DAP firmware

First, extract file CMSIS-DAP.S19 from Keil Application Note 232. This is a firwmare for FRDM-KL25Z that supports the CMSIS-DAP interface to the board’s on-chip debugger.

The following steps must be performed on Windows: Next, enter Bootloader mode in board by holding down the Reset button while plugging in an USB cable to the OpenSDA connector and your computer. (When the D4 led blinks you can release the button as this indicates bootloader mode.) The MSD Bootloader appears in Windows as a removable drive with a volume label of BOOTLOADER. Copy file CMSIS_DAP.s19 into the BOOTLOADER drive, wait for a few seconds and unplug the board.

Back to Gentoo Linux, replug the board and check for usb device with vendor ID 0xc251 and product ID 0xf002:

localhost ~ # lsusb
Bus 001 Device 023: ID c251:f002 Keil Software, Inc. 
...

Create file /etc/udev/rules.d/99-frdm-kl25z-cmsis-dap.rules containing:

SUBSYSTEM=="usb", ATTR{idVendor}=="c251", ATTR{idProduct}=="f002", MODE="0660", GROUP="plugdev"
SUBSYSTEM=="hidraw", ACTION=="add", MODE="0660", GROUP="plugdev"

Unplug and replug the board again, and check that the created hidraw device file belongs to the plugdev group and is group writable:

localhost ~ # ls -l /dev/hidraw*
crw-rw---- 1 root plugdev 252, 0 Mar 10 21:58 /dev/hidraw0
...

This allows the flashing process to be performed by normal users belonging to the plugdev group.

Install OpenOCD with CMSIS-DAP support

For communicating with FRDM-KL25Z on-chip debugger in order to perform flashing, we use OpenOCD. Unfortunately at the moment of this writing the latest available version of OpenOCD from Portage tree (0.7.0-r1) does not support CMSIS-DAP; however I successfully used OpenOCD from openocd.zylin.com for flashing. You may want to grab a snapshot of the latest openocd source tree, unpack, build and install it:

localhost ~/src/openocd # ./configure --enable-cmsis-dap
...
OpenOCD configuration summary
--------------------------------------------------
CMSIS-DAP Compliant Debugger            yes

localhost ~/src/openocd # make
...

localhost ~/src/openocd # make install
...

In a clean Gentoo Linux system the configure phase will likely fail due to missing libraries and softwares; just emerge any required stuff and resume the process as shown above. You should end with a working openocd installation:

localhost ~ # openocd --version
Open On-Chip Debugger 0.8.0-dev-00350-g6c74255 (2014-02-14-16:00)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.sourceforge.net/doc/doxygen/bugs.html

Flash frdm_kl25z_blink3 using OpenOCD

The Makefile in frdm-kl25z-blink3 sources has a target for taking care of flashing:

user@localhost /tmp/frdm-kl25z-blink3-1.0 $ make flash
openocd \
        -c 'interface cmsis-dap' \
        -f ./support/openocd/kl25_init.cfg \
        -f ./support/openocd/kl25_flash.cfg
Open On-Chip Debugger 0.8.0-dev-00350-g6c74255 (2014-02-14-16:00)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.sourceforge.net/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'cmsis-dap'
Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: Interface Initialised (SWD)
cortex_m reset_config sysresetreq
adapter speed: 50 kHz
Info : add flash_bank kinetis kl25.flash
#0 : kl25.flash (kinetis) at 0x00000000, size 0x00000000, buswidth 0, chipwidth 0
Info : CMSIS-DAP: FW Version = 1.0
Info : SWCLK/TCK = 0 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : DAP_SWJ Sequence (reset: 50+ '1' followed by 0)
Info : CMSIS-DAP: Interface ready
Info : clock speed 50 kHz
Info : IDCODE 0x0bc11477
Info : kl25.cpu: hardware has 2 breakpoints, 2 watchpoints
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x00002038 msp: 0x20003000
** Programming Started **
auto erase enabled
Info : Probing flash info for bank 0
Info : Padding image section 0 with 832 bytes
Warn : flash configuration field erased, please reset the device
Warn : Kinetis L Series supports Program Longword execution only.
Info : Kinetis: FLASH Write ...
wrote 11264 bytes from file frdm_kl25z_blink3 in 14.069720s (0.782 KiB/s)
** Programming Finished **
** Verify Started **
verified 10060 bytes in 1.938245s (5.069 KiB/s)
** Verified OK **
** Resetting Target **
shutdown command invoked

If flashing succeeds the application should start automatically and the RGB led should blink repeatedly in a succession of red, green and blue colors.

Next in Debugging we’ll use OpenOCD as a remote server for the GNU debugger, so we can debug the flashed application.


References

português

Table of contents:

  1. Introduction
  2. Crosstoolchain
  3. Building
  4. Flashing
  5. 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, unzip binary/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.

português

Table of contents:

  1. Introduction
  2. Crosstoolchain
  3. Building
  4. Flashing
  5. Debugging

In order to compile software for FRDM-KL25Z board we must be able to generate object code for ARM CPUs. It’s very likely that your Gentoo system runs on a non-ARM computer, so we require tools for handling generation and manipulation of object code targeted to a CPU architecture other that your computer’s.

Install crossdev, the Gentoo cross-toolchain generator:

localhost ~ # emerge sys-devel/crossdev

Have crossdev to build C cross-compiler, libc and other build tools for ARM CPUs:

localhost ~ # crossdev -t arm-none-eabi
-----------------------------------------------------------
 * crossdev version:      20131107
 * Host Portage ARCH:     amd64
 * Target Portage ARCH:   arm
 * Target System:         arm-none-eabi
 * Stage:                 3 (C compiler & libc)
 * ABIs:                  default

 * binutils:              binutils-[latest]
 * gcc:                   gcc-[latest]
 * libc:                  newlib-[latest]



 * Log: /var/log/portage/cross-arm-none-eabi-binutils.log
 * Emerging cross-binutils ... [ ok ]
 * Log: /var/log/portage/cross-arm-none-eabi-gcc-stage1.log
 * Emerging cross-gcc-stage1 ... [ ok ]
 * Log: /var/log/portage/cross-arm-none-eabi-newlib.log
 * Emerging cross-newlib ... [ ok ]

Now your Gentoo system contains a damn good GNU cross-toolchain that can build code for ARM CPUs. All tools are prefixed by arm-none-eabi- indicating their purpose of being cross-tools for ARM in your non-ARM system:

user@localhost ~ $ cd /usr/bin
user@localhost /usr/bin $ ls arm-none-eabi-*
arm-none-eabi-addr2line  arm-none-eabi-gcc-4.8.2   arm-none-eabi-nm
arm-none-eabi-ar         arm-none-eabi-gcc-ar      arm-none-eabi-objcopy
arm-none-eabi-as         arm-none-eabi-gcc-nm      arm-none-eabi-objdump
arm-none-eabi-c++filt    arm-none-eabi-gcc-ranlib  arm-none-eabi-pkg-config
arm-none-eabi-cpp        arm-none-eabi-gcov        arm-none-eabi-ranlib
arm-none-eabi-cpp-4.8.2  arm-none-eabi-gcov-4.8.2  arm-none-eabi-readelf
arm-none-eabi-dwp        arm-none-eabi-gdb         arm-none-eabi-run
arm-none-eabi-elfedit    arm-none-eabi-gprof       arm-none-eabi-size
arm-none-eabi-emerge     arm-none-eabi-ld          arm-none-eabi-strings
arm-none-eabi-fix-root   arm-none-eabi-ld.bfd      arm-none-eabi-strip
arm-none-eabi-gcc        arm-none-eabi-ld.gold

For quick checking the usability of the cross-compiler, you can create a file named hello.c containing:

#include <stdio.h>

int main() {

        printf("Hello world\n");
        return 0;

}

Let’s see if the cross-compiler can generate executables for ARM:

user@localhost ~ $ arm-none-eabi-gcc -o hello hello.c 
user@localhost ~ $ file hello
hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped

Looks good.

Next in Building we’ll use the cross-toolchain to build an application developed specifically for the FRDM-KL25Z board.

português

Table of contents:

  1. Introduction
  2. Crosstoolchain
  3. Building
  4. Flashing
  5. Debugging

This series of posts depict my trials on building, flashing and debugging a sample application for the Freescale FRDM-KL25Z board in Gentoo GNU/Linux OS. The application (a simple multicolor LED blinking program) was originally developed using CodeWarrior 10.4 with Processor Expert for Windows. The relevant source files of the application were copied without any changes and compiled in Linux using GNU Autotools for configuring the build process.

What is covered:

  • Setup of an ARM crosstoolchain in Gentoo Linux;
  • Cross-building in Linux an application developed with CodeWarrior IDE;
  • Flashing an application to FRDM-KL25Z board in Linux;
  • Debugging a FRDM-KL25Z application in Linux.

A few things that are NOT covered:

  • Executing CodeWarrior IDE in Linux;
  • Updating sources of applications using Processor Expert in Linux;
  • Integration with Eclipse;
  • Setup steps known to be effective in GNU/Linux distros other than Gentoo (although a great deal of them is expected to be compatible).

Note: for an excellent tutorial on setting up a free and functional GNU gcc + Eclipse + debugger environment for use with the Freescale FRDM-KL25Z board in Windows, take a look at DIY Free Toolchain for Kinetis

Whenever possible, all instructions make use of free software tools.

Let’s get started in Crosstoolchain where we setup build tools for ARM CPUs in your Gentoo Linux system.

português

Electromyography (EMG) is a technique for evaluating and recording the electrical activity produced by skeletal muscles.

Presentation on EMG (Brazilian Portuguese)