I have installed and tested different tools for debugging the Freescale kinetis family of ARM micro-controllers utilizing the SWD debug port on the freedom boards, but not yet the J-link GDB server by Segger.
The main reason I got interested in the J-link GDB server was because i wanted to try out semihosting, the SWI interface which is common across all debug agents provided by ARM Limited.
what is semihosting?
Semihosting is a mechanism for ARM targets to communicate input/output requests from application code to a host computer running a debugger. This mechanism could be used, for example, to enable functions in the C library, such as
scanf(), to use the screen and keyboard of the host rather than having a screen and keyboard on the target system.
This is useful because development hardware often does not have all the input and output facilities of the final system. Semihosting enables the host computer to provide these facilities. Cited: arm infocenter
The standard C library for input-output is pretty big for including and using to implement this, so what really happens is that we have newlib, or some stripped down flavor of it that implements similar functionality. When this is done with newlib stdio version, sometimes you will need up to more than 32K of ROM and 2+K of RAM just to output two lines of code! You need to be careful using it on a controller with limited memory. Its because of this that a simpler printf is sometimes implemented in inline assembly using a SuperVisor Call to output a character, see this post on using semihosting with Qemu for details.
In a nutshell, for example the implementation of SVC SYS_WRITEC is: you load R1 with an address to a character,R0 with 0x03 and execute a SuperVisor Call (SVC 0x00123456).
int SYS_WRITEC = 0x03; register int reg0 asm("r0"); register int reg1 asm("r1"); outchar = '!'; reg0 = SYS_WRITEC; reg1 = (int)&outchar; asm("svc 0x00123456");
We can experiment with this some other time, for now our aim is to just make it happen, besides, we have 128K ROM and 16k RAM (we can use 34K for printf).
The new GNU ARM toolchain eclipse plugin comes with some cool features like project templates for some famous controllers, including Freescale’s Kinetis family. We will use this templates, and select semihosting in the process.
The overview is:
- A linux system, I am using Ubuntu 13.04
- Install GNU ARM toolchain if you don’t have it already
- Install the GNU ARM toolchain eclipse plugin in eclipse
- Install J-link GDB Server
- Create a GNU ARM template project for the FRDM-KL25Z board
- Configure the debug settings of the eclipse project
- Launch debug
Install J-link GDB server
Go to the Segger J-link GDB server download select page and select either the 32-bit or 64-bit DEB, or RPM, or the TGZ installer and documentation pack. On the next page that opens, select the last link, you would like to download the software for other reasons. On the next page, check that box confirming that you won’t use illegal j-link debugger clones. On the next page that opens, don’t worry, you’re almost there… check that box specifically confirming that you will not use those clones whose images are shown, and finally download. I am using ubuntu so I got the .deb package. to install it:
sudo dpkg -i path_to_j-link.deb
Change the firmware to the J-Link openSDA and plugin the freedom board then run the Jlink GDB server in the terminal
and the output is:
SEGGER J-Link GDB Server V4.84 Command Line Version JLinkARM.dll V4.84 (DLL compiled Mar 28 2014 16:31:00) -----GDB Server start settings----- GDBInit file: none GDB Server Listening port: 2331 SWO raw output listening port: 2332 Terminal I/O port: 2333 Accept remote connection: yes Generate logfile: off Verify download: off Init regs on start: on Silent mode: off Single run mode: off Target connection timeout: 5 sec. ------J-Link related settings------ J-Link Host interface: USB J-Link script: none J-Link settings file: none ------Target related settings------ Target device: unspecified Target interface: JTAG Target interface speed: 1000kHz Target endian: little Connecting to J-Link... J-Link is connected. Firmware: J-Link OpenSDA compiled Mar 13 2013 11:48:08 Hardware: V1.00 S/N: 621000000 Checking target voltage... Target voltage: 3.30 V Listening on TCP/IP port 2331 Connecting to target... *** J-Link V4.84 Error *** Debugger tries to select target interface JTAG. This interface is not supported by the connected emulator. Selection will be ignored by the DLL. *** J-Link V4.84 Error *** J-Link found 1 JTAG device, Total IRLen = 4 JTAG ID: 0x0BC11477 (Cortex-M0) Connected to target Waiting for GDB connection...
Now we know the GDB server is ready. Lets create a project.
Go to file->new->C Project.
Enter the name of your project and select Executable->Freescale KLxx C/C++ Project and click next.
On the next window defaults of the chip family, ROM, RAM and clock are selected. Select Blinky(blink a LED), for the content and semihosting for use system calls.
Click Next and Next again on the list of project folders (leave them as they are if no need to change).
Next window is about configuration, leave both debug and release selected, we want to see how huge the binaries will be for both. Click Next and set the toolchain path to /usr/bin or wherever you installed it.
To build the project, select it in the project browser and click the build icon.
To set up debug, Right click on the project in the project explorer and go to Debug as->Debug Configuration. Select the GDB SEGGER J-Link Debugging and create a new entry. On the right, in the Debugger tab, we have the debug server settings. Enter the Executable as JLinkGDBServer, same command we used to run it in terminal. Give Device name, such as J-Link OpenSDA
Here we have some default settings selected like endianness to little, connection to USB and interface as SWD. We can set Debug speed to fixed: 500Khz (it can be set higher, we are just testing the waters). The GDB port, SWO port and Telnet port are by default set to 2331,2332 and 2333 respectively. We can keep those. On the Startup tab, we have the debug client settings. You can set the initial reset and halt command to init, and low speed to a low initialization speed, like 50Khz. You can enable flash breakpoints, enable semihosting and choose the console for the output to be routed to as either telnet or GDB client. Its a good thing that in eclipse, you can choose to show any of these consoles when the output changes during debug. You can also enable SWO and select the CPU and SWO frequencies. . For guidelines on these settings, check out the J-Link hardware debug GNU ARM eclipse plugin on livius.net. My values just worked on first trial. The rest of the settings below that is all about the normal gdb configuration like whether to halt the target after initialization and set a breakpoint at a specific point in source, like at the main method.
The other thing we can do is make these debug settings easily accessible in the UI by going to the common tab and enable Debug under Display in favorites menu. We could also enable shared file under Save as to allow as to share the debug configuration whenever we share the project with others, like when we push to github.
Its that time to plug in the hardware, click debug and get some output. The LED blink example contains code that runs a Systick timer and uses it to blink the blue LED keeping it on 2/3 of the time and off 1/3 of the time as well as output some messages to the host PC.
Release binary file
15:46:04 **** Incremental Build of configuration Release for project KL25z_semihosting **** make all Invoking: Cross ARM GNU Create Flash Image arm-none-eabi-objcopy -O ihex "KL25z_semihosting.elf" "KL25z_semihosting.hex" Finished building: KL25z_semihosting.hex Invoking: Cross ARM GNU Print Size arm-none-eabi-size --format=berkeley "KL25z_semihosting.elf" text data bss dec hex filename 3204 1548 256 5008 1390 KL25z_semihosting.elf Finished building: KL25z_semihosting.siz
So the release file is 3.2Kb compared to the 34.4Kb in debug build.