# OpenOCD question

**URL:** <https://community.sparkfun.com/t/openocd-question/3319>\
**Category:** MicroMod\
**Tags:** arm-lpc\
**Created:** [December 15, 2006, 9:21am UTC](https://community.sparkfun.com/t/openocd-question/3319 "2006-12-15T09:21:53Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![volunteer](https://avatars.discourse-cdn.com/v4/letter/v/278dde/32.png) [@volunteer](https://community.sparkfun.com/u/volunteer)\
**Post date:** [December 15, 2006, 9:21am UTC](https://community.sparkfun.com/t/openocd-question/3319/1 "2006-12-15T09:21:53Z")

</div>

Dear all,

I am using OpenOCD to debug my self-made LPC22xx board. Everything works quite well except I have to reset my board every time I try to download my program.

The details are:

I want to downlaod my program into an external flash. I have to

Erase the flash ----- step 1

Reset my board ----- step 2

Download my program ------step 3

If I do not do step 2, step 3 will fail. Does anyone know the reason? Thanks!

The OpenOCD outputs the following message many times, and then the download operation fails.

Debug: embeddedice.c:156 embeddedice\_read\_re\_w\_check(): 1.

Regards,

Kevin

---

<div class="post-metadata">

**Author:** ![volunteer](https://avatars.discourse-cdn.com/v4/letter/v/278dde/32.png) [@volunteer](https://community.sparkfun.com/u/volunteer)\
**Post date:** [December 15, 2006, 9:31am UTC](https://community.sparkfun.com/t/openocd-question/3319/2 "2006-12-15T09:31:09Z")

</div>

Here’s part of the logfile.

> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 5: 0xe3100902
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 5: 0x1a000072
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 5: 0xe3a00c11
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 5: 0xe2800030
> 
> Debug: arm7\_9\_common.c:781 arm7\_9\_halt(): target-\>state: debug\_running
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 9: 0xffffffff
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 11: 0xffffffff
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 12: 0x00000100
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 13: 0x000000f7
> 
> Debug: embeddedice.c:156 embeddedice\_read\_reg\_w\_check(): 1
> 
> Debug: arm7\_9\_common.c:619 arm7\_9\_poll(): DBGACK set, dbg\_state-\>value: 0x9
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 0: 0x00000005
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 12: 0x00000000
> 
> Debug: arm7\_9\_common.c:919 arm7\_9\_debug\_entry(): target entered debug from ARM state
> 
> Debug: arm7\_9\_common.c:951 arm7\_9\_debug\_entry(): target entered debug state in Supervisor mode
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r0: 0x40002100
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r1: 0x70000000
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r2: 0x00001000
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r3: 0x002200a0
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r4: 0x0000f018
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r5: 0x002200aa
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r6: 0x0000aaaa
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r7: 0x00005554
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r8: 0x80000000
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r9: 0x00000000
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r10: 0x7d729f1b
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r11: 0x6e7c4aed
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r12: 0x00000009
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r13: 0x400000ac
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r14: 0x7ffff1ad
> 
> Debug: arm7\_9\_common.c:980 arm7\_9\_debug\_entry(): r15: 0x40002104
> 
> Debug: arm7\_9\_common.c:986 arm7\_9\_debug\_entry(): entered debug state at PC 0x40002104
> 
> Debug: target.c:442 target\_call\_event\_callbacks(): target event 3
> 
> Debug: armv4\_5.c:537 armv4\_5\_run\_algorithm(): setting core\_mode: 0x13
> 
> Debug: breakpoints.c:87 breakpoint\_add(): added hardware breakpoint at 0x400000fc of length 0x00000004
> 
> Debug: arm7\_9\_common.c:1303 arm7\_9\_resume():
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 8: 0x400000fc
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 9: 0x00000003
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 11: 0xffffffff
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 13: 0x000000f7
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 12: 0x00000100
> 
> Debug: arm7\_9\_common.c:1102 arm7\_9\_restore\_context():
> 
> Debug: arm7\_9\_common.c:1118 arm7\_9\_restore\_context(): examining User mode
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: r0
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: r1
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: r2
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: r3
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: r4
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: r5
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: r6
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: r7
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: r8
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: r9
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: pc
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: cpsr
> 
> Debug: arm7\_9\_common.c:1181 arm7\_9\_restore\_context(): writing register 0 of mode User with value 0x40000100
> 
> Debug: arm7\_9\_common.c:1181 arm7\_9\_restore\_context(): writing register 1 of mode User with value 0x80000000
> 
> Debug: arm7\_9\_common.c:1181 arm7\_9\_restore\_context(): writing register 2 of mode User with value 0x00001000
> 
> Debug: arm7\_9\_common.c:1181 arm7\_9\_restore\_context(): writing register 3 of mode User with value 0x002200a0
> 
> Debug: arm7\_9\_common.c:1181 arm7\_9\_restore\_context(): writing register 4 of mode User with value 0x00000000
> 
> Debug: arm7\_9\_common.c:1181 arm7\_9\_restore\_context(): writing register 5 of mode User with value 0x002200aa
> 
> Debug: arm7\_9\_common.c:1181 arm7\_9\_restore\_context(): writing register 6 of mode User with value 0x0000aaaa
> 
> Debug: arm7\_9\_common.c:1181 arm7\_9\_restore\_context(): writing register 7 of mode User with value 0x00005554
> 
> Debug: arm7\_9\_common.c:1181 arm7\_9\_restore\_context(): writing register 8 of mode User with value 0x80000000
> 
> Debug: arm7\_9\_common.c:1181 arm7\_9\_restore\_context(): writing register 9 of mode User with value 0x00000000
> 
> Debug: arm7\_9\_common.c:1118 arm7\_9\_restore\_context(): examining FIQ mode
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: pc
> 
> Debug: arm7\_9\_common.c:1118 arm7\_9\_restore\_context(): examining IRQ mode
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: pc
> 
> Debug: arm7\_9\_common.c:1118 arm7\_9\_restore\_context(): examining Supervisor mode
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: pc
> 
> Debug: arm7\_9\_common.c:1118 arm7\_9\_restore\_context(): examining Abort mode
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: pc
> 
> Debug: arm7\_9\_common.c:1118 arm7\_9\_restore\_context(): examining Undefined mode
> 
> Debug: arm7\_9\_common.c:1132 arm7\_9\_restore\_context(): examining dirty reg: pc
> 
> Debug: arm7\_9\_common.c:1214 arm7\_9\_restore\_context(): writing cpsr with value 0x600000d3
> 
> Debug: arm7tdmi.c:475 arm7tdmi\_write\_xpsr(): xpsr: 600000d3, spsr: 0
> 
> Debug: arm7\_9\_common.c:1221 arm7\_9\_restore\_context(): writing PC with value 0x400000ac
> 
> Debug: embeddedice.c:252 embeddedice\_write\_reg(): 0: 0x00000004
> 
> Debug: target.c:442 target\_call\_event\_callbacks(): target event 4
> 
> Debug: arm7\_9\_common.c:1406 arm7\_9\_resume(): target resumed
> 
> Debug: embeddedice.c:156 embeddedice\_read\_reg\_w\_check(): 1
> 
> Debug: embeddedice.c:156 embeddedice\_read\_reg\_w\_check(): 1

---

<div class="post-metadata">

**Author:** ![Dominic](https://avatars.discourse-cdn.com/v4/letter/d/13edae/32.png) [@Dominic](https://community.sparkfun.com/u/Dominic)\
**Post date:** [December 15, 2006, 9:50am UTC](https://community.sparkfun.com/t/openocd-question/3319/3 "2006-12-15T09:50:52Z")

</div>

Hello Kevin,

could you send a complete log file and your .cfg file to Dominic.Rath [gmx.de](http://gmx.de)? The log you’ve posted doesn’t contain the lines that show the flashing fail.

Best regards,

Dominic

---

<div class="post-metadata">

**Author:** ![A.K](https://avatars.discourse-cdn.com/v4/letter/a/e8c25b/32.png) [@A.K](https://community.sparkfun.com/u/A.K)\
**Post date:** [December 15, 2006, 2:24pm UTC](https://community.sparkfun.com/t/openocd-question/3319/4 "2006-12-15T14:24:11Z")

</div>

It is known that the ARM7 core used by the LPC family does not allow JTAG control right out of reset. So what happens with interrupts or other hardware setups by some flash-stored program program once the JTAG based programming gets into control?

The effect described here may indicate, that there is some interference between the stored program’s hardware setup and the flash programming. If the programming is done after flash erase and a hardware reset, there no longer is any prior state which could interfere.

Maybe it helps to place a 1sec delay loop right after reset, to make sure the JTAG catches the processor before any harm is done.

---

<div class="post-metadata">

**Author:** ![smead](https://avatars.discourse-cdn.com/v4/letter/s/ac8455/32.png) [@smead](https://community.sparkfun.com/u/smead)\
**Post date:** [December 16, 2006, 7:45am UTC](https://community.sparkfun.com/t/openocd-question/3319/5 "2006-12-16T07:45:22Z")

</div>

At reset the processor takes off and runs, and some thousands of instructions later the jtag is able to get control. You have to keep the processor in a cage until you’re ready to let it out.

Here’s what I’m doing in crt.s based on a suggestion by Dominic.

/\*

let the application stop processor advancement if they want

to get gdb started at a known location. after starting gdb

they need to tell gdb jump past\_gdb\_hook. if not debugging then

gdb\_hook can just return. gdb\_hook is a basic while( 1 ){}

\*/

bl gdb\_hook

.global past\_gdb\_hook

past\_gdb\_hook:

Then I define a go command in .gdbinit.

define go

echo (gdb) target remote :3333\n

target remote :3333

r16

display/i $pc

jump past\_gdb\_hook

end

I fire up gdb, set breakpoints if desired and then give it the go command.

If you’re not writing your own crt.s, then you’ll probably have to do something equivalent in main.

Hope this helps

---

<div class="post-metadata">

**Author:** ![volunteer](https://avatars.discourse-cdn.com/v4/letter/v/278dde/32.png) [@volunteer](https://community.sparkfun.com/u/volunteer)\
**Post date:** [December 19, 2006, 3:32am UTC](https://community.sparkfun.com/t/openocd-question/3319/6 "2006-12-19T03:32:29Z")

</div>

> Maybe it helps to place a 1sec delay loop right after reset, to make sure the JTAG catches the processor before any harm is done.

where should I place the delay loop? Since there is no code any more in the flash after it is erased.

By the way, I did not connect the reset pin of JTAG to the MCU’s reset pin, will this cause the problem?

Regards,

Kevin

---

<div class="post-metadata">

**Author:** ![A.K](https://avatars.discourse-cdn.com/v4/letter/a/e8c25b/32.png) [@A.K](https://community.sparkfun.com/u/A.K)\
**Post date:** [December 20, 2006, 9:38pm UTC](https://community.sparkfun.com/t/openocd-question/3319/7 "2006-12-20T21:38:21Z")

</div>

If JTAG cannot reset the MCU, all hardware stays in the state left over from the program which ran before. Guess what happens if there still is a timer interrupt configured, but its handler is gone.

So while the debugger looses control over the MCU when applying reset (IMHO a design fault of the ARM7TDMI debug macrocell), not connecting to reset gets you into other problems, as you demonstrated.

The delay loop suggestion is a result of my own experience with JTAG based code-in-RAM debugging. Debugging got somewhat easier when any (unused but present) flash code did not touch any hardware, because due to the mentioned bug, after reset the debugger usually does not get in control over the MCU before at least part of the flash code code was run. If the startup code (crt.S or whatever it is called in your setup) contains a 1sec delay loop, the debugger can catch the MCU before any initialization has been done, so left over flash code does not hinder RAM based debugging. I’ve not yet done much flash based JTAG debugging, but I won’t be surprised if it helps in this setup too.

---

<div class="post-metadata">

**Author:** ![dshuman](https://avatars.discourse-cdn.com/v4/letter/d/85f322/32.png) [@dshuman](https://community.sparkfun.com/u/dshuman)\
**Post date:** [December 20, 2006, 11:04pm UTC](https://community.sparkfun.com/t/openocd-question/3319/8 "2006-12-20T23:04:58Z")

</div>

> A.K.:  
> So while the debugger looses control over the MCU when applying reset (IMHO a design fault of the ARM7TDMI debug macrocell), not connecting to reset gets you into other problems, as you demonstrated.

It certainly is a serious design weakness, but the fault is NOT with ARM7TDMI EmbeddedICE macrocell. In the LPC family, it was purposely designed that way by Phillips to implement their code read protection “feature”. In Phillips ARM parts the nRESET and nTRST signals are internally connected so that when reseting ARM via nRESET, the JTAG TAP controller is ALSO reset. The TAP controller reset causes the debugger to lose control until the TAP controller can be reconfigured. Since the JTAG clock must be slower than the ARM clock, ARM can execute a very large number of instructions before the debugger regains control. A normal ARM system can be configured so the CPU can be reset without reseting the TAP controller, so it is possible to set a breakpoint at the reset vector and catch ARM before any code has executed. To see how it is really supposed to work, take a look at ARM AppNote 31.

– Dave

---

<div class="post-metadata">

**Author:** ![tcmichals](https://avatars.discourse-cdn.com/v4/letter/t/e9c0ed/32.png) [@tcmichals](https://community.sparkfun.com/u/tcmichals)\
**Post date:** [December 27, 2006, 6:50pm UTC](https://community.sparkfun.com/t/openocd-question/3319/9 "2006-12-27T18:50:18Z")

</div>

This is also true for ATMEL correct?

---

<div class="post-metadata">

**Author:** ![dshuman](https://avatars.discourse-cdn.com/v4/letter/d/85f322/32.png) [@dshuman](https://community.sparkfun.com/u/dshuman)\
**Post date:** [December 27, 2006, 9:53pm UTC](https://community.sparkfun.com/t/openocd-question/3319/10 "2006-12-27T21:53:36Z")

</div>

> tcmichals:  
> This is also true for ATMEL correct?

If your question was to me in response to my description of the Phillips design "feature" concerning nTRST and nRESET, I do not know. I have only worked with cell phone ASICs containing ARM, and the more general purpose Phillips parts. The cell phone ASICs followed ARM's recommendations and could be debugged directly out of reset, while the Phillips parts can not.

– Dave
