Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set the stack pointer from gdb using JLink and a Cortex M4?

Tags:

embedded

gdb

arm

I am using a Segger J-Link Base with gdb on Linux to debug an Atmel SAM4S8C MCU. I have the following in a gdb command file that I specify with the --command argument when starting gdb:

target remote localhost:2331
monitor flash device SAM4S8C

I also specify my ELF file and load the program in the command file.

I have noticed that when I load my program (using load) the stack pointer is not getting set correctly. monitor reset also does not modify the stack pointer.

The J-Link User Guide says (for Cortex-M3 devices):

Moreover, the user have to correct the Stack pointer (R13) and the PC (R15) manually, after reset in order to debug the application.

What is the command to do this from gdb?

It's strange that I should have to do this manually. The stack pointer is the first entry of the reset vector. As I develop my code, the initial stack pointer changes (particularly switching between applications that have very different initial stack pointers, which is how I first noticed this).

Is there a way to get gdb to read this from the ELF file during load and automatically set it?

like image 508
Patrick Avatar asked Oct 28 '15 20:10

Patrick


Video Answer


2 Answers

Cortex-M were designed so that no assembly startup code would be required:
At startup, Cortex-M will automaticaly load sp and pc registers from the two first 32-bits words of flash.
In the case of my LPC1788, that means I need to load r13/sp with the content of 0x00000000, and r15/pc with the content of 0x00000004:

target remote localhost:2331
monitor interface SWD
monitor endian little
monitor speed auto
monitor reset
monitor halt
monitor flash device = LPC1788
monitor flash download = 1
monitor flash breakpoints = 1
file program.elf
load program.elf
break main
monitor reg r13 = (0x00000000)
monitor reg r15 = (0x00000004) 
continue
like image 173
Frant Avatar answered Oct 15 '22 09:10

Frant


I had this issue as my product used a bootloader located at the start of flash which I wanted to skip while debugging. Since the stack pointer value should be stored as the first word in your executable and the reset vector as the next, you need something like:

$sp = {int} program_start_address
$pc = {int} program_start_address + 4

e.g. for a binary that starts at 0x08001000

$sp = {int} 0x08001000
$pc = {int} 0x08001004
like image 39
bainorama Avatar answered Oct 15 '22 09:10

bainorama