Debugging NXP MK20 using J-Link and OpenOCD

by | April 23, 2017

For the longest time I was having problems debugging with my setup:

  • Freescale MK20FX512VLQ
  • J-Link
  • OpenOCD 0.10.0
  • GDB 7.12.1
  • Qt Creator 4.2.1

The debugging chain would crash randomly, especially when debugging under FreeRTOS threads.

I found out (debugging output from OpenOCD) that GDB is trying to access weird locations, most obvious address was 0xA5A5A5A5. This is a fill value for the stack of a FreeRTOS thread. (FreeRTOS fills the stack with 0xA5 to allow for monitoring stack overflow.)

So when a breakpoint was executed at a beginning of a function with references, those references were not initialized at the beginning of the function (had random values from stack which happened to be0xA5A5A5A5). At this point, GDB (or Qt Creator) tried to fetch all the locals variables, which resulted in asking for this weird location.

The MCU, Kinetis MK20 probably did not like this memory access and crashed.

Solution

I found out that memory regions and their access attributes (r, w, rw) can be specified in GDB. Initially, GDB gets the description of these regions from OpenOCD.

The default memory regions look like that:

(gdb) info mem
Using memory regions provided by the target.
Num Enb Low Addr High Addr Attrs 
0 y 0x00000000 0x00040000 flash blocksize 0x1000 nocache 
1 y 0x00040000 0x100000000 rw nocache

Memory region 0 describes flash and region 1 is the RAM. We can see, that GDB has access to the entire memory space including invalid locations.

My solution was to redefine region number 1 so that is covers only the connected ram.

From my gdbinit file:

delete mem

mem auto
mon sleep 200
delete mem 1 2 3

mem 0x1C000000 0x1FFFFFFF rw nocache
mem 0x20000000 0x200FFFFF rw nocache

First I delete the configuration. Then I request the memory description from OpenOCD (mem auto). This step is because I was not able to manually define a region with flash attribute.

Then I delete the memory region (Sometimes there were more than one – that’s why there are 1, 2, 3) and add two new memory regions according to the device datasheet.

That’s how GDB reports memory regions after the change:

(gdb) info mem
Using user-defined memory regions.
Num Enb Low Addr High Addr Attrs 
0 y 0x00000000 0x00040000 flash blocksize 0x1000 nocache 
1 y 0x1c000000 0x1fffffff rw nocache 
2 y 0x20000000 0x200fffff rw nocache

Now, GDB is not accessing the invalid memory and nothing crashes anymore.

Todo

  • Modify OpenOCD so that it provides only valid regions for my MCU.
  • add the memory mapped peripheral region to the description. I’m afraid that now I wouldn’t be able to access the peripherals.

Appendix:

gdbinit:
target remote localhost:3333

set remote hardware-breakpoint-limit 6
set remote hardware-watchpoint-limit 4

delete mem

mem auto
mon sleep 200
delete mem 1 2 3

mem 0x1C000000 0x1FFFFFFF rw nocache
mem 0x20000000 0x200FFFFF rw nocache

set remotetimeout 5

monitor reset halt
#load
#monitor reset halt

mon sleep 500
openocd.cfg
interface jlink
adapter_khz 100
transport select swd

set CHIPNAME k20
source [find target/kx.cfg]

$_TARGETNAME configure -event reset-init {
 puts "-event reset-init occured"
}

$_TARGETNAME configure -work-area-phys 0x1C000000 -work-area-size $_WORKAREASIZE -work-area-backup 0

 

Leave a Reply

Your email address will not be published. Required fields are marked *