Possible to debug on Flash (LPC2148)

Hi,

I’m running OpenOCD v0.2.0 with an Olimex Usb-Arm-Tiny on a LPC2148 board, but can’t seem to debug, (or read/write to flash for that matter).

Is it possible to debug code running from flash? Is setting breakpoints or halting the target only on ARM processors running out of RAM, and not ARM microcontrollers

like the LPC2148 running out of Flash?

This is the config file I’m using, basically only modified for the olimex tiny and a 12mhz clock for the lpc2148:

#
# For more information about the configuration files, take a 
# look at the "Open On-Chip Debugger (openocd)" documentation.
#

# daemon configuration
telnet_port 4444
gdb_port 3333
tcl_port 6666 

# tell gdb our flash memory map
# and enable flash programming
gdb_memory_map enable
gdb_flash_program enable

#########################################################
#
# Interface, if you want to use an other interface
# you must replace this section here.
#

interface ft2232 
ft2232_device_desc "Olimex OpenOCD JTAG TINY A" 
ft2232_layout "olimex-jtag" 
ft2232_vid_pid 0x15BA 0x0004


#########################################################
#

# Start slow, speed up after reset
jtag_khz 30

if { [info exists CHIPNAME] } {	
   set _CHIPNAME $CHIPNAME
} else {
   set _CHIPNAME lpc2148
}

if { [info exists ENDIAN] } {
   set _ENDIAN $ENDIAN
} else {
   set _ENDIAN little
}

if { [info exists CPUTAPID ] } {
   set _CPUTAPID $CPUTAPID
} else {
   set _CPUTAPID 0x4f1f0f0f
}

jtag_nsrst_delay 250
jtag_ntrst_delay 250

# NOTE!!! LPCs need reset pulled while RTCK is low. 0 to activate
# JTAG, power-on reset is not enough, i.e. you need to perform a
# reset before being able to talk to the LPC2148, attach is not possible.

reset_config trst_and_srst srst_pulls_trst

jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID

set _TARGETNAME [format "%s.cpu" $_CHIPNAME]

target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME -variant arm7tdmi-s_r4

$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup 0

$_TARGETNAME configure -event reset-start {
	jtag_khz 30
}

$_TARGETNAME configure -event reset-init {
	# Force target into ARM state.
	soft_reset_halt

	# Do not remap 0x0000-0x0020 to anything but the flash (i.e. select
	# "User Flash Mode" where interrupt vectors are _not_ remapped,
	# and reside in flash instead).
	#
	# See section 7.1 on page 32 ("Memory Mapping control register") in
	# "UM10139: Volume 1: LPC214x User Manual", Rev. 02 -- 25 July 2006.
	# http://www.standardics.nxp.com/support/documents/microcontrollers/pdf/user.manual.lpc2141.lpc2142.lpc2144.lpc2146.lpc2148.pdf
	mwb 0xE01FC040 0x01

	jtag_khz 1500
}

# flash bank lpc2000 <base> <size> 0 0 <target#> <variant> <clock> [calc_checksum]
flash bank lpc2000 0x0 0x7d000 0 0 0 lpc2000_v2 12000 calc_checksum

#########################################################

init

reset init

And invoking it with openocd-ftd2xx, I get this output:

C:\test>openocd-ftd2xx -f olimex_usb_arm_tiny.cfg
Open On-Chip Debugger 0.2.0 (2009-08-24-22:44) Release
$URL: http://svn.berlios.de/svnroot/repos/openocd/tags/openocd-0.2.0/src/openocd
.c $
For bug reports, read http://svn.berlios.de/svnroot/repos/openocd/trunk/BUGS
30 kHz
jtag_nsrst_delay: 250
jtag_ntrst_delay: 250
Info : device: 4
Info : deviceID: 364511236
Info : SerialNumber: FTRF9W5CA
Info : Description: Olimex OpenOCD JTAG TINY A
Info : JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
Info : JTAG Tap/device matched
target state: halted
target halted in ARM state due to breakpoint, current mode: Supervisor
cpsr: 0x000000d3 pc: 0x000004c8
30 kHz
Info : JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
Info : JTAG Tap/device matched
Warn : srst pulls trst - can not reset into halted mode. Issuing halt after reset.
target state: halted
target halted in ARM state due to debug-request, current mode: Abort
cpsr: 0x000000d7 pc: 0x0000044c
requesting target halt and executing a soft reset
target state: halted
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x000000d3 pc: 0x00000000
Warn : memory write caused data abort (address: 0xe01fc040, size: 0x1, count: 0x
1)
Runtime error, file "olimex_usb_arm_tiny.cfg", line 11:

