adding arm jtag example!
This commit is contained in:
39
armjtag/Makefile
Normal file
39
armjtag/Makefile
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
ARMGNU ?= arm-none-eabi
|
||||
|
||||
COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding
|
||||
|
||||
all : armjtag.hex armjtag.bin fastblink.elf
|
||||
|
||||
clean :
|
||||
rm -f *.o
|
||||
rm -f *.bin
|
||||
rm -f *.hex
|
||||
rm -f *.elf
|
||||
rm -f *.list
|
||||
rm -f *.img
|
||||
|
||||
vectors.o : vectors.s
|
||||
$(ARMGNU)-as vectors.s -o vectors.o
|
||||
|
||||
armjtag.o : armjtag.c
|
||||
$(ARMGNU)-gcc $(COPS) -c armjtag.c -o armjtag.o
|
||||
|
||||
armjtag.elf : memmap vectors.o armjtag.o
|
||||
$(ARMGNU)-ld vectors.o armjtag.o -T memmap -o armjtag.elf
|
||||
$(ARMGNU)-objdump -D armjtag.elf > armjtag.list
|
||||
|
||||
armjtag.bin : armjtag.elf
|
||||
$(ARMGNU)-objcopy armjtag.elf -O binary armjtag.bin
|
||||
|
||||
armjtag.hex : armjtag.elf
|
||||
$(ARMGNU)-objcopy armjtag.elf -O ihex armjtag.hex
|
||||
|
||||
|
||||
fastblink.o : fastblink.c
|
||||
$(ARMGNU)-gcc $(COPS) -c fastblink.c -o fastblink.o
|
||||
|
||||
fastblink.elf : memmap vectors.o fastblink.o
|
||||
$(ARMGNU)-ld vectors.o fastblink.o -T memmap -o fastblink.elf
|
||||
$(ARMGNU)-objdump -D fastblink.elf > fastblink.list
|
||||
|
||||
227
armjtag/README
Normal file
227
armjtag/README
Normal file
@@ -0,0 +1,227 @@
|
||||
|
||||
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)
|
||||
|
||||
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, had it
|
||||
been on P1 as well then you could use the same jumper wires I am using
|
||||
to get from P1 to the ARM jtag wiggler.
|
||||
|
||||
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
|
||||
|
||||
ARM_TRST 22 GPIO_GEN3 P1-15 IN (22 ALT4)
|
||||
ARM_TDO 5/24 GPIO_GEN5 P1-18 OUT (24 ALT4)
|
||||
ARM_TCK 13/25 GPIO_GEN6 P1-22 OUT (25 ALT4)
|
||||
ARM_TDI 4/26 GPIO_GCLK P1-7 IN ( 4 ALT5)
|
||||
ARM_TMS 12/27 CAM_GPIO S5-11 OUT (27 ALT4)
|
||||
|
||||
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...
|
||||
|
||||
Basically the same thing is:
|
||||
|
||||
http://microcontrollershop.com/product_info.php?cPath=154_171&products_id=3124
|
||||
|
||||
Which comes with a little ribbon cable, dont worry. This is the
|
||||
signalyzer-lite board.
|
||||
|
||||
There is little difference, basically they are ftdi usb to parallel parts
|
||||
with some signal conditioning on them. You could use one of these already
|
||||
purchased for usb.
|
||||
|
||||
http://www.sparkfun.com/products/718
|
||||
|
||||
If you forgo the signal conditioning and probably have to do a little
|
||||
work on openocd or some research. A very nice feature of the ftdi
|
||||
parallel/serial parts like this one is that you can, using the ftdi
|
||||
driver (linux) bit bang whatever you want. I have used the above board
|
||||
to build a spi flash programmer for example...Go with the signalyzer-lite
|
||||
or amontec if you can.
|
||||
|
||||
Now the signalyzer lite and amontec are bit banged, so they are slow(er),
|
||||
but they work. The multi thousand dollar solutions are very fast. Now
|
||||
what I found is if you are using it for non-commercial, personal, use.
|
||||
You can get a Jlink, which is not a multi-thousand dollar one, but is
|
||||
still a bit pricey for home/hobby use. You can get basicall a jlink at
|
||||
educational prices for $60
|
||||
|
||||
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.
|
||||
|
||||
Maybe if we all ask very nicely they will connect GPIO12 or 27 to
|
||||
the P1 connector and we wont have any soldering (well unless the
|
||||
final production version of the board is without P1 pins.
|
||||
|
||||
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.
|
||||
11
armjtag/amontec.cfg
Normal file
11
armjtag/amontec.cfg
Normal file
@@ -0,0 +1,11 @@
|
||||
#
|
||||
# Amontec JTAGkey
|
||||
#
|
||||
# http://www.amontec.com/jtagkey.shtml
|
||||
#
|
||||
|
||||
interface ft2232
|
||||
ft2232_device_desc "Amontec JTAGkey"
|
||||
ft2232_layout jtagkey
|
||||
ft2232_vid_pid 0x0403 0xcff8
|
||||
|
||||
98
armjtag/armjtag.c
Normal file
98
armjtag/armjtag.c
Normal file
@@ -0,0 +1,98 @@
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
extern void PUT32 ( unsigned int, unsigned int );
|
||||
extern unsigned int GET32 ( unsigned int );
|
||||
extern void dummy ( unsigned int );
|
||||
|
||||
#define ARM_TIMER_LOD 0x2000B400
|
||||
#define ARM_TIMER_VAL 0x2000B404
|
||||
#define ARM_TIMER_CTL 0x2000B408
|
||||
#define ARM_TIMER_DIV 0x2000B41C
|
||||
#define ARM_TIMER_CNT 0x2000B420
|
||||
|
||||
#define SYSTIMERCLO 0x20003004
|
||||
#define GPFSEL0 0x20200000
|
||||
#define GPFSEL1 0x20200004
|
||||
#define GPFSEL2 0x20200008
|
||||
#define GPSET0 0x2020001C
|
||||
#define GPCLR0 0x20200028
|
||||
#define GPPUD 0x20200094
|
||||
#define GPPUDCLK0 0x20200098
|
||||
|
||||
#define TIMEOUT 1000000
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
int notmain ( void )
|
||||
{
|
||||
unsigned int ra;
|
||||
unsigned int rb;
|
||||
|
||||
//for led
|
||||
|
||||
ra=GET32(GPFSEL1);
|
||||
ra&=~(7<<18); //gpio16 OK LED
|
||||
ra|=1<<18; //gpio16 output
|
||||
PUT32(GPFSEL1,ra);
|
||||
|
||||
//for jtag
|
||||
|
||||
//alt4 = 0b011 3
|
||||
//alt5 = 0b010 2
|
||||
|
||||
|
||||
PUT32(GPPUD,0);
|
||||
for(ra=0;ra<150;ra++) dummy(ra);
|
||||
PUT32(GPPUDCLK0,(1<<4)|(1<<22)|(1<<24)|(1<<25)|(1<<27));
|
||||
for(ra=0;ra<150;ra++) dummy(ra);
|
||||
PUT32(GPPUDCLK0,0);
|
||||
|
||||
ra=GET32(GPFSEL0);
|
||||
ra&=~(7<<12); //gpio4
|
||||
ra|=2<<12; //gpio4 alt5 ARM_TDI
|
||||
PUT32(GPFSEL0,ra);
|
||||
|
||||
ra=GET32(GPFSEL2);
|
||||
ra&=~(7<<6); //gpio22
|
||||
ra|=3<<6; //alt4 ARM_TRST
|
||||
ra&=~(7<<12); //gpio24
|
||||
ra|=3<<12; //alt4 ARM_TDO
|
||||
ra&=~(7<<15); //gpio25
|
||||
ra|=3<<15; //alt4 ARM_TCK
|
||||
ra&=~(7<<21); //gpio27
|
||||
ra|=3<<21; //alt4 ARM_TMS
|
||||
PUT32(GPFSEL2,ra);
|
||||
|
||||
//ARM_TRST 22 GPIO_GEN3 P1-15 IN (22 ALT4)
|
||||
//ARM_TDO 5/24 GPIO_GEN5 P1-18 OUT (24 ALT4)
|
||||
//ARM_TCK 13/25 GPIO_GEN6 P1-22 OUT (25 ALT4)
|
||||
//ARM_TDI 4/26 GPIO_GCLK P1-7 IN ( 4 ALT5)
|
||||
//ARM_TMS 12/27 CAM_GPIO S5-11 OUT (27 ALT4)
|
||||
|
||||
PUT32(ARM_TIMER_CTL,0x00F90000);
|
||||
PUT32(ARM_TIMER_CTL,0x00F90200);
|
||||
|
||||
rb=GET32(ARM_TIMER_CNT);
|
||||
while(1)
|
||||
{
|
||||
PUT32(GPSET0,1<<16);
|
||||
while(1)
|
||||
{
|
||||
ra=GET32(ARM_TIMER_CNT);
|
||||
if((ra-rb)>=TIMEOUT) break;
|
||||
}
|
||||
rb+=TIMEOUT;
|
||||
PUT32(GPCLR0,1<<16);
|
||||
while(1)
|
||||
{
|
||||
ra=GET32(ARM_TIMER_CNT);
|
||||
if((ra-rb)>=TIMEOUT) break;
|
||||
}
|
||||
rb+=TIMEOUT;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
62
armjtag/fastblink.c
Normal file
62
armjtag/fastblink.c
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
extern void PUT32 ( unsigned int, unsigned int );
|
||||
extern unsigned int GET32 ( unsigned int );
|
||||
extern void dummy ( unsigned int );
|
||||
|
||||
#define ARM_TIMER_LOD 0x2000B400
|
||||
#define ARM_TIMER_VAL 0x2000B404
|
||||
#define ARM_TIMER_CTL 0x2000B408
|
||||
#define ARM_TIMER_DIV 0x2000B41C
|
||||
#define ARM_TIMER_CNT 0x2000B420
|
||||
|
||||
#define SYSTIMERCLO 0x20003004
|
||||
#define GPFSEL0 0x20200000
|
||||
#define GPFSEL1 0x20200004
|
||||
#define GPFSEL2 0x20200008
|
||||
#define GPSET0 0x2020001C
|
||||
#define GPCLR0 0x20200028
|
||||
#define GPPUD 0x20200094
|
||||
#define GPPUDCLK0 0x20200098
|
||||
|
||||
#define TIMEOUT 250000
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
int notmain ( void )
|
||||
{
|
||||
unsigned int ra;
|
||||
unsigned int rb;
|
||||
|
||||
ra=GET32(GPFSEL1);
|
||||
ra&=~(7<<18); //gpio16 OK LED
|
||||
ra|=1<<18; //gpio16 output
|
||||
PUT32(GPFSEL1,ra);
|
||||
|
||||
PUT32(ARM_TIMER_CTL,0x00F90000);
|
||||
PUT32(ARM_TIMER_CTL,0x00F90200);
|
||||
|
||||
rb=GET32(ARM_TIMER_CNT);
|
||||
while(1)
|
||||
{
|
||||
PUT32(GPSET0,1<<16);
|
||||
while(1)
|
||||
{
|
||||
ra=GET32(ARM_TIMER_CNT);
|
||||
if((ra-rb)>=TIMEOUT) break;
|
||||
}
|
||||
rb+=TIMEOUT;
|
||||
PUT32(GPCLR0,1<<16);
|
||||
while(1)
|
||||
{
|
||||
ra=GET32(ARM_TIMER_CNT);
|
||||
if((ra-rb)>=TIMEOUT) break;
|
||||
}
|
||||
rb+=TIMEOUT;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------
|
||||
8
armjtag/jlink.cfg
Normal file
8
armjtag/jlink.cfg
Normal file
@@ -0,0 +1,8 @@
|
||||
#
|
||||
# Segger J-Link
|
||||
#
|
||||
# http://www.segger.com/jlink.html
|
||||
#
|
||||
|
||||
interface jlink
|
||||
|
||||
12
armjtag/memmap
Normal file
12
armjtag/memmap
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ram : ORIGIN = 0x00000000, LENGTH = 0x1000
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : { *(.text*) } > ram
|
||||
.bss : { *(.bss*) } > ram
|
||||
}
|
||||
|
||||
30
armjtag/raspi.cfg
Normal file
30
armjtag/raspi.cfg
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
# Broadcom 2835 on Raspberry Pi
|
||||
|
||||
telnet_port 4444
|
||||
#gdb_port 0
|
||||
#tcl_port 0
|
||||
|
||||
jtag_khz 1000
|
||||
|
||||
jtag_nsrst_delay 400
|
||||
jtag_ntrst_delay 400
|
||||
|
||||
if { [info exists CHIPNAME] } {
|
||||
set _CHIPNAME $CHIPNAME
|
||||
} else {
|
||||
set _CHIPNAME raspi
|
||||
}
|
||||
|
||||
reset_config none
|
||||
|
||||
if { [info exists CPU_TAPID ] } {
|
||||
set _CPU_TAPID $CPU_TAPID
|
||||
} else {
|
||||
set _CPU_TAPID 0x07b7617F
|
||||
}
|
||||
jtag newtap $_CHIPNAME arm -irlen 5 -expected-id $_CPU_TAPID
|
||||
|
||||
set _TARGETNAME $_CHIPNAME.arm
|
||||
target create $_TARGETNAME arm11 -chain-position $_TARGETNAME
|
||||
|
||||
11
armjtag/signalyzer-lite.cfg
Normal file
11
armjtag/signalyzer-lite.cfg
Normal file
@@ -0,0 +1,11 @@
|
||||
#
|
||||
# Xverve Signalyzer LITE (DT-USB-SLITE)
|
||||
#
|
||||
# http://www.signalyzer.com
|
||||
#
|
||||
|
||||
interface ft2232
|
||||
ft2232_device_desc "Signalyzer LITE"
|
||||
ft2232_layout signalyzer
|
||||
ft2232_vid_pid 0x0403 0xbca1
|
||||
|
||||
23
armjtag/vectors.s
Normal file
23
armjtag/vectors.s
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
b reset
|
||||
|
||||
reset:
|
||||
mov sp,#0x1000
|
||||
bl notmain
|
||||
hang: b hang
|
||||
|
||||
.globl PUT32
|
||||
PUT32:
|
||||
str r1,[r0]
|
||||
bx lr
|
||||
|
||||
.globl GET32
|
||||
GET32:
|
||||
ldr r0,[r0]
|
||||
bx lr
|
||||
|
||||
.globl dummy
|
||||
dummy:
|
||||
bx lr
|
||||
Reference in New Issue
Block a user