ARM (ARM7TDMI)

The ARM architecture is available in various variants, ranging from low-end embedded targets to high-end chips suitable for workstations. NoICE currently supports the ARM7TDMI instruction set, both ARM and Thumb mode, which is the most common one for embedded systems

Because of the large number of ARM vendors, and the equally large number of JTAG interface solutions, we will be phasing in support for various targets, interfaces, and features.

This version of NoICE for ARM supports Flash burning for

We plan to support other chips in the future, in most cases as they are requested by NoICE users. If your target isn't listed in the Target Communications drop-list, please contact us.

If you use NoICE to load a file that should reside in Flash, but on a target for which NoICE does not support Flash burning, NoICE will compare the data in the file to current Flash contents, and tell you if they differ. This can be a handy warning if you forget to run your Flash burner.

ARM is a complex processor, released in many variants by many vendors and communicated with by many JTAG interfaces with many options. If you have problems that you can't resolve by reading the information in this document, or if you have suggestions, please contact us.

In addition to this document, you may wish to read the NoICE ARM Tutorial at http://www.noicedebugger.com/tour_arm. It contains step-by-step examples of configuring and using NoICE for ARM.

NoICE for the ARM may be used with

Additional information is available about


Segger J-Link (includes IAR, SAM-ICE and mIDAS-Link)

Segger (http://www.segger.com) sells a JTAG pod called the J-Link and various associated software. The J-Link is also sold by IAR under their own label, and it is included in IAR demo kits. The Atmel SAM-ICE and the Analog Devices mIDAS-Link are also private-label J-Links. NoICE will work with any of these variants of J-Link, but some of the private-label versions are restricted to work only with that vendor's ARM chips.

Before using the J-Link, you must first download the driver and utility package from Segger's web site and install it. In addition to the drivers and DLL necessary to use the J-Link with NoICE, the package includes a number of handy utilities to verify the J-Link, manipulate options in targets like the STR9xx, etc. Be sure to read the documentation to see what goodies are included.

The J-Link pod is powered by its USB connection to the PC. As a convenience, the IAR version is able to supply 5-volt power to the target board using a non-standard connection on pin 19 of the 20-pin JTAG connector. This is used to power the IAR demo boards, for example. Pin 19 of the ARM JTAG connection is offically defined as DBGACK, or Debug Acknowledge. DBGACK is an output from the host, so there should be no hardware conflict even on target boards that use DBGACK. (Neither the J-Link nor the Wiggler implement the DBGRQ input, and the Wiggler has no connection to DBGACK.) Consult the documentation for your JTAG pod and your target board.

To use the J-Link interface, select Options, Target Communications from the menu. Then select "Segger J-Link Interface " from the Interface drop list.

 ARM GDB Setup
Click on a field for more information about its function.

USB Connection

If your J-Link is connected to your PC via USB (the usual case), select the USB radio button.

TCP/IP Connection

If you are connecting to a J-Link server on a remote computer, select the TCP IP radio button. Then select the appropriate Hostname or IP address and Port. The port number is specified in the J-Link server documentation.

JTAG Speed

In most cases, you can use the "Auto" setting. However, if you have problems you may wish to specify a slower JTAG speed manually.

If your version of J-Link supports adaptive clocking, and if your target connects RTCK to pin 11 of the JTAG connector, you may enter "0" as the JTAG Speed to tell NoICE to use adaptive clocking. For more details about adaptive clocking, refer to the Segger documentation.

Target Chip/Environment

Use this drop-list to select your target chip. This tells NoICE which address ranges contain Flash and RAM.

If your target is not in the list, you may select "generic ARM". NoICE will assume that all memory can be read and written at will. In this case, please let us know which targets you need.

Information Box

This box shows information about your selected target, including Flash and RAM address ranges if known.

CPU Frequency MHz

This combo box specifies the target CPU frequency after the processor has been reset and any Play After Reset command file has been played. This field is a combo box: if the frequency you want isn't in the drop-list, just type the value.

The frequency entered here is used used only for Flash burning. When your program runs, it may re-program the clock or PLL as you see fit.

If you use NoICE to burn flash, you must enter a correct value here. Failure to do so is likely to result in incorrect burning, and may cause destruction of the target chip.

Play this file after Reset

Some targets must initalize chip selects or enable a PLL before they can be used for debugging. The easiest way to perform such mode setting and initialization is to use this edit box to specify a command file to play when communications are initialized and after each reset.

This file is also a convenient way to deal with various reset issues


RDI

RDI, the ARM Remote Debugger Interface, is a standard defined by ARM, Limited. RDI allows a debugger such as NoICE to connect to a debug target by means of a DLL provided by a vendor. The most common target connection is a JTAG interface.

To use RDI, select Options, Target Communications from the menu. Then select "RDI Interface" from the Interface drop list.

 ARM RDI Setup
Click on a field for more information about its function.

RDI DLL

Type or browse to the RDI DLL provided by your RDI implementation. If you are using the H-JTAG Interface, this will usually be

    C:\Program Files\H-JTAG V0.3.0\H-JTAG.dll

If you are using H-JTAG, please read the additional information below.

Segger (http://www.segger.com) sells an RDI interface DLL for use with its J-Link JTAG pod. The J-Link can also be used without an RDI license by selecting Segger J-Link Interface instead of RDI Interface in the Interface drop list.

If you are using another RDI implementation, please consult your supplier's documentation.

RDI Config File

If the RDI implementation you are using needs a configuration file, enter its name here.

RDI Setup...

Some RDI implementations have their own configuration dialog. To invoke such a dialog, press this button

If you are using the Segger RDI DLL, do not enable Flash burning in the Segger RDI setup: NoICE uses its own Flash burning code and will not use the Segger burner.

Show Config...

Press this button to show the contents of the RDI Configuration File, or the default if no file is specified.


GDB Remote Protocol Interface

GDB is an open-source debugger, part of the GNU project. GDB defines a serial protocol, more often used on TCP/IP than on actual serial connections, to permit remote debugging. NoICE can use this protocol to debug ARM targets. (Note that NoICE does not use GDB or any GDB code - only the GDB protocol in order to communicate with a target.)

One restriction on the GDB protocol is that it does not provide access to the ARM's banked or shadow registers. You can see R0 through R15 and CPSR for the current mode, but the SPSR and registers for other modes are not visible.

To use NoICE with the GDB protocol, you will usually need a "GDB protocol server" or "GDB daemon" program to convert between the GDB protocol and a JTAG or other connection to the ARM. Some examples of GDB protocol servers are

Unless the GDB server/daemon is a target-resident monitor, you will need to run the server/daemon program before you run NoICE.

To use the GDB protocol, select Options, Target Communications from the menu. Then select "GDB Interface " from the Interface drop list.

 ARM GDB Setup
Click on a field for more information about its function.

Serial Connection

If you are using a target stub such as a monitor ROM with a serial interface, select the Serial radio button. Then select the appropriate serial port and baud rate.

TCP/IP Connection

If you are using a GDB server/daemon (more common than a serial stub for ARM), select the TCP IP radio button. Then select the appropriate Hostname (usually "localhost", if the server/daemon is running on the same PC as NoICE) and Port. The port number should be specified in the documentation for your GDB server/daemon.

It may seem odd to use TCP/IP to communicate between programs on the same computer. However, the technique is not uncommon. It also provides a DMZ between GPL code such as GDB and commercial software such as NoICE.

Additional Commands

When GDB is selected for target communications, NoICE adds two commands to let you communicate directly with the GDB server/daemon.

Send Remote Command

    RCMD {command-string}

This command allows the user to send a string to the GDB server/daemon as a qRcmd message. The contents of such a message (your command-string) may be executed by a command handler on the GDB server. For example, if your GDB server is OpenOCD, the command is passed to OpenOCD's text command interface. Any reply from the GDB server will be shown in the NoICE Data Window. For example, with an OpenOCD server, the command

    rcmd arm7_9 sw_bkpt enable

will tell OpenOCD to enable the use of software breakpoints. The Data Window will show

    GDB qRcmd(arm7_9 sw_bkpt enable)
    software breakpoints enabled

where the first line is an echo of the command and the the second is the response from the GDB server.

This particular example is useful if your program is in RAM, because it allows the use of any number of software breakpoints, rather than the two hardware breakpoints that can be used for programs in Flash. To use this feature, the "rcmd arm7_9 sw_bkpt enable" must be placed in the Play After Reset command file.

Send Command to GDB Server/Daemon


    GDB {gdb-string}

This command allows the user to send a string to the GDB server. NoICE will turn the string into a GDB command by wrapping it in $, # and a checksum. Any reply from the GDB server will be shown in the NoICE Data Window. For example, the command

    gdb m0,4

Will tell GDB to read 4 bytes of memory from address zero. The Data Window will show

    GDB (m0,4)
    18f09fe5

where the first line is an echo of the command, the the second is the response from the GDB server. This example is a bit silly, since you could more conveniently use NoICE's built-in commands to examine memory. However, you may find it useful if you need to invoke GDB protocol commands not used by NoICE.


Drivers for JTAG Pods

Before you can use NoICE with your JTAG pod, you may need to install the appropriate driver.

If you have not already done so, you should install the driver that came with the pod, or visit the vendor's web site to get the most recent driver. This is especially true if you are running Windows Vista, which tends to hate any driver older than a week and a half...


Compiling for NoICE

The ARM has a rich instruction set and a pile of registers. These make it possible for a compiler to produce optimized code at level that isn't possible for 8-bit microprocessors. A problem with optimized code is that it can be very difficult for a debugger to deal with.

For example, if you compile an ARM program with GCC using optimization level 2 (-O2), it will in some cases generate instructions out of order with respect to the lines of C code. When you single-step this sort of code, the PC seems to jump around the code in a most peculiar manner.

We recommend that you begin by disabling optimization (-O0 in GCC) at least until you have verified NoICE's operation. Once you see how NoICE handles non-optimized code, you can try various optimization settings to see if they adversely affect debugging.

NoICE can load the .DBG files generated by the ImageCraft ARM compiler or the Elf/Dwarf files generated by most other compilers for ARM.


ARM and Thumb Modes

Most ARM cores can operate either on 32-bit ARM instructions or 16-bit Thumb instructions. This causes problems for a disassembler such as the one in NoICE: which instruction set should it use for disassembly?

The NoICE View menu lets you select a preference:


Reset Issues

ARM is a great processor, but the ARM vendors seem to compete with each other to see who can come up with the stupidest reset handling. Please read this section to see if any items apply to your hardware or JTAG interface.

Analog Devices ADuC70xx

The ADcC70xx parts have a reset pin, RST. However, the Analog Devices demo boards connect it only to a push-button - not to the JTAG reset output (pin 15). Thus, at least on these boards, JTAG can't issue a hard reset. The parts have a TRST (JTAG reset) pin - but it is shared with Port 0.3, and it must be enabled by writing to the Port's control register in order to function as TRST. This renders it pretty much useless.

There is a peripheral register, RSTSTA, which can be written to reset the entire processor and all its peripherals. Unfortunately, writing to this from JTAG causes a JTAG error, as the processor and its JTAG controller get reset during the JTAG write transaction. Thus, this register cannot be easily written to via a NoICE command.

To deal with this, the Segger J-Link incorporates special reset processing for the ADcC70xx. This will be invoked automatically when you select an ADcC70xx target from NoICE's target/chip list. If you are using a Wiggler or other non-J-Link interface, consult your documentation, or learn to live with imperfect resets.

Atmel SAM7

AT91SAM7 parts have a reset pin, NRST. Unfortunately, the micro can set the RSTC_MR control register to ignore NRST - and "ignore" is the default setting. What were they thinking? Your program runs amok, you press the reset button and - nothing happens. Power cycling is the only fail-safe reset on these chips.

JTAG can usually halt the processor and set the registers as if a reset had occurred. However, this leaves all the peripherals in unknown states. In particular, the SAM7's IAC interrupt controller has an eight-level hardware stack. Simply re-initializing it is not enough to clear out any pending interrupts. So the safest thing to do is to force a peripheral reset by writing to the RSTC_CR PERRST bit, and if desired to the EXTRST bit as well.

A second issue is that AT91SAM7 parts come out of reset running on a low-speed RC clock of 20 to 40 kHz. The crystal oscillator or PLL are not used until they are initialized and enabled, either by boot code or by NoICE. Since NoICE needs a stable clock in order to burn Flash, you must ensure that the crystal oscillator, and PLL if desired, are initialized.

The best way to deal with both the reset and the clock issues is by specifying a Play After Reset command file that contains the appropriate commands.

Here is a sample Play After Reset file that is suitable for the Atmel AT91SAM7SE-EK evaluation board, which contains an AT91SAM7SE512. A file called AT91SAM7SE-EK_Reset.noi containing this content will be installed in your NoICE\config directory. Consult your datasheet and board schematic to see what changes you might need to make for your hardware.

    ECHO AT91SAM7SE-EK_Reset.noi: configure an Atmel AT91SAM7SE-EK eval board

    ECHO - RSTC_CR: reset on-chip peripherals, since JTAG reset may have been ignored.
    OUT32 0xFFFFFD00 0xA5000004

    ECHO - WDT_MR: disable watchdog timer
    OUT32 0xFFFFFD44 0x8000

    ECHO - EFC_FMR: set 2 wait states on both Flash banks for operation at 48 MHz
    OUT32 0xFFFFFF60 0x200
    OUT32 0xFFFFFF70 0x200

    ECHO - CKGR_MOR: enable crystal oscillator (18.432 MHz), wait for MOSCS
    OUT32 0xFFFFFC20 0x4001
    IN32 0xFFFFFC68 0x01 0x01 100 waiting for MOSCS

    ECHO - CKGR_PLLR: enable PLL, *73, /14 (net 96.110 MHz), wait for LOCK
    OUT32 0xFFFFFC2C 0x10482F0E
    IN32 0xFFFFFC68 0x04 0x04 100 waiting for LOCK

    ECHO - PMC_MCKR: processor pre-scaler divide by 2, wait for MCKRDY
    OUT32 0xFFFFFC30 0x4
    IN32 0xFFFFFC68 0x08 0x08 100 waiting for MCKRDY

    ECHO - PMC_MCKR: source is PLL, processor pre-scaler divide by 2: 48.055 MHz
    OUT32 0xFFFFFC30 0x7
    IN32 0xFFFFFC68 0x08 0x08 100 waiting for MCKRDY

Some members of the AT91SAM7 family (in particular, the 7SE line) include what Atmel calls "SAM-BA" - a boot loader in ROM. After reset, this boot loader will run unless the GPNVM2 bit is set in the Flash status register.

If you use NoICE to burn the Flash on these chips, NoICE will autmatically automatically set GPNVM2 if the file being burned includes the ARM exception vectors (address 0). If the file being burned does not include address 0, or if the SAM7 variant does not include SAM-BA, NoICE will not touch GPNVM2.

Philips/NXP LPC2xxx

The LPC2xxx has a bootloader that takes control after reset. It computes a checksum on the ARM interrupt vectors. Only if the checksum is deemed correct will control be passed to the Flash reset vector. If the checksum isn't correct, the boot loader remains is control, and may be seen by NoICE.

If you use NoICE to burn the Flash on a Philips LPC2xxx, NoICE will autmatically compute and insert the checksum on the vectors.

However, the boot loader scheme means that the only way JTAG can "reset" a Philips LPC2xxx is to reset it, let it run long enough for the boot loader to do its stuff, and then stop the program. Unfortunately, at the time of stop there is no telling what the states of the various peripherals are, whether RAM or Flash or the boot loader mapped at location zero, etc.

STMicroelectronics STR9xx

The STR7xx family has a straightforward reset and startup sequence, and needs no special handling. Not so the STR9xx family. The main difficulty is that some of the clock configuration registers are not initialized by a process reset - only by a power-on reset (POR). In order to give a consistent platform for Flash burning, these registers need to be explicitly initialized.

The best way to do this is by specifying a Play After Reset command file that contains the appropriate commands.

Here is a sample Play After Reset file that is suitable for all current STR91xFA parts. A file called STR9xx.noi containing this content will be installed in your NoICE\config directory. Consult your datasheet to verify that these settings are appropriate for starting your application. Note that the intent of this file is to place the chip in the state it would be in after a powerp-on reset. Your application will likely need to do other initialization, especially to use the PLL etc. The file sets a simple initialization suitable for the Flash burner.

	REM - SCU_CLKCNTR : defaults: FMICLK=RCLK, PCLK=RCLK, RCLK=fMSTR, fMSTR=fOSC
	OUT32 0x5C002000 0x00020002
	REM - SCU_PLLCONF : defaults: PLL disabled
	OUT32 0x5C002004 0x0003C019
	REM - SCU_PWRMNG : defaults: do not power down Flash during debug, normal run mode
	OUT32 0x5C00200C 0x00000000
	REM - SCU_PCGR0   : defaults: enable clocks for EXT_MEM, EMI, SRAM, PQFBC, FMI
	OUT32 0x5C002014 0x000000DB
	REM - SCU_PRR0    : default: release resets for EMI, SRAM, PQFBC, FMI
	OUT32 0x5C00201C 0x00001053
	REM - SCU_PECGR0  : default: emulation mode clocks: let all run (includes SRAM, PQFBC, FMI)
	OUT32 0x5C00202C 0x00000FFB
	REM - SCU_SCR0 : default except SRAM size up to 96KB, PQFBC disabled
	OUT32 0x5C002034 0x00000196

NoICE includes configurations for STR9xx chips configured to boot from Flash Block 0 (the chip default) or from Flash Block 1 (the boot block). NoICE does not include the capability to change the boot configuration of an STR9xx. However, if you are using a Segger J-Link, Segger's DLL and driver download includes a utility called JLinkSTR91x.exe that can do this an other functions such as manipulating security bits and programming the OTP.

Texas Instruments TMS470

The TMS470 parts have two features that complicate debugging. First, unlike ARM chips from other vendors, RAM and Flash are not at fixed addresses, but must be enabled by programming chip-select registers. Second, there are several types of security keys which must be massaged before any external access is allowed.

Annoyingly, the security keys aren't tucked up against the exception vectors - they are in the last 32 bytes of the first sector of Flash. That means that they are at addresses 0x1FE0, 0x3FE0, or 0xFFE0, depending on the size of each part's Flash sectors. This in turn causes great fun in your linker script as you try to avoid these areas. NoICE's Flash burner will not allow you to program anything except for 0xFF into the security bytes, thus ensuring that you don't inadvertently turn your TMS470 into a brick.

The best way to deal with these issues is by specifying a Play After Reset command file that contains commands that perform the necessary initialization.

Here is a sample Play After Reset file that is suitable for the IAR TMS470R1B1M evaluation board, which contains a TMS470R1B1M. A file called TMS470R1B1M.noi containing this content will be installed in your NoICE\config directory, and similar files may be found there for other TMS470 parts. Consult your datasheet and board schematic to see what changes you might need to make for your hardware.

    echo Configure TMS470R1B1M for Flash
    ; 24-November-2007

    ; Ignore errors while we unlock security, etc.
    IgnoreErrors 1

    echo SYSECR: no reset on bad address etc.
    out32 0xFFFFFFE0 0x4007

    echo MFBALR0, MFBAHR0: 1 Meg of Flash at 0
    out32 0xFFFFFE04 0x00B0
    out32 0xFFFFFE00 0x0000

    echo MFBAHR2, MFBALR2: 64K of RAM at 0x40_0000.
    out32 0xFFFFFE10 0x0040
    out32 0xFFFFFE14 0x0070

    echo MFBALR1,3,4,5 inactive
    out32 0xFFFFFE0C 0x0000
    out32 0xFFFFFE1C 0x0000
    out32 0xFFFFFE24 0x0000
    out32 0xFFFFFE2C 0x0000

    echo MCBALR0,1,2,3,4,5 inactive
    out32 0xFFFFFE34 0x0000
    out32 0xFFFFFE3C 0x0000
    out32 0xFFFFFE44 0x0000
    out32 0xFFFFFE4C 0x0000
    out32 0xFFFFFE54 0x0000
    out32 0xFFFFFE5C 0x0000

    ; Activate the chip selects
    out32 0xFFFFFE04 0x01B0

    echo Unlock security
    ; MSMSCR: force into a secure state
    out32 0xFFFFF724 0x80000000
    ; Read security keys at end of first Flash sector
    in32 000000FFE0
    in32 0x0000FFE4
    in32 0x0000FFE8
    in32 0x0000FFEC

    ; Restore normal error processing
    IgnoreErrors 0

    echo GCR: Mult by 8, Div by 8: CPU frequency = SYSCLK = crystal frequency
    ; (7.5 MHz on TI/IAR Kickstart board)
    ; Default after reset is 0x000F, SYSCLK = crystal/2, but erratum ZPLL#1 for B1M 
    ; and A288 says that MULT4 bit doesn't work on those parts.  For simplicity and
    ; consistency, we set GCR to ensure SYSCLK = crystal.
    out32 0xFFFFFFDC 0x0007

    echo PCR: CLKDIV=1111 (ICLK=SYSCLK/16), enable peripherals
    out32 0xFFFFFD30 0x1E
    out32 0xFFFFFD30 0x1F

    echo Device ID
    in32 0xFFFFFFF0

JTAG Reset

Making life even more interesting, not all JTAG interface methods allow a reliable reset:


Hardware and Software Breakpoints

Most members of the ARM family contain two hardware breakpoints. NoICE uses these breakpoints in conjunction with JTAG to allow single-step and breakpoint operations on programs executing from Flash.

If your code is in RAM, you may be able to use software breakpoints, which are not limited in number. To do this, NoICE uses one of the hardware breakpoints to trap the fetching of a particular unused ARM instruction. Because of this, only one hardware breakpoint is available when software breakpoints are in use.

If you are using the Segger J-Link interface, software breakpoints are currently not available. This may change when Segger implements the feature in a future version of their JLinkARM.DLL. Software breakpoints are available if you use the Segger RDI interface.

If you are using the RDI interface, NoICE will automatically allocate breakpoints as hardware or software based on the location of your breakpoint.

If you are using OpenOCD, however, you must manually enable software breakpoints, typically by including the NoICE command

    rcmd arm7_9 sw_bkpt enable

in your Play After Reset command file, or the equivalent command in OpenOCD's reset script.

When properly configured, NoICE will not let you set more hardware or software breakpoints that your target can support.


Using NoICE with H-JTAG

H-JTAG (http://hjtag.blogspot.com or http://twentyone.blogchina.com) is a free RDI interface that works with the Macraigor (http://www.macraigor.com) Wiggler JTAG pod, or a clone such as the Olimex (http://www.olimex.com/dev/arm-jtag.h) pod.

As with many software projects, the maturity of the documentation lags that of the source code. Before you run NoICE, you must run the H-JTAG server (H-JTAG.EXE). This program will attempt to communicate with your target, and inform you of its success or failure. Once this is done, you can exit H-JTAG.exe and run NoICE. An H-JTAG server program will continue to run, and is visible in the task tray.

If H-JTAG.EXE complains that it can't find your target, you may need to reconfigure it. I don't have a Macraigor pod, but with the Olimex pod, you will need to change the JTAG settings in H-JTAG.EXE. Select "Settings" from the menu, then "JTAG settings".

As shown in the screen-shot below, TMS, TCK,TDI, and TDO are all preset correctly if you select Wiggler as the hardware device. However nTRST must be set to "Pin6 D4", and "nTRST Output Inverted" must not be checked. nSRST can be set to "NO SYS RST", or nSRST can be set to "Pin2 D0" with "nSRST Output Inverted" checked.

H-JTAG setup for Olimex JTAG pod

Note: The H-JTAG documentation and the H-Flash Flash burner program discuss only Philips LPCxxx targets. However, NoICE can use H-JTAG to debug non-Philips targets as well.


Using NoICE with OpenOCD

OpenOCD (http://developer.berlios.de/projects/openocd) is a free, open-source program that implements both a GDB server and a simple TTY (via TELNET) interface to ARM JTAG. OpenOCD works with

OpenOCD is under continuous development. We recommend that you use a version of OpenOCD built from revision 100 or later of the SVN source tree.

OpenOCD Using Cygwin

The main distribution of OpenOCD uses cygwin. If you use cygwin for other tools, or if you want to be able to build OpenOCD from the source code, you will probably want to use the cygwin version of OpenOCD.

If you aren't familiar with cygwin-based programs, you can find helpful step-by-step instructions for installing and using OpenOCD at http://gandalf.arubi.uni-kl.de/avr_projects/arm_projects/index.html

Note: cygwin attempts to simulate a UNIX/Linux environment under Windows, which can lead to some peculiar culture clashes. If you don't know UNIX/Linux, cygwin can seem very strange indeed. We can help you try to get OpenOCD running, but we cannot and will not help you learn how to install and use cygwin. Can you say "Google"?

OpenOCD Without Cygwin

If you would prefer to avoid cygwin, you can find informtation about an alternative from YAGARTO (Yet Another GNU ARM Toolchain) at http://www.yagarto.de or Freddie Chopin at http://www.freddiechopin.info/

Using OpenOCD With NoICE

Before you run NoICE, you must run the OpenOCD server (typically called openocd.exe, openocd-pp.exe, or openocd-ftd2xx.exe, depending on how the server was built and what kind of JTAG pod you are using). This program will attempt to communicate with your target, and inform you of its success or failure via a no-nonsense console window as shown below.

OpenOCD server output

Once this is done, you can run NoICE.

OpenOCD must be run with a configuration file to specify various target options. More information about these options, and a variety of sample configuration files are available from OpenOCD and YAGARTO

As an example, to use the Olimex Wiggler clone we run

    openocd -farm7_wig.cfg

where the file arm7_wig.cfg contains:

    #daemon configuration
    telnet_port 4444
    gdb_port 3333
    #interface
    interface parport
    parport_port 0x378
    parport_cable wiggler
    jtag_speed 0
    #use combined on interfaces or targets that can't set TRST/SRST separately
    reset_config trst_and_srst srst_pulls_trst
    #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 200

As an example, to use the Olimex ARM-USB-OCD we run

    openocd -farm7_olimex_usb.cfg

where the file arm7_olimex_usb.cfg contains:

    #daemon configuration
    telnet_port 4444
    gdb_port 3333
    #interface
    interface ft2232
    ft2232_device_desc "Olimex OpenOCD JTAG A"
    ft2232_layout olimex-jtag
    ft2232_vid_pid 0x15ba 0x0003
    jtag_speed 3
    #use combined on interfaces or targets that can't set TRST/SRST separately
    reset_config trst_and_srst srst_pulls_trst
    #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

OpenOCD does not implement the GDB reset message. The GDB protocol document deprecates the reset message, so OpenOCD is certainly "legal", but reset is a very useful message for embedded debugging. In order to get a reliable reset of your target in the absence of GDB reset, we recommend that you specify a Play After Reset command file with content similar to the following:

    ECHO Send OpenOCD commands to reset a Philips LPC21xx
    RCMD reset run_and_halt
    ; OpenOCD reset may take a while, so give it time to complete
    WAIT 500
    ; "run_and_halt" leaves the PC in the boot ROM.  Fake a "textbook" reset.
    RCMD soft_reset_halt

    ; If you want to use software breakpoints for programs in RAM, change
    ; the final parameter in the following RCMD command from "disable" to
    ; "enable.  This will leave you only one hardware breakpoint, so do 
    ; this ONLY if you need to use software breakpoints.
    RCMD arm7_9 sw_bkpt disable

A file called OpenOCD_Reset.noi containing this content will be installed in your NoICE\config directory.

"run_and_halt" is the recommended reset parameter for the Philips LPC2xxx family. In most cases, it can be used for other vendor's ARM chips as well. Consult the OpenOCD documentation for more information on other reset types.

Note that these commands are specific to OpenOCD. If you are using another GDB server, and it does not support the GDB reset message (NoICE will tell you this the first time you run), consult your server's documentation to see if there is an alternate method to cause a target reset.

Additional Information

An OpenOCD FAQ is available at http://openfacts.berlios.de/index-en.phtml?title=OpenOCD_FAQ

SparkFun Electronics maintains an OpenOCD forum at http://www.sparkfun.com/cgi-bin/phpbb/viewforum.php?f=18. Read past postings and you are likely to find a solution for your problem. If not, post your OpenOCD-related questions. (If you have NoICE-related questions, please contact us.)


Running a GDB or RDI Server or Daemon Automatically

Some RDI implementations, including H-JTAG, and most GDB stub implementations, including OpenOCD and Macraigor's OCDemon, require server or daemon programs to be run before NoICE can use them.

You can run such programs manually. However, you may find it convenient to let NoICE run them for you. To configure this, select "Options", "Extensions..." from the menu and congifure the Run At Startup extension.


Performance

We ran simple time trials on a 2 GHz PC running Windows XP, loading and saving a 32K file into target RAM and Flash. The target was a Philips LPC2106 running at 14 MHz. Your results may vary depending on PC, operating system, and changes made by the vendors to pod software and interface DLLs.

JTAG pod / Server NoICE Interface Load 32K (seconds) Save 32K (seconds) Burn 32K (seconds)
Segger J-Link (USB) Segger J-Link Interface 0.77 2.94 5.15
Segger J-Link (USB) with RDI license RDI Interface 0.36 2.27 5.72
Olimex Wiggler clone (parallel) with H-JTAG RDI Interface 2.88 3.29 10.94
Olimex Wiggler clone (parallel) with OpenOCD GDB Interface 6.61 6.70 11.11
Olimex ARM-USB_OCD with OpenOCD GDB Interface 6.50 6.40 10.34

The slower performance with OpenOCD compared to RDI and J-Link is most likely due to the fact that NoICE must communicate via TCP/IP with the OpenOCD server running as a separate process. In contrast, the Segger DLL and RDI interfaces provide a function call API within a single process. Even if OpenOCD provided a function-call interface, NoICE couldn't use it, since OpenOCD is released under GPL and NoICE is not. However, even the slowest interface shown above is faster than most BDM interfaces for HC12, and OpenOCD provides a very pleasant debugging environment.


Limitations, Bugs, and Stuff Not Implemented Yet

As we mentioned above, ARM processors and JTAG interfaces come in a wide range of flavors. We will do our best to have NoICE support as many as we can. This section lists some of the things we either haven't gotten to yet or don't have solutions for.

If any of these are big issues for you, please contact us to see if we have a solution, or to propose a solution to us.


Terminal Interface Using ARM DCC

The ARM7's Embedded ICE includes a Debug Communications Channel, or DCC, as described in ARM docuemnt DAI0038B. While most features of the Embedded ICE can only be accesses by the host via JTAG, the DCC can also be accessed by the target processor, using co-processor instructions.

The DCC provides a 32-bit data register from the host to the target, and another from the target to the host. Each register has a busy/empty status bit. By using these registers, data can be exchanged between the target and the host. Various ARM debuggers have used the DCC for various purposes, including semi-hosting, live and access to target memory. NoICE has implemented a simple "virtual serial port", following the description in DAI0038B.

When the target is running, NoICE will poll the DCC for data from the host. When a non-zero value is received, NoICE will take one of two actions:

If keyboard focus is in the Output window and the user presses any key other than a function or cursor key while the target is executing, the ASCII/Windows representation of the key will be sent to the target via the DCC. NoICE will send each keyhit as a 32-bit value via the DCC.

Currently, NoICE supports the DCC interface only when using the J-Link.

The GDB Remote Protocol includes the 'O' message, which can carry text from the target to the host. If NoICE receives such a message from a gdb server, it will display the text in the Output Window. The GDB Remote Protocol does not include a mechanism to sent keyhits to the target. OpenOCD does not currently implement the 'O' message, although it shouldn't be hard for someone with a bit of ambition to modify OpenOCD to use DCC to implement 'O'.

The RDI standard includes support for the DCC. NoICE does not currently support this RDI feature. It may be supported in a future release.


NoICE (tm) Debugger, Copyright 2012 by John Hartman

Using NoICE - Contact us - NoICE Home