Not sure why the memory write caused data abort or the runtime error on line 11 (gdb_memory_map enable?) but this is the gdb file I’m using for initialization, I didn’t modify it all:

target remote localhost:3333
monitor reset init
monitor sleep 500
#monitor poll
#monitor soft_reset_halt
monitor mww 0xE01FC040 0x0001
monitor mdw 0xE01FC040

# needed for gdb 6.8 and higher
set mem inaccessible-by-default off

load
break main
continue

When I launch the insight debugger with gdb file,

arm-elf-insight -x lpc2148_rom_oocd.gdb Led_Blink.elf

The Insight console window shows:

0xe01fc040: 00000001 
Loading section .eh_frame, size 0x33c lma 0x40000200
Loading section .text, size 0xe24 lma 0x0
Loading section .data, size 0x30 lma 0xe24
Start address 0x0, load size 4496
Transfer rate: 686 bytes/sec, 1498 bytes/write.
Breakpoint 1 at 0x28c: file main_blink.c, line 140.
Note: automatically using hardware breakpoints for read-only addresses.

With the command console window updates :

Warn : srst pulls trst - can not reset into halted mode. Issuing halt after reset.
target state: halted
target halted in ARM state due to debug-request, current mode: Abort
cpsr: 0x000000d7 pc: 0x0000044c
requesting target halt and executing a soft reset
target state: halted
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x000000d3 pc: 0x00000000
Warn : memory write caused data abort (address: 0xe01fc040, size: 0x1, count: 0x
1)
Runtime error, file "olimex_usb_arm_tiny.cfg", line 11:
    0xe01fc040: 00000001
Warn : Verification will fail since checksum in image(0xe1a00000) written to flash was different from calculated vector checksum(0xb9205f84).
Warn : To remove this warning modify build tools on developer PC to inject correct LPC vector checksum.
Warn : keep_alive() was not invoked in the 1000ms timelimit. GDB alive packet not sent! (1219). Workaround: increase "set remotetimeout" in GDB
Error: timed out while waiting for target halted
Warn : lpc2000 prepare sectors returned 13822120
Error: failed erasing sectors 0 to 0 (-902)
Error: flash_erase returned -902

Most of the time it will just freeze here, waiting for the target to halt, and no timeout… but occasionally

the main Insight window comes up that would allow me to step thru the source code but I immediately get this error:

Error: timed out while waiting for target halted
Warn : lpc2000 prepare sectors returned 13822120
Error: failed erasing sectors 0 to 0 (-902)
Error: flash_erase returned -902

Is it possible for code to be stepped thru running out of the lpc2148 (flash)?

(I downloaded an eval version of crossworks arm but that too shows an error that the target cannot be halted… perhaps there is something wrong with

reset hardware?)

If Anyone has a cfg/gdb for an lpc2148 that can debug or read/write a hex file to the flash that would be great!

Of course LPC2148 (just like any other ARM) can be debugged in flash.

Firs of all - start with the config files provided with OpenOCD - you really don’t need to change ANYTHING in them (except for the crystal frequency in the lpc2148.cfg). Also - when connecting gdb with OpenOCD don’t issue hundreds of strange commands - just do:

target remote localhost:3333

monitor reset halt

load

break main

continue

nothing more.

4/3!!

I have the arm-usb-ocd and an LPC-2148 dev board from Olimex. I had almost given up on it Then when I set jtag_khz 500 it suddenly started working.

It seems mostly reliable at 1000. Not so good for me above that. This all may depend on host OS, usb chipset, CPU, CPU load, who knows.

As far as I can see, the config files I’ve been using don’t specify a slower clock at reset. That may have actually been my problem.

Anyway, one more thing to keep in mind.

-Hugh

The clock speed seems to depend on the PCB layout. My own parallel port JTAG design works fine at max. speed (I took a lot of care over the layout) but a genuine Wiggler needs a much slower speed. I wasn’t very impressed with the PCB design when I took mine apart. I don’t know if that applies to the Olimex design, though.

Leon

Thanks for the tip, I will lower to jtag_khz 1000… I’ll also simplify the gdb file (but add ‘set mem inaccessible-by-default off’)

Since I’m not using an lpc2148 target board from olimex, that might explain why the original olimex cfg that came with the tiny didn’t work on my board.

Also, since it’s not compatible with openocd 0.2.0, it doesn’t even execute the cfg properly:

#daemon configuration
telnet_port 4444
gdb_port 3333

