This page is is part of my embedded system notes.
OpenOCD stands for Open On-Chip Debugger. The project home page is:
http://openocd.sourceforge.net/and the documentation is at:
http://openocd.sourceforge.net/doc/html/index.html
While the first chapter of the documentation does try to answer the question "What is OpenOCD?", it could really benefit from a slightly higher overview. Below is what I think are the important aspects of OpenOCD:
http://openocd.sourceforge.net/doc/html/About.html
The next issue is to select with interface adapter to use. The list of supported adapters is in the second chapter:
http://openocd.sourceforge.net/doc/html/Debug-Adapter-Hardware.htmlWhat is really desired is a table that lists the various debug adapters and their various features. Unfortunately, that table does not exist. The table below summarizes the ones I researched:
I basically decided that I wanted a USB dongle that used USB 2.0 High Speed mode (480 Mpbs). Further, I was looking for a dongle that supported RTCK (also known as adaptive clocking.) This adaptive clocking issue is discussed in the OpenOCD FAQ:
Vendor Product Host
InterfaceRTCK RS-232 Target
InterfaceCost JTagKey2 480 Mbps Yes ? ? €$75 (OEM) Signalizer H2 480 Mbps Yes ? ? $79 (Canadian) Olimex ARM-USB-OCD-H 480 Mbps Yes Yes 20-pin $54.95 Olimex ARM-USB-Tiny-H 480 Mbps Yes No 20-pin $39.95 Tin Can Tools Flyswatter2 480 Mbps Yes Yes 20-pin $89.00 Tin Can Tools Flyswatter 12 Mbps No Yes 14-pin $49.95 SeeedStudio
Dangerous PrototypesBus Blaster 2 12 Mbps Yes No 20-pin $34.95
http://openocd.sourceforge.net/doc/html/FAQ.html#FAQ-RTCKI only include the Flyswatter (version 1) because I own one of them. For my purposes, the ARM-USB-Tiny-H from Olimex looks like it has the right features at a reasonable cost. The Bus Blaster2 looks nice as well, but it uses the second port on the FT2232H for programming the CPLD rather than for a serial connection.
The next task is to get OpenOCD installed on your machine. For a Linux distribution that uses .deb packages (e.g. the Ubuntu distribution), a precompiled version of OpenOCD can be obtained via the following command:
sudo apt-get install openocd
Unfortunately, there is a good chance this will be
an older version of OpenOCD.
Instead, OpenOCD site recommends that you download the source code and compile from scratch. I decided to follow this advice, and my experiences are listed below.
Like many people, I have a downloads directory that I use to download and build software. For Linux, the following tasks get the job done:
# Create the directories, download the code and unpack:
cd ~/download # My down load directory
mkdir openocd
cd openocd
wget http://superb-dca2.dl.sourceforge.net/project/openocd/openocd/0.6.1/openocd-0.6.1.zip
unzip openocd-0.6.1.zip
cd openocd-0.6.1
Now the everything is downloaded.
The most natural thing to do is type (hint: do not do this):
./configure
make
sudo make install
Unfortunately, that will create a version of OpenOCD
that does not have any transports compiled into it.
(I found this out by accident.)
The correct thing to do is to read the README
file that explains that you need to add one or more
--enable--{interface} options
to ./configure.
The correct process is list the contents of the
tcl/interface directory:
ls tcl/interface
# List of available interfaces is shown:
Next, find the interface files that correspond to each
of your debug adapters. For each .cfg
file, search for the wordinterface.
In my case, the correct file is
tcl/interface/flyswatter.cfg and I get
the following:
grep interface tcl/interface/flyswatter.cfg
interface ft2232
In this case, the needed interface is ft2232.
Once you know the correct interface name, read through
the README file and follow the instructions
to properly configure that interface. In the case of
the ft2232 interface, there are two options --
use the proprietary closed source driver from FTDI or use
the an open source driver. I selected the latter. Thus,
the steps for configuring OpenOCD for my flyswatter are:
# Get the FTDI libraries for the FTDI USB to serial chip:
sudo apt-get install libftdi-dev libftdi1
# Password may be necessary:
# Get everything cleaned, configured, compiled and installed:
make clean
./configure --enable-ft2232_libftdi
sudo make install
# Password may be necessary:
Until the permissions of the USB connection are fixed up,
I run openocd as root using the
sudo program. When I run the command,
I get the following output results:
sudo openocd -f interface/flyswatter.cfg -f target/lpc1768.cfg
#Password may be necessary:
Open On-Chip Debugger 0.5.0 (2012-04-09-00:20)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.berlios.de/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
Error: An adapter speed is not selected in the init script. Insert a call to adapter_khz or jtag_rclk to proceed.
in procedure 'init'
These error messages are pretty straight-forward.
Section 8 of the OpenOCD documentation explains
about the adapter_khz and
jtag_rclk features:
http://openocd.sourceforge.net/doc/html/Debug-Adapter-Configuration.html#JTAG-SpeedWhile the flyswatter2 does support RCLK, the original flyswatter (which I have) does not; so
adapter_khz is the command to use for me.
The following is what happened next:
sudo openocd -f interface/flyswatter.cfg \
-c "adapter_khz 1000" -f target/lpc1768.cfg
Open On-Chip Debugger 0.5.0 (2012-04-09-00:20)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.berlios.de/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
1000 kHz
adapter_nsrst_delay: 200
jtag_ntrst_delay: 200
10 kHz
Info : clock speed 10 kHz
Error: JTAG scan chain interrogation failed: all ones
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway...
Error: lpc1768.cpu: IR capture error; saw 0x0f not 0x01
Warn : Bypassing JTAG setup events due to errors
Warn : Invalid ACK 0x7 in JTAG-DP transaction
Polling target failed, GDB will be halted. Polling again in 100ms
Polling target failed, GDB will be halted. Polling again in 300ms
Polling target failed, GDB will be halted. Polling again in 700ms
...
In another terminal window, I was able to connect to
the OpenOCD network service as follows:
telnet localhost 4444
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
Polling target failed, GDB will be halted. Polling again in 6300ms
Polling target failed, GDB will be halted. Polling again in 6300ms
>
...
This looks like success to me, since I do not actually
have a microcontroller connected to the other end of
Flyswatter yet.
For Linux, there is a file called
contrib/openocd.udev that needs to be
renamed to 52-openocd.rules:
cd /tmp
cp .../contrib/openocd.udev 52-openocd.rules
After the file is copied over to /tmp.
we need to make sure that each user that needs to
access in the debug adapter is in the
plugdev group. Running the
groups command will list all the groups
that user is in. If plugdev is not
listed, change all occurrences of plugdev
in 52-openocd.rules to the different
group. For me, I changed plugdev to
users using an editor. Finally, copy
the file up to /etc/udev/rules.d/.
cd /tmp
sudo cp 52-openocd.rules /etc/udev/rules.d
Eventually, we want to be able to support more than
one debug adapter at once so that we can debug a
system that has more than one microcontroller.
The following URL's, explain how to deal with the
semi-random order in which Linux assigns devices
that are plugged into USB sub-system using the
UDEV system:
The high level concept is that the Linux kernel
in conjunction with UDEV manage the contents of
the /dev directory. My understanding
is that the kernel uses the devfs
file system to construct all of the device nodes in
/dev. (For Ubuntu, devfs
file system is mounted at /sys.)
The UDEV system is notified by
devfs when there are any additions,
modifications, or deletions to /dev.
UDEV is responsible for changing
permissions, adding symbolic links, etc. to
/dev using a bunch of rules files.
The system wide rules files live in
/lib/udev/rules.d, and the use supplied
rules files live in /etc/udev/rules.d.
In general,
/sys is organized as a hierarchical tree of
device nodes. The USB sub system shows up a tree
with a USB root device, zero, one or more, USB
hubs (arranged as a tree), with a number of USB
devices sprinkled through out the tree.
The first step is to plug the serial USB cable into
a USB socket. The first USB serial is assigned to
/dev/ttyUSB0. A full dump of such a
serial port is found with something like:
udevadm info -a -p /class/tty/ttyUSB0
This results in a fairly long list of data:
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.
looking at device '/devices/pci0000:00/0000:00:12.2/usb1/1-4/1-4.3/1-4.3:1.0/ttyUSB0/tty/ttyUSB0':
KERNEL=="ttyUSB0"
SUBSYSTEM=="tty"
DRIVER==""
looking at parent device '/devices/pci0000:00/0000:00:12.2/usb1/1-4/1-4.3/1-4.3:1.0/ttyUSB0':
KERNELS=="ttyUSB0"
SUBSYSTEMS=="usb-serial"
DRIVERS=="ftdi_sio"
ATTRS{latency_timer}=="1"
ATTRS{port_number}=="0"
looking at parent device '/devices/pci0000:00/0000:00:12.2/usb1/1-4/1-4.3/1-4.3:1.0':
KERNELS=="1-4.3:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="ftdi_sio"
ATTRS{bInterfaceNumber}=="00"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bNumEndpoints}=="02"
ATTRS{bInterfaceClass}=="ff"
ATTRS{bInterfaceSubClass}=="ff"
ATTRS{bInterfaceProtocol}=="ff"
ATTRS{modalias}=="usb:v0403p6001d0600dc00dsc00dp00icFFiscFFipFF"
ATTRS{supports_autosuspend}=="0"
ATTRS{interface}=="FT232R USB UART"
looking at parent device '/devices/pci0000:00/0000:00:12.2/usb1/1-4/1-4.3':
KERNELS=="1-4.3"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{configuration}==""
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bmAttributes}=="a0"
ATTRS{bMaxPower}==" 90mA"
ATTRS{urbnum}=="15"
ATTRS{idVendor}=="0403"
ATTRS{idProduct}=="6001"
ATTRS{bcdDevice}=="0600"
ATTRS{bDeviceClass}=="00"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bNumConfigurations}=="1"
ATTRS{bMaxPacketSize0}=="8"
ATTRS{speed}=="12"
ATTRS{busnum}=="1"
ATTRS{devnum}=="90"
ATTRS{version}==" 2.00"
ATTRS{maxchild}=="0"
ATTRS{quirks}=="0x0"
ATTRS{authorized}=="1"
ATTRS{manufacturer}=="FTDI"
ATTRS{product}=="FT232R USB UART"
ATTRS{serial}=="A800I7X0"
{And some more for good measure!}
The first section corresponds to the device, the next
levels ups correspond to the USB hubs (if any), leading
up to the root of the /sys/devices tree.
A rule file has a name of the form
##-name, where ##
is a two digit decimal number. Lower numbers are
processed before higher numbers.
name is user selected name
that suggests what the rules file contains. For
us, the file name is 52-openocd.rules
The file contains a list of rules, where each rule is on a single line. The left half of the rule is a sequence of one or more patterns to match, and the right have is a sequence of one or more operations to perform.
The patterns are of the form:
KERNEL=="..."
SUBSYSTEM=="..."
DRIVER=="..."
KERNELS=="..."
SUBSYSTEMS=="..."
DRIVERS=="..."
ATTRS{name}=="..."
SYMLINK+="..."
MODE="..."
GROUP="..."
In order to properly match the device, at least
one KERNEL, SUBSYSTEM,
or DRIVER patter must be specified.
In our case, KERNEL=="ttyUSB*" and/or
SUBSYSTEM=="tty" will work. If neither
of these are present, the symbolic link will probably
be attached to the wrong device node (e.g.
/dev/bus/usb/001/003.)
The serial number, vendor id, and product id
are excellent values to further refine the
device selection. For example,
ATTRS{idVendor}=="0403" and
ATTRS{idVendor}=="6001" will
match a typical FTDI serial USB cable.
ATTRS{serial}=="serial_number"
will match a specific serial number.
There is the final catch, the "parent" patterns must only match one parent node. (I do not know why, but what little documentation is out there is pretty adamant about this.)
OpenOCD is perfectly happy to let gdb download an executable image into a microcontroller attached to a debug adapter. For the NXP series of microcontrollers, there is an issue concerning checksums.
The ROM bootloader in the NXP LPCxxxx embedded microcontrollers (ARM Cortex M1-4) will not transfer control to the code in flash memory unless the first eight 32-bit words in the flash memory starting at 0x00000000 sum to 0. This quick little consistency check is to prevent transferring control from the ROM bootloader to "incorrect" code in flash memory.
The location where the checksum is stored varies depending upon which version of the chip is used. Some NXP chips store the checksum in the 7th word and others store it in the 5th word. OpenOCD has different variants for the NXP driver. The code below is extracted from OpenOCD and show what the variants are and how the checksum is computed:
http://code.google.com/p/micropendousx/source/browse/trunk/MicropendousX/Vector_Checksum_Calculator.c
The solution to this problem is to have a program
that reads in the executable image, computes the
correct checksum, and writes the updated executable
back out again. I searched the net for such a program
and could not find it. So, I wrote my own program
to perform the checksum modification called
nxp_checksum:
http://gramlich.net/projects/nxp_checksum/nxp_checksum.cI am providing
nxp_checksum to the net
just in case other people find it useful.
If the checksum is not properly computed, the following error message will show up from OpenOCD:
Verification will fail since checksum in image (...) to be written to flash is different from calculated vector checksum (...).
To remove this warning modify build tools on developer PC to inject correct LPC vector checksum.
I suspect that it would not be too difficult for
OpenOCD to write the checksum into the correct
location, but until it does, at least it detects
the problem and lets you know.
Clocking can be a real chore on microcontrollers that have the ability to change their clock speed. The NXP LPCxxxx microcontrollers have this capability. When they first start, they are running off the internal RC oscillator which runs at 4 MHz. In order, to successfully use the JTAG interface, it should be running slower than that. Eventually, the microcontroller can switch over to a PLL (Phase locked loop) connected to an external crystal, at which time the computer can run at a substantially higher speed (e.g. 100 MHz.) The wide disparity in clock speeds causes issues with JTAG clocking.
The simplest solution is to use the RTCK signal that is available on some ARM microcontrollers. If the debug adapter supports RTCK, the debug adapter will automatically adapt to changes in microcontroller clock speed. For example, the LPC176x microcontrollers (QFP-100) have RTCK and the LPC175x (QFP-80) do not. When designing a board, if you have the option of choosing a ARM microcontroller with RTCK support, it can simplify the JTAG clocking issue.
If RTCK is not an option, messing around with clock speeds is needed. The issues are discussed in section 6.2.4 in the OpenOCD documentation:
http://openocd.sourceforge.net/doc/html/Config-File-Guidelines.html#index-config-file_002c-board-22
The basic solution is to start with the debug adapter clock speed slow immediately after a reset. Another command can be used to "jam" a faster clock speed into the microcontroller and then update the adapter clock speed to be faster.
An example of this can be found in the
board/mcb1700.cfg configuration
file that ships with OpenOCD. This file is
reproduced below:
# Keil MCB1700 PCB with 1768
#
# Reset init script sets it to 100MHz
set CCLK 100000
source [find target/lpc1768.cfg]
global MCB1700_CCLK
set MCB1700_CCLK $CCLK
$_TARGETNAME configure -event reset-start {
# Start *real slow* as we do not know the
# state the boot rom left the clock in
jtag_khz 10
}
# Set up 100MHz clock to CPU
$_TARGETNAME configure -event reset-init {
# PLL0CON: Disable PLL
mww 0x400FC080 0x00000000
# PLLFEED
mww 0x400FC08C 0x000000AA
# PLLFEED
mww 0x400FC08C 0x00000055
# CCLK=PLL/4 (=100 MHz)
mww 0x400FC104 0x00000003
# CLKSRCSEL: Clock source = internal RC oscillator
mww 0x400FC10C 0x00000000
# PLL0CFG: M=50,N=1 -> PLL=400 MHz
mww 0x400FC084 0x00000031
# PLLFEED
mww 0x400FC08C 0x000000AA
# PLLFEED
mww 0x400FC08C 0x00000055
# PLL0CON: Enable PLL
mww 0x400FC080 0x00000001
# PLLFEED
mww 0x400FC08C 0x000000AA
# PLLFEED
mww 0x400FC08C 0x00000055
sleep 50
# PLL0CON: Connect PLL
mww 0x400FC080 0x00000003
# PLLFEED
mww 0x400FC08C 0x000000AA
# PLLFEED
mww 0x400FC08C 0x00000055
# Dividing CPU clock by 8 should be pretty conservative
#
#
global MCB1700_CCLK
jtag_khz [expr $MCB1700_CCLK / 8]
# 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 Table 612. Memory Mapping Control register (MEMMAP - 0x400F C040) bit description
# Bit Symbol Value Description Reset
# value
# 0 MAP Memory map control. 0
# 0 Boot mode. A portion of the Boot ROM is mapped to address 0.
# 1 User mode. The on-chip Flash memory is mapped to address 0.
# 31:1 - Reserved. The value read from a reserved bit is not defined. NA
#
# http://ics.nxp.com/support/documents/microcontrollers/?scope=LPC1768&type=user
mww 0x400FC040 0x01
}
There are two OpenOCD event handlers called
reset-start and reset-init.
The target event handers are briefly discussed in section
11.5 of the documentation:
http://openocd.sourceforge.net/doc/html/CPU-Configuration.html#Target-Events
The first event handler is called when the processor is reset via the following command issued in GDB:
This causes themonitor reset halt
reset-start event code
to be executed. In the example above, this sets the
adapter speed to 10 kHz using:
In actually, thejtag_khz 10
jtag_khz command has been
superseded by the adapter_khz command.
The code for the second event handler uses a bunch of
memory write word (mww) commands to
load up and start the on board microcontroller PLL
(phase locked loop.) This code can be manually
initiated by the following command from GDB:
After executing this code, the PLL is updated to run at a speed of 100 MHz and the adapter clock rate is updated substantially.monitor reset init
The following steps seem to work for me:
nxp_program.
nxp_checkusm your_executable_in_ELF_format
{correct_arm_toolchain_path}/gdbtui
file your_executable_in_ELF_format
openocd -f interface/flyswatter.cfg -f board/robus_uc1754.cfg
target remote localhost:3333
monitor reset halt
reset-init event.
monitor reset init
load
reset-start event got triggered:
monitor reset halt
main:
break main
main:
continue
monitor adapter_khz 6000
step,
next, continue, and
Control-C to interrupt execution.
Just as a random comment, I found the article over at:
http://fun-tech.se/stm32/OpenOCD/gdb.phpto be useful.
This section has been replaced by the next section called Connectors Revisited. This section is retained only because it contained the original research.
I will start this section with the following quote:
The wonderful thing about standards is that there are so many of them to choose from. -- Grace HopperAlong those line, the URL below lists a bunch of different JTAG pin-outs:
http://www.jtagtest.com/pinouts/When designing a printed circuit board, the PCB designer has to select a connector and assign the signals to the connector. My thoughts on selecting a JTAG connector follow.
While there are many possible JTAG connectors, I have selected three to focus the discussion:
20-Pin ARM JTAG Connector Pin Use Use Pin 1 (VREF) Voltage Reference (VSUPPLY) Supply Voltage 2 3 (nTRST) Test Reset (GND) Ground 4 5 (TDI) Test Data In (GND) Ground 6 7 (TMS) Test Mode Select (GND) Ground 8 9 (TCK) Test Clock (GND) Ground 10 11 (RTCK) Return Clock (GND) Ground 12 13 (TDO) Test Data Out (GND) Ground 14 15 (nSRST) System Reset (GND) Ground 16 17 (DBGRQ) Debug Request (*) (GND) Ground (*) 18 19 (DGBACK) Debug Acknowledge (*) (GND) Ground (*) 20
14-Pin ARM JTAG Connector Pin Use Use Pin 1 (VREF) Voltage Reference (GND) Ground 2 3 (nTRST) Test Reset (GND) Ground 4 5 (TDI) Test Data In (GND) Ground 6 7 (TMS) Test Mode Select (GND) Ground 8 9 (TCK) Test Clock (GND) Ground 10 11 (TDO) Test Data Out (nSRST ) System Reset 12 13 (VREF) Voltage Reference (GND ) Ground 14
10-Pin AVR JTAG Connector Pin Use Use Pin 1 (TCK) Test Clock (GND) Ground 2 3 (TDO) Test Data Output (VREF) Voltage Reference 4 5 (TMS) Test Mode Select (nSRST) System Reset (*) 6 7 no connection (nTRST) Test Reset (*) 8 9 (TDI) Test Data Input (GND) Ground 10
The table below indicates which signals are present on which connectors:
Signal ARM-20 ARM-14 AVR JTAG Altera Byte Blaster (GND) Ground 4,6,8,10,12,14,16,18,20 2,4,6,8,10,14 2,10 2,10 (VREF) Voltage Reference 1 1,13 4 4 (nTDST) Test Reset 3 3 6 - (TDI) Test Data In 5 5 9 9 (TMS) Test Mode Select 7 7 3 3 (TCK) Test Clock 9 9 1 1 (TDO) Test Data Output 13 11 3 3 (nSRST) System Reset 15 12 6 - (VSUPPLY) Voltage Supply 2 - - - (RTCK) Return Test Clock 11 - - - (DBGRQ) Debug Request 17 - - - (DBGACK) Debug Acknowledge 19 - - -
When designing a printed circuit board, a connector choice is needed. These are my thoughts on the JTAG connector topic:
I know that the NXP LPC13xx and LPC17xx microcontrollers have a serial boot loader in the ROM. When the RESET pin on the microcontroller is triggered, the code in the ROM is executed. This code checks one pin to see if it is low, and if so, enters a serial boot loader that allows the microcontroller to be programmed using one of the microcontroller UART's.
I suspect, but do not know, that other ARM embedded microcontrollers do the same thing. I have "standardized" on a common 5-pin connector for doing ISCP:
I have a little board that takes the 6 pins from a 3.3V FTDI RS-232 cable, adds a reset and program button, provides 5 signals above. In order to program a microcontroller, I hold the [Program] button down followed by depressing the [Reset] button to force the microcontroller into the serial boot loader. I then run a program called
Pin Signal Description 1 GND Ground 2 TXD Transmit Data 3 nRESET System Reset 4 RXD Receive Data 5 nPGM Program (and LED)
nxpprog to download
a .hex file into the microcontroller. I depress the
[Reset] (but leave the program button unchanged.)
Lastly, there is an LED connected to the nPROG signal.
My blinky program can turn drive the nPROG signal on
and off to cause the LED to blink. It means that I
no longer feel obligated to put an LED on all of my
boards.
So the quest arises, how should these microcontrollers be programmed. Obviously, they can be programmed via either the serial boot loader or the JTAG interface. Frankly, the serial boot loader seems to load programs in faster than the JTAG interface. I seem to be getting about 4K/second with the serial boot loader and 2.5K/second for the JTAG.
When I am debugging a PCB, I am perfectly happy to solder a JTAG connector to the edge of the board. For mass product, something faster is required. Currently, I am leaning towards the connector below:
http://tag-connect.com/The TC2030-IDC-NL looks like it would be pretty reasonable for doing serial programming. What is nice is that no additional connector needs to be installed. The amount of board real estate require appears to be quite reasonable. Since there are 6 pins available, I am thinking that the sixth pin should be hooked up to a voltage supply so that both power and programming can be done using a single connector.
The question arises of whether I should have a connector that merges both JTAG programming/debugging and serial programming?
Many of the newer JTAG dongles out there are using the FT2232 chip that has two serial channels on one chip. One channel is put into MSSP (Master Synchronous Serial Port) mode for the JTAG and the other is a standard serial port. The serial port signals are typically exported on a DB9 with RS232 voltage levels.
The serial port can be used for both serial programming and ad hoc debugging. For ad hoc debugging, a little command line interpreter can be used to issue commands. In addition, trace information can be output to the to the serial port for subsequent logging and data visualization.
Given that the only connector that has RTCK is the ARM-20, some sort of rewire PCB is needed to get down to a smaller connector. I am leaning towards a 14-pin connector that can be soldered onto the edge of a board. This would include the "ARM-10" pin-outs and an additional 4 pins for serial download:
14-Pin AVR JTAG Connector Pin Use Use Pin 1 (TCK) Test Clock (GND) Ground 2 3 (TDO) Test Data Output (VREF) Voltage Reference 4 5 (TMS) Test Mode Select (nSRST) System Reset (*) 6 7 (RTCK) Return Test Clock (nTRST) Test Reset (*) 8 9 (TDI) Test Data Input (GND) Ground 10 11 (TXD)Transmit Data (VSUPPLY) Voltage Supply 12 13 (RXD) Receive Data (nPROG) Program 14
In addition, there would be a chunk of board area set aside for TC2030 connector with the following pin-outs:
Pin Signal Description 1 GND Ground 2 TXD Transmit Data 3 nRESET System Reset 4 RXD Receive Data 5 nPGM Program (and LED) 6 VSUPPLY Voltage Supply
I have been struggleing with the connector issue. Rather than delete my previous thoughts, I decided to just add this new section.
The requirements that must be met are:
The ability to do in circuit serial programming without a connector is pushing me towards a "pogo" connector allows the board to be placed down and programmed. This requires that GND, TXD, RXD, VSUPPLY, nSRST, nPROG be on the bottom of the board and suitable for use with a "pogo" connector. An example is the Mil-Max 821-22-008-10-003101
Originally, the plan was that the JTAG/ICSP connector would look more like PCB edge connectors. The plan was to solder on a regular male header to the edge. The theory was that this would save some board real estate. In practice, not enough board real estate was save to make it worth the effort. Instead a standard 2 × 8 connector (2.54mm pitch) is used.
The first try at the connector looks as follows:
bold signals "wiggle" and it is desired that they be separated by a non "wiggle" signal line to lower cross talk issues:
16-Pin JTAG Connector Pin Use Use Pin 1 (GND1) Ground (RXD) Receive Data 2 3 (VREF) Voltage Reference (TXD) Transmit Data 4 5 (nTRST) Test Reset (GND2) Ground 6 7 (RTCK) Return Test Clock (nPROG) Program 8 9 (TCK) Test Clock (SWDCLK) (VSUPPLY) Voltage Supply 10 11 (TDO) Test Data Out (SWO) (nSRST) System Reset 12 13 (TDI) Test Data In (VPROG) Program Voltage 14 15 (TMS) Test Mode Select (SWDIO) (unused) 16
The second try:
16-Pin JTAG Connector Pin Use Use Pin 16 (unused) (TMS) Test Mode Select (SWDIO) 15 14 (nPROG) Program (TDI) Test Data In 13 12 (nSRST) System Reset (TDO) Test Data Out (SWO) 11 10 (VUNREG) Unregulated Voltage Supply (TCK) Test Clock (SWDCLK) 9 8 (VREF) Voltage Reference (RTCK) Return Test Clock 7 6 (GND2) Ground (GND1) Ground 5 4 (TXD) Transmit Data (nTRST) Test Reset 3 2 (RXD) Receive Data (unused) 1
The purpose of VUNREG (unregulated voltage supply) pin is to provide some flexibility in powering devices.
There are three objects in this discussion -- 1) a module with an embedded microcontroller on it, 2) a serial programmer board with the 8-pin "pogo" connector that touches the bottom 8 pins of the JTAG/ICSP pads, and 3) an JTAG device (i.e. something that can talk to OpenOCD.) I will call these MODULE, SERIAL, and JTAG, respectively. MODULE can be connected to either SERIAL or JTAG, but not both at the same time.
The goal is to support three scenerios:
VUNREG is required to be between 6V and 30V.
MODULE has an on board regulator that takes VUNREG and regulates it down to a useful regulated voltage for further use. The regulator is typically a low drop out (LDO) voltage regulator.
All possible power sources connected to VUNREG must go through a current direction protection diode. The current direction protection diode does the following.
MODULE JTAG SERIAL Discussion no no no No power on VUNREG no no yes SERIAL supplies power no yes no JTAG supplies power no yes yes Simultaneous JTAG and SERIAL is not allowed yes no no MODULE supplies power yes no yes Higher voltage of MODULE or SERIAL supplies power yes yes no Higher voltage of MODULE or JTAG supply power yes yes yes Simultaneous JTAG and SERIAL is not allowed
The JTAG device needs to be able to get power from two or more sources. For the sake of discussion, we will assume that the JTAG device wants to be able to get power from:
The solution here is the same. VUNREG, USB5V and JACK all supply power to the JTAG voltage regulator through a protection diode. The source with the highest voltage will provide the power.
As a side note for Robus modules, it should be noted that VUNREG is tied to the LPWR pins of the bus connector. Each Robus module does not need a protection diode. However, the device that does connect to the LPWR wires does need to have the protection diode.
As a further side note for Robus modules, the shroud of the shrouded male header for the Robus connector is allowed to overlap the JTAG/ICSP connector holes. If it is necessary to access the JTAG/ICSP pins, the shroud can be pulled off and still be quite serviceable.
I found the following scripts for cross compiling OpenOCD from Linux to Windows using mingw:
https://github.com/caspencer/openocd-mingw32-build-scriptsNaturally I could not leave the scripts alone and munged them together to form my own script:
http://gramlich.net/projects/openocd/cross.shThis script download libusb, libftdi, and openocd and compiles them all with an embedded ARM cross compiler. The resulting
openocd appears to execute
just fine on one my ARM based Linux boxes.
As a side note, ARM based Linux box (a rooted version of the Iomega iConnect) does not have enough power to run my flyswatter. I needed to add a power USB hub to make if work.
I am starting to research wireless access points. It is important that I be able to connect to specific ports OpenOCD ports to support GDB and such. Some random links below:
http://www.dd-wrt.com/wiki/index.php/Wireless_Access_Point
http://wireless.wikia.com/wiki/Wi-Fi_How_To#Use_a_wireless_router_as_a_wireless_access_point
After reading the specification sheet for the FTDI FT2232H chip:
http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT2232H.pdfit looks like making a PCB for a JTAG dongle is quite easy. It looks like it takes the following parts:
In addition, there is a program provided by FTDI that is used to load up the serial EEPROM to configure it for MSSP mode, provide a serial number etc. The amount of code required to add a new debug adapter into OpenOCD looks quite nominal.
http://www.freertos.org/index.html?http://www.freertos.org/portLM3Sxxxx_Eclipse.html
http://stackoverflow.com/questions/3539970/configuring-gcc-with-freertos-and-openocd
The following issues need to be worked on: