See the top level README for information on where to find the schematic and programmers reference manual for the ARM processor on the raspberry pi. Also find information on how to load and run these programs. This example is an alternate bootloader basically. The ARM11 on the Raspberry Pi has a jtag based debug port for software development. Problem is the pins are not by default connected to the outside world so you cant for example reset the ARM as that would disconnect the jtag. (there is no SRST available) On the older rev1 boards, all but one signal is available on P1, unfortunately that other signal is on the S5 connector. I was able to solder a wire onto it. The rev2 boards, no soldering is required. I use jumper wires like these to get from my jtag board/device to the raspberry pi. http://www.sparkfun.com/products/9140 http://www.sparkfun.com/products/9385 The signal name, gpio pins, schematic name, connector pin and direction shown here. When looking into the holes of an arm 20 pin (female) jtag connector. There should be a key or bit of plastic almost two holes wide on one side. With that key pointed up, looking into the holes pin one is the top left corner. The arm jtag names on the left of this list start with pin 1 and go along that side of the connector in order. For ground use any one of the holes on the other side except the lower left, pin 2, that is not a ground. See this page as an example http://www.amontec.com/jtag_pinout.shtml rev1 raspberry pi boards (older boards) 1 ARM_VREF P1-1 2 ARM_TRST 22 GPIO_GEN3 P1-15 IN (22 ALT4) 3 ARM_TDI 4/26 GPIO_GCLK P1-7 IN ( 4 ALT5) 4 ARM_TMS 12/27 CAM_GPIO S5-11 OUT (27 ALT4) 5 ARM_TCK 13/25 GPIO_GEN6 P1-22 OUT (25 ALT4) 7 no connect 9 ARM_TDO 5/24 GPIO_GEN5 P1-18 OUT (24 ALT4) 4-20 ARM_GND P1-25 rev2 raspberry pi boards 1 ARM_VREF P1-1 2 ARM_TRST 22 GPIO_GEN3 P1-15 IN (22 ALT4) 3 ARM_TDI 4/26 GPIO_GCLK P1-7 IN ( 4 ALT5) 4 ARM_TMS 12/27 CAM_GPIO P1-13 OUT (27 ALT4) 5 ARM_TCK 13/25 GPIO_GEN6 P1-22 OUT (25 ALT4) 7 no connect 9 ARM_TDO 5/24 GPIO_GEN5 P1-18 OUT (24 ALT4) 4-20 ARM_GND P1-25 In parenthesis is the gpio pin used and the alternate function setting needed in the GPIO to connect it to the edge of the BCM chip. armjtag.c does just that, first it disables pull up or pull down on the gpio pins in question. Then it configures the alternate gpio functions for the pins in question. armjtag.c also configures gpio16 to drive the OK led and sets up a timer so that after configuring it blinks an led every 2 seconds. (copy armjtag.bin to kernel.img on the raspbery pi sd card and power the raspberry pi, verify it is right from the blinking led). fastblink.c is a test program that we will load using jtag, but first. To do all of this you are going to need a jtag debugger card/board/box. Not long ago that meant forking out a few grand, or making something with a parallel port (what is a parallel port you ask?). The one I use day in and day out is this one: http://www.amontec.com/jtagkey-tiny.shtml Problem is the shipping to the USA makes it not worth it unless you buy a bunch or have your boss buy it. If you are not in the USA then it might be cheaper shipping and definitely worth it... The jtagkey-tiny and a great number of other usb to jtag boards or microcontroller or fpga or cpld boards that include a usb jtag programmer on the board use some flavor of the FT2232 from Future Technology Devices International (FTDI). http://www.ftdichip.com. They have an array of usb to _blank_ devices. Usb to serial, usb to spi, i2c, jtag, parallel. Some devices have what they call Multi-Protocol Synchronous Serial Engine (MPSSE). What we care about here is it can be used to accelerate jtag beyond simple bit banging. Openocd has long had FT2232 support. Dont do what I did and confuse the FT232 with the FT2232, the FT232 does not have an MPSSE so you have to do just slow bit banging (which I talk about below). The FT2232 has two of these MPSSEs so you can use the part as two uarts or one uart one jtag, two jtags, one uart one spi, etc. They also have an FT4232, which has four uarts, but DOES NOT have four MPSSEs it still only has two MPSSEs. So you can have three uarts and one jtag and so on. Some boards have come and gone, unfortunately for example the signalyzer-lite is no longer available. You can get the flyswatter though which is yet another ft2232 board. http://www.tincantools.com/JTAG/Flyswatter.html And the jtag side is basically the same as the amontec. The flyswatter breaks out the uart, but we cant use it with the raspberry pi because it is at RS232 levels and if you were to connect it to the raspberry pi you will likely damage one board or the other or both. If you look around the openocd source code or schematics, etc the MPSSE deals with TCK, TMS, TDI, and TDO. TRST, SRST if there are supported by the other pins which are generic bit bang GPIO in this mode. The various board vendors naturally have other features beyond that. So I dont know how long these have been out but I was very happy to see that FTDI now has a couple of development boards one for the FT2232H and one for the FT4232H. These boards are under $30, and I have successfully used one with the Raspberry Pi, the bonus is you can use both the JTAG and Serial, one board and you get both. Even better the FT2232H/FT4232H supports jtag up to 30Mbps, where the prior incarnations of the FT2232 went to 6Mbps, so in theory we can compete speed-wise with the multi-thousand dollar boxes. Even at 6Mbps you can easily push the I/O or other speed limits in your target, so just because your jtag debugger device might go fast, doesnt mean you can always run that fast you either need to ask the (target) chip vendor or do some experiments. If you go to http://www.mouser.com And search for either of these part numbers 895-FT2232HMINIMOD 895-FT4232HMINIMOD You will find the FTDI development boards I am talking about. You can also get them from other distributors around the world. I assume anyone that sells FTDI parts might also sell FTDI boards. FT4232H Mini Module: Searching for this you get the datasheet for the development board. You dont necessarily NEED this as I will show you what to connect, but it is probably a good idea for your own education to look at it, it is a fairly short document. And may help to see the pinout which you will need to get right if you want to hook this up. http://www.ftdichip.com/Documents/DataSheets/Modules/DS_FT4232H_Mini_Module.pdf Googling for the FT4232H part you get its webpage http://www.ftdichip.com/Products/ICs/FT4232H.htm Where you can download the datasheet. The part we care about there is the pinout per function AD0 is TCK for JTAG, AD1 is TDI and so on. I spent some time fiddling with the FT_PROG utility thinking I was going to need to reconfigure something. I also messed with the ftdi_eeprom and eeprom tools from libftdi, to find that they work just fine on linux (not obvious at all on HOW to get them working) but we dont need them. When openocd fires up and grabs the A bus for jtag linux gives up on that being a uart. [1275978.391156] ftdi_sio ttyUSB1: FTDI USB Serial Device converter now disconnected from ttyUSB1 [1275978.391164] ftdi_sio 3-2:1.0: device disconnected They wisely used the same pin for uart and jtag output (D0) and the same pin for input (D1) so for the period of time that the FTDI part is thinking it is a uart, you wont hurt the jtag on your board (in theory, I should have already had a disclaimer that you are on your own, I wont be responsible for you melting down your board trying this stuff). This part is such that you can power the usb from the usb host side or the device side, and if you dont do anything the part isnt powered so as it says in the develompent board datasheet. Connect VBUS to VCC (CN3, pin 1 to CN3, pin 3) Likewise I connected CN2 pin 2 to CN2 pin 11 to Connect V3V3 to VIO, depending on the power needed you may need to connect more of the 3.3 volt pins to more of the VCCIO pins. I have been successful with just this one connection. Now when you plug in the mini module it will show up in lsusb and demesg will show the four uarts. Uart first I have already walked through other usb to uart connections. The P1 connector on the raspberry pi is the 2 rows of 13 pins along one side starting at a corner. The outer corner pin is numbered pin 2. The pin next to it as you move toward the micro-b usb connector that powers the raspberry pi, is pin 1. The pins along the outer edge of the board (other than pin 1) are the even numbered the row inside that are the odd numbered. So the outside starting at the corner heading toward the yellow rca (composite video) are pins 2,4,6,8,10, up to pin 26. The inner pins are 1,3,5,7,11 up to 25. This is a very common numbering scheme for dual row headers. You just have to figure out which one is pin one and you are set from there. If you look on the back of the board, the sd card side of the raspberry pi, the hole where the pin is soldered on is square, the rest are round. This is very common with these kind of through hole connectors to make the hole for pin 1 square and/or different than the others (just FYI). So the raspberry pi side of the uart/serial connection is 2 outer corner 4 6 GND 8 TX out 10 RX in The FT4232H Mini Module side, we want to use BD0 and BD1 which are pins CN2-18 and CN2-17. With the board oriented so the pins are pointing away from you and the mini-b usb connector on the top and pointed left. The top connector is CN3 and bottom CN2. The lower right pin is 25, the one to the left of that 23 and so on. You can count backward from there to find CN2-17 17 BD1 RXD in 19 21 23 25 lower right corner So P1-8 TX out on the rasberry pi connects to CN2-17 RXD on the FT4232H board. The pin next to that on the FT board (or above it if still holding it in that orientation is pin 18 18 BD0 TXD out 20 22 24 26 inside and next to lower right That connects to P1-10 on the raspberry pi. The lower left corner of the FT board is CN2-1 which we are using to power VCCIO. Above that toward the usb connector is CN2-2 a ground you can connect that to ground on the raspberry pi which is P1-6 If all you want is uart, there you go. To add jtag then: JTAG: (FT board left, Raspi right) TCK: CN2-7 P1-22 TDI: CN2-10 P1-7 TDO: CN2-9 P1-18 TMS: CN2-12 P1-13 UART: TXRX: CN2-18 P1-10 RXTX: CN2-17 P1-8 Ground: GND: CN2-2 P1-6 Raspi to Raspi: TRST: P1-1 P1-15 FTDI board to FTDI board: VCCIO: CN2-1 CN2-11 VCC: CN3-1 CN3-3 That is for a rev2 Raspberry Pi board, for a rev1 use S5-11 instead of P1-13 (some soldering or cable hacking required). Lastly when you connect your FT4232H board to your computer dmesg will show the four uarts (/dev/ttyUSBx) the first one on the list will go away when we take it over to do jtag, the second one listed will be the one you use for uart/serial communications to the raspberry pi. FT2232H Mini Module: The FT2232H Mini Module is very similar to the FT4232H above. The only difference relevant in our case is the location of the the UART pins, instead giving us the connections: JTAG: (FT board left, Raspi right) TCK: CN2-7 P1-22 TDI: CN2-10 P1-7 TDO: CN2-9 P1-18 TMS: CN2-12 P1-13 UART: TXRX: CN3-26 P1-10 RXTX: CN3-25 P1-8 Ground: GND: CN2-2 P1-6 Raspi to Raspi: TRST: P1-1 P1-15 FTDI board to FTDI board: VCCIO: CN2-1 CN2-11 VCC: CN3-1 CN3-3 Other alternatives, it doesnt take too much work to use the ftdi drivers to bit bang a board like this. http://www.sparkfun.com/products/718 Openocd has drivers for this you just make the (software) connectin between the bits that openocd wants you to drive or read and the gpio pins on the ftdi part. This is pretty slow but functions as a sub $20 jtag. For a little more money you can approach the more expensive solutions speed and perhaps features so long as you can declare your work educational. The educational version of the jlink is around $60, and it is pretty speedy. The non-educational version is I assume the same functionality if not the same, but more expensive. http://microcontrollershop.com/product_info.php?cPath=154_171&products_id=3647 The title of the page says ARM7/ARM9, the description includes ARM11, I have used it on an ARM11 (not the raspi yet). And the jlink works with openocd and is fast with openocd. You can also use their proprietary software. The software you want is http://openocd.sourceforge.net/ Now, I normally download the source, and build specifically with ftdi drivers enabled. And this is on linux. You might have to do it that way, I want to remember that you may have to pick some things at compile time. Try it out see what happens, maybe one size fits all, maybe on windows it is different than linux. Openocd (sources) come with a number of configuration files, just like my boot code and linker script I like to carry my openocd configs with the project. I have provided the jtag debugger files for the ones mentioned and then a file for the ARM itself. If you are running with the amontec you would run: openocd -f amontec.cfg -f raspi.cfg and should see something like this: Open On-Chip Debugger 0.5.0 (2011-09-20-21:55) 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: 400 jtag_ntrst_delay: 400 none separate raspi.arm Info : clock speed 1000 kHz Info : JTAG tap: raspi.arm tap/device found: 0x07b7617f (mfg: 0x0bf, part: 0x7b76, ver: 0x0) Info : found ARM1176 Info : raspi.arm: hardware has 6 breakpoints, 2 watchpoints This is a client server type of thing, the openocd program itself is the server. I recommend you are in the directory that contains the programs you want to run when you start openocd. The reason is the binaries are in the same path, you dont have to type a full path to a file. One client is gdb, which you are welcome to use, I have no use for it, can barely spell it. I prefer to telnet into openocd and use openocd's native commands (This is where the path thing comes in). With the openocd server running in one terminal/window I telnet to it in another: telnet localhost 4444 and see: Trying ::1... Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Open On-Chip Debugger > Be careful here, as the first command you type is halt and if you are root on a normal command line prompt (linux) and type halt it will halt your computer. So dont just type blindly, wait and watch. So the first thing you type is halt > halt target state: halted target halted in ARM state due to debug-request, current mode: Supervisor cpsr: 0x800001d3 pc: 0x0000007c your cpsr and pc might be different. Since the armjtag program already set up the led you can manually change the gpio pin now: > mww 0x2020001C 0x10000 and > mww 0x20200028 0x10000 The led should turn on or off depending on which command. Note these are the GPSET0 and GPCLR0 registers, the 0x10000 is bit 16 which is GPIO16 the led register. mww means memory write word. mdw is a memory read word > mdw 0 0x00000000: eaffffff Type the help command to see more fun stuff. Be careful, this is a powerful interface you dont want to just poke around at any memory address unless you know what it is... Also note that for example if you have left the instruction cache on on the ARM. The ARM cache has some instruction in it probably. The jtag debug port goes directly to memory not through the cache so if you halt the ARM and load another program and run it you can get a mixture of new isntructions and old instructions from the prior program which is probably going to result in a crash. When messing with the mmu or cache, just power cycle the board to try again. This directory also contains the fastblink example which is just blinker03 basically. I only built the .elf not the .bin because with openocd I rarely use .bin files. If you use the .elf then openocd can read that file and put the programs in the proper place. For example if you wanted to run from 0x20000 instead of 0 and built your binary to run from that memory address just load the elf and start execution at that address. What the elf saves you most of the time is typing in an address which you already had in the linker script. So > halt > load_image fastblink.elf 216 bytes written at address 0x00000000 downloaded 216 bytes in 0.063038s (3.346 KiB/s) > resume 0 What I tend to do is have yet another terminal open. One for openocd server, one for the telnet client and one to re-build the binary (.elf) file. I type the above three commands (with the appropriate binary file name and resume with the starting address). Then I can quickly up, up, up, enter up, up, up, enter up, up, up, enter In the telnet window to re-load and re-run a new build of the program. If you ctrl-c in the openocd window it kills both openocd and the telnet session. If you power cycle the board without doing this the two windows freak out. I have had them work once the board is back up and jtag is available, but I prefer to stop openocd and start fresh anyway. There are other .cfg files in this directory for the different jtag interface boards I have used (signalizer-lite, jlink, ft4232h, amontec). Use the same command line above but replace the appropriate config file openocd -f amontec.cfg -f raspi.cfg replace amontec.cfg with one of the other files or make your own. Update: amontec is history their website is gone. But you can get j-link (or clone) boxes from asia on ebay for around $11, so far I have tried them with ARM JTAG and ARM SWD. Very pleased so far. YMMV. As of this writing the signalyer at least the $50 one is long gone that company still makes something but it is pricy. flyswatter? I think they are still out there. Bus pirate, still out there, I think I got a $18 one on ebay and I think it works fine for jtag as well, the serial port i didnt get figured out, some soldering required. (the j-link, no soldering required). And the FT2232H and 4232 mini modules should still be out there too, have to use a number of jumpers to get VDDIO and such powered.