#interface
interface ft2232
ft2232_device_desc "Olimex OpenOCD JTAG TINY A"
ft2232_layout "olimex-jtag"
ft2232_vid_pid 0x15BA 0x0004

jtag_speed 2

#use combined on interfaces or targets that can't set TRST/SRST separately
reset_config trst_and_srst separate

#jtag scan chain
#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)
jtag_device 4 0x1 0xf 0xe

#target configuration
daemon_startup reset

#target <type> <startup mode>
#target arm7tdmi <reset mode> <chainpos> <endianness> <variant>
target arm7tdmi little run_and_halt 0 arm7tdmi-s_r4
run_and_halt_time 0 30

#target_script 0 reset oocd_flash2138.script
working_area 0 0x40000000 0x40000 nobackup

#flash configuration
flash bank lpc2000 0x0 0x40000 0 0 0 lpc2000_v2 12000 calc_checksum

# For more information about the configuration files, take a look at:
# http://openfacts.berlios.de/index-en.phtml?title=Open+On-Chip+Debugger
Open On-Chip Debugger 0.2.0 (2009-08-24-22:44) Release
$URL: http://svn.berlios.de/svnroot/repos/openocd/tags/openocd-0.2.0/src/openocd
.c $
For bug reports, read http://svn.berlios.de/svnroot/repos/openocd/trunk/BUGS
jtag_speed: 3
OLD SYNTAX: DEPRECATED - translating to new syntax
jtag newtap CHIP TAP -irlen 4 -ircapture 0x1 -irvalue 0xf
Example: STM32 has 2 taps, the cortexM3(len4) + boundaryscan(len5)
jtag newtap stm32 cortexm3 ....., thus creating the tap: "stm32.cortexm3"
jtag newtap stm32 boundary ....., and the tap: "stm32.boundary"
And then refer to the taps by the dotted name.
NEW COMMAND:
Unknown command: daemon_startup reset

