JLink Flash and debug interface

The compiler can be integrated with a Segger JLink to provide Flash programming and debugging facilities. Instructions for downloading the required software will have been provided with your JLink. The Segger website is at http://www.segger.com. Make sure that the installed Segger shared library is at least v4.78e or v4.78.5.

These facilities are available for Windows, Mac OS X and Linux.

Installing Segger software

Windows

Download the latest Segger tools; you need at least v4.78e or v4.78.5. Place the file JLinkARM.dll in a directory in the search path. The directory containing the compiler is always in the search path.

Mac OS X

Download the latest Segger tools; you need at least v4.78e or v4.78.5. We need the shared library libjlinkarm.4.xx.y.dylib and the link libjlinkarm.4.dylib. Check that the following file exists:

  /Applications/Segger/JLink/libjlinkarm.dylib

If it is present, you are all done. If it does not exist, either the installation has failed or Segger have changed the rules. Note that this file is a symbolic link.

For the 64 bit compiler, put the shared libraries libjlinkarm.*.dylib in /usr/local/lib. If the cross-compiler cannot find the Segger library, make a symbolic link libjlinkarm.dylib to it in /usr/local/lib.

You will have to repeat this incantation whenever you update the Segger tools.

Linux

Download the latest Segger tools; you need at least v4.78e or v4.78.5. After installation or update, you should have a directory /opt/SEGGER/JLink containing the files libjlinkarm.so.4 and libjlinkarm.so.4.xx.y. Copy these to /usr/lib or a system directory which is searched for 32 bit libraries. For example:

  sudo  cp /opt/SEGGER/JLink/libjlinkarm.so.* /usr/lib/

You will have to repeat this incantation whenever you update the Segger tools.

Controlling the J-Link

JLink commands can be executed at any time, either in the control file or interactively (at the keyboard). However, the memory image and output files are not finalised until the word FINIS has been executed. Actions that must be performed after FINIS can be specified with AFTERWARDS, which saves the rest of the line as text to be interpreted at the end of FINIS. AFTERWARDS can be used several times, and each line is interpreted in order, first encountered being interpreted first. The example below sets up the JLink and then causes the code sections to be downloaded to Flash.


  jlink STM32F407ZG 0 Project.jlink \ device, speed, project file
  afterwards  download-sections   \ download image

The list of device names can be found in the file <jlink>\ETC\JFlash\MCU.csv supplied by Segger. The speed (0=automatic) and project file (Project.jlink) are defaults and rarely need to be changed.

Umbilical Forth

At the end of the control file, you can place something like:


...

jlink LPC1114/302 0 Project.jlink  \ device, speed, project file
useSWD                  \ use SWD rather than the default JTAG
PSUART0 set-sjl-link    \ select Umbilical link through J-Link

umbilical-forth

The word jlink sets the device (important), the speed (0=autodetect to maximum) and project file. By default, the J-Link operates in JTAG mode. For systems that require SWD operation useSWD selects SWD operation. We can fake a serial line for the Umbilical Forth link using set-sjl-link which takes the address of the four-byte data used for talking to the J-Link.

The file Cortex/Drivers/serPSUART.fth contains an example link driver for the target side. It's rather slow because of the USB connection to the J-Link, but it works.

If you have a system with a real serial port, you can still use it but you will have to replace the line

PSUART0 set-sjl-link    \ select Umbilical link through J-Link

with serial configuration lines such as

c" COM4:" console-speed serial
c" dtr=off rts=off" set-control

Initialisation and download

: JLINK         \ -- ; jlink <device> <speed> <projfile>
Set the JLink to use the given device, connection speed and the given project file. The list of devices can be found in the file <jlink>\ETC\JFlash\MCU.csv supplied by Segger. The connection speed is specified in kHz, where 0 specifies automatic speed detection, and 65535 specifies adaptive clocking. For example:

jlink STM32F407ZG 1000 Project.jlink

selects an STM32F407ZG device, 1000 kHz and the project file is Project.jlink in the compiler's working directory.

: speedJLink    \ kHhz --
Set the JLink speed in kHz. A value of zero selects automatic detection of JLink speed. A value of 65535 selects adaptive clocking. This word is useful when a CPU runs at a low speed after reset, e.g. at 32 kHz until the clock unit has been set up.

: useJTAG       \ --
The JLink connects to the target by JTAG. This is the default.

: useSWD        \ --
The JLink connects to the target by SWD.

: download-sections     \ --
After JLINK above has been used, download-sections is set to use the JLink device to program the target. Download-sections closes the JLink connection after programming.

: InitJLink     \ --
Initialise the J-Link connection.

: TermJLink     \ --
Terminate the J-Link connection.

: ProgramImage  \ taddr "<filename>" -- ; 0 ProgramImage File.bin
Program the file at the given target address.

: setImageFile  \ "<filename>" -- ; ImageFile <filename>
Set the predefined image file used by commands such as DownloadJLink below.

: setFlashStart \ taddr -- ; $0800:0000 setFlashStart
Set the predefined Flash start address used by commands such as DownloadJLink below.

: DownloadJLink \ --
Download the image file predefined by ImageFile to the target.

Debug and stepping

The word InitJLink must have been used before any of these words have been run.

: reg@          \ reg# -- x
Return the data in the saved register (0..15). The CPU must have been halted.

: reg!          \ x reg# --
Apply the data to the saved register (0..15).

: .regs         \ --
Display the working registers.

: stop          \ --
Stop the CPU.

: StopCPU       \ -- flag
Return true if the CPU was previously running. If the CPU is running, halt it.

: from          \ addr --
Set the target PC to the given address

: go            \ -- ; target carries on
Carry on execution of the target code.

: halt          \ --
Halt the CPU and dump registers.

: step          \ --
Execute a single step. There is no display.

: ss            \ --
Execute a single step and then display registers

: stepOver      \ --
If the current instruction is an unconditional BL instruction, step without display until it returns. Otherwise perform a single step. There is no display until the end.

: so            \ --
Step past the current instruction and then display registers.

: resetOnly     \ --
Reset the CPU with no checks.

: resetGo       \ --
Reset the target and set it to free run if the CPU had been halted.

: halted?       \ -- flag
Return true if the CPU is halted.

: running?      \ -- flag
Return true if the CPU is running.

Breakpoints

: setBP         \ addr -- bp# ; 0=failure
Set a breakpoint at the given address and return the breakpoint number.

: clrBP         \ bp# --
Clear the given breakpoint.

: clrAllBPs     \ --
Clear all breakpoints.

: waitHalt      \ --
Wait until the CPU halts, e.g. for a breakpoint, or until the <ESC> key is pressed.

Memory driver

Unless otherwise set, the cross compiler defaults to reading and writing target memory images in host memory. When a JLink or other hardware provides access to real target memory, the memory drivers can be selected to read and write the real target memory.

: all-via-jlink         \ --
Switch all memory sections to use the JLink to access target memory.

: all-via-default       \ --
Switch all memory sections to use the default memory image driver.

: [image        \ --
Start compiling or other actions that affect Flash. The compilation is performed to a memory image, and the result is written to Flash when image] is executed.

: image]        \ --
Finish compiling to memory, update the Flash and restore the memory drivers.

J-Link pseudo serial port

We use four bytes of target memory as a pretend UART (PSUART). This allows us to run debug communications and Umbilical Forth through the J-Link using no resources except the four bytes of RAM.

: set-sjl-link  \ addr --
Set the base address in the target at which the pseudo-UART four byte RAM block is located. The Umbilical Forth link drivers are also set to use the pseudo UART.

Interactive debugging

When you build a standalone target, you can still debug it using the J-Link. If the compiler directive INTERACTIVE has been used the compiler stays alive after executing FINIS. you can then use any of the commands as required. In order to permit access to any memory block in the target, we first modify our usual SECTION definitions in the control file.


 $0000:0000 $FFFF:FFFF udata section CATCHALL
 $0000:0000 $0000:7FFF cdata section LPC1114ufjl        \ code section
 $1000:0200 $1000:0FFF idata section PROGd      \ 4k IDATA
 $1000:1000 $1000:1FFF udata section PROGu      \ 4k UDATA

The CATCHALL section provides a valid memory area for every target memory address. It must be the first SECTION defined.

After FINIS, the compiler stays alive. You can now enter commands interactively at the keyboard.


all-via-jlink
Section PROGU switched
Section PROGD switched
Section K60TWR switched
Section CATCHALL switched ok
0 100 dump
0000:0000 00 FB 00 20 AD 05 00 00 ED 56 00 00 3D 57 00 00  .{. -...mV..=W..
0000:0010 8D 57 00 00 DD 57 00 00 2D 58 00 00 00 00 00 00  .W..]W..-X......
0000:0020 00 00 00 00 00 00 00 00 00 00 00 00 0F 02 00 00  ................
0000:0030 7D 58 00 00 00 00 00 00 13 02 00 00 EB 72 00 00  }X..........kr..
0000:0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000:0050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0000:0060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
 ok

The first command, ALL-VIA-JLINK, switches the memory drivers to use the J-Link. The second command dumps a block of memory. You can also use the debugging commands.


halt
R0  = 1FFF:0120 FFFF:FFFF 0000:37A9 0000:0000
R4  = 0000:0020 0000:001E 0000:0000 1FFF:00F4
R8  = 0000:0000 0000:0000 0000:0000 2000:FF00
R12 = 2000:FEF0 2000:FDE0 0000:5B3F 0000:6E18
XPSR = 2100:0000   MSP = 2000:FB00   PSP = 2000:FDE0
( 0000:6E14 7047 pG )        bx LR ok
ss
R0  = 1FFF:0120 FFFF:FFFF 0000:37A9 0000:0000
R4  = 0000:0020 0000:001E 0000:0000 1FFF:00F4
R8  = 0000:0000 0000:0000 0000:0000 2000:FF00
R12 = 2000:FEF0 2000:FDE0 0000:5B3F 0000:5B42
XPSR = 2100:0000   MSP = 2000:FB00   PSP = 2000:FDE0
( 0000:5B3E F5E7 ug )        b # $5B2C ok
ss
R0  = 1FFF:0120 FFFF:FFFF 0000:37A9 0000:0000
R4  = 0000:0020 0000:001E 0000:0000 1FFF:00F4
R8  = 0000:0000 0000:0000 0000:0000 2000:FF00
R12 = 2000:FEF0 2000:FDE0 0000:5B3F 0000:5B30
XPSR = 2100:0000   MSP = 2000:FB00   PSP = 2000:FDE0
( 0000:5B2C FCF794FC |w.| )  bl # $2458      [I ok
go  ok