I use openocd 1.0 (10/08), it does at least start the daemon but can’t halt/debug the processor (i.e:

cpsr: 0x000000d7 pc: 0x0000044c
Warn : acknowledgment received, but no packet pending
Warn : Verification will fail since checksum in image(0xe1a00000) written to fla
sh was different from calculated vector checksum(0xb9205f84).
Warn : To remove this warning modify build tools on developer PC to inject corre
ct LPC vector checksum.
Warn : keep_alive() was not invoked in the 1000ms timelimit. GDB alive packet no
t sent! (1235). Workaround: increase "set remotetimeout" in GDB
Warn : keep_alive() was not invoked in the 1000ms timelimit. GDB alive packet no
t sent! (1250). Workaround: increase "set remotetimeout" in GDB
Warn : keep_alive() was not invoked in the 1000ms timelimit. GDB alive packet no
t sent! (1265). Workaround: increase "set remotetimeout" in GDB

Any special setup on the gdb file for ram vs rom debugging? Could the setremotetimeout warning be the reason for the halt/debug issue?

It could also be a problem with the layout of the target board, of course.

Leon

The vendor of the lpc2148 board shows it supports jtag, so I don’t think it’s a design issue… but perhaps something got zapped on the board.

As another data point, I got a hold of a cirrus logic sbc board that has an ep9302 on it. Luckily it also has a 20 pin jtag connector, so I connected it directly to the jtag-tiny. Since I’m not very familiar with modifying the cfg, I tried using Crossworks first… Crossworks was able to read the ID, but not halt the processor (similar to the lpc2148 board).

To use openocd, how can I find the cputapid of the ep9302? flash_bank?

Disclaimer: This post is mostly wild speculation.

Do you know for certain that you have a good working program flashed into your 2148 board? The symptoms you describe sound a bit like ones I’ve seen after I flashed a program that caused an un-handled exception.

One thing I’ve been trying to understand on my own** is why it takes openocd so long to get control after a reset. I’ve resorted to things like decrementing a counter from 500,000 in crt.s so that Insight can actually halt on entry to main(). Anyway, the point here is that if your program is going off the track, it will be wrecked long before openocd gets control after reset. Assuming your system behaves like mine.

**My optimism is gradually fading that I’ll be able to grasp how the reset process works. I’ll stare at the openocd docs for a while, then stare at the Architecture refman for a while. I comprehend little bits here and there but so far the big picture remains opaque. If I can just get to the point where I can ask specific questions I’m going to be a tremendous pest.

First of all in LPCs SRTS (normal reset) is internally connected to TRST (TAP reset for JTAG interface). It is impossible to take control of the core without reseting the JTAG interface. That’s why you cannot connect to a running chip

But that’s less important here.

Immediately after reset the JTAG interface is actually disabled. The first thing running is ALWAYS the bootloader. It checks whether it should start the code or wait for ISP (by checking one of the pins). It also checks whether there is a valid code in the flash (by checking the checksum from the unused vector). There is also a check of option bytes, which are a security mechanism of LPC - if the option bytes allow that the JTAG and / or ISP are enabled. That’s why it is impossible to tell how long after de-asserting the reset the JTAG interface is really enabled. That’s why OpenOCD just waits after reset for a while before trying to halt the core.

Unhandled exceptions really do no harm - the real problem is disabling the JTAG in code in some way (either intentionally or by a pure coincidence)

4/3!!

With respect to faulty code running that’s preventing openocd to halt the processor…

Using Philips LPC21xx serial flashing utility, I’ve flashed a blink hex file (came with the board), and the led does in fact blink.

Just for completeness, I’ve also built and serially flashed the LPC_h2148 and LPC_p2148 projects that came on the olimex cd. But, since the design is from another vendor, the board is not exactly the same as the h2148 or the p2148,

In any case, I’ve verified that the flash matches the hex file uploaded, so it should be running known good code, however I still have the halt processor issue (using openocd 1 or 2, and crossworks).

What should the state of the bootloader pin (P0.14) be set to at power-on for debugging?

The ISP should be disabled for debugging.

There are other pins that have special meaning for debugging - especially RTCK. See the manual and the chapter about JTAG debugging - chapter EmbeddedICE, sub-chapter Reset state of multiplexed pins

4/3!!

Thanks! Disabling the bootloader halted it!

The target now halts (no more blinking led!) when I run openocd-ftdxx -f h2148.cfg

(openocd version 0.2.0)

C:\Program Files\GNUARM\bin>openocd-ftd2xx_v2 -f h2148.cfg
Open On-Chip Debugger 0.2.0 (2009-08-24-22:44) Release
$URL: http://svn.berlios.de/svnroot/repos/openocd/tags/openocd-0.2.0/src/openocd.c $
For bug reports, read http://svn.berlios.de/svnroot/repos/openocd/trunk/BUGS
30 kHz
jtag_nsrst_delay: 250
jtag_ntrst_delay: 250
Info : device: 4
Info : deviceID: 364511236
Info : SerialNumber: FTRF9W5CA
Info : Description: Olimex OpenOCD JTAG TINY A
Info : JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
Info : JTAG Tap/device matched
30 kHz
Info : JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
Info : JTAG Tap/device matched
Warn : srst pulls trst - can not reset into halted mode. Issuing halt after reset.
target state: halted
target halted in ARM state due to debug-request, current mode: System
cpsr: 0x6000005f pc: 0x00000160
requesting target halt and executing a soft reset
target state: halted
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x600000d3 pc: 0x00000000
1500 kHz

But then in eclipse galileo, after compiling, I try to execute the debugger, but it never finishes loading or reaching the ‘main’ source code:

warning: (Internal error: pc 0x0 in read in psymtab, but not in symtab.)

/cygdrive/c/eclipse/Projects/LPC2148Test/prj/lpc2148_rom_oocd.gdb:10: Error in sourced command file:
No symbol "mem" in current context.
target remote localhost:3333
warning: (Internal error: pc 0x0 in read in psymtab, but not in symtab.)
_vectors () at crt.S:49
49	_vectors:       ldr     PC, Reset_Addr         
warning: (Internal error: pc 0x0 in read in psymtab, but not in symtab.)
monitor reset halt
30 kHz
JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
JTAG Tap/device matched
srst pulls trst - can not reset into halted mode. Issuing halt after reset.
target state: halted
target halted in ARM state due to debug-request, current mode: System
cpsr: 0x6000005f pc: 0x00000168
warning: (Internal error: pc 0x0 in read in psymtab, but not in symtab.)
load break main
Invalid download offset:main.
continue
warning: (Internal error: pc 0x0 in read in psymtab, but not in symtab.)

This is how I’ve configured the zylincdt plugin settings:

http://i32.tinypic.com/2nlb68m.jpg

Why would it report, ‘Invalid download offset:main’?

enliteneer:
This is how I’ve configured the zylincdt plugin settings:

http://i32.tinypic.com/2nlb68m.jpg

But how should anyone know what is inside the script file you add? Remove that as no more commands are required.

Why would it report, ‘Invalid download offset:main’?

because the command is "load", not "load break main". Those two commands need two separate lines.

4/3!!