skip to Main Content

I am using Ubuntu 22.04 and I have an STM32F4 Discovery board which has an stf32f407vg MCU on it.
I am trying to learn about linker scripts and starting files.
I have written a small linker(ld file) and start up file in which I am only declaring the size of flash and ram and then declaring the end of the stack and in the starter file I am just making the code start at beginning of flash(0x08000000). Or at least that’s what I am trying to do :). I am guessing they are not very correct since it’s my first try at something like this but since I am not entirely sure how relevant to the issue they are I will post them below:

The starter file:

    // These instructions define attributes of our chip and
// the assembly language we'll use:

    .syntax unified
    .cpu cortex-m4
    .thumb

// Import these symbols

    .extern   __ram_start__
    .extern   __ram_size__
    .extern   __ram_end__ 
    .extern   __stack_end__ 

// Global memory locations.
.global vtable
.global reset_handler


/*
 * The actual vector table.
 * Only the size of RAM and 'reset' handler are
 * included, for simplicity.
 */
 
 // Exception vector table--Common to all Cortex-M4

vtable:
    .word   __stack_end__
    .word   reset_handler
 
/*
 * The Reset handler. Called on reset.
*/

// Reset vector: In a real project this would do some RAM initialisations and then call main
    .thumb_func
reset_handler:
  // Set the stack pointer to the end of the stack.
  // The '__stack_end__' value is defined in our linker script.
  LDR  r0, =__stack_end__
  MOV  sp, r0

  // Set some dummy values. When we see these values
  // in our debugger, we'll know that our program
  // is loaded on the chip and working.
    LDR  r7, =0xDEADBEEF
    MOVS r0, #0
    main_loop:
    // Add 1 to register 'r0'.
    ADDS r0, r0, #1
    // Loop back.
    B    main_loop

And the linker file:

    /* Define the end of RAM and limit of stack memory */
/* (4KB SRAM on the STM32F031x6 line, 4096 = 0x1000) */
/* (RAM starts at address 0x20000000) */
/* _estack = 0x20001000;              */
/* In our code _estack = __stack_end__ */

MEMORY
{
    FLASH ( rx )      : ORIGIN = 0x08000000, LENGTH = 1024K
    RAM ( rxw )       : ORIGIN = 0x20000000, LENGTH = 128K
}


__ram_start__   = ORIGIN(RAM);
__ram_size__    = LENGTH(RAM);
__ram_end__     = __ram_start__ + __ram_size__;
__stack_end__   = __ram_end__;      /* Top of RAM */

I have then compiled and created an elf file and then converted it to a binary file which I have flashed on the board with STM32 Programmer. After flashing I tried to connect to the board with GDB and when I am getting connection timeout on port 4242 which as I understand should be the default port of STM devices – although on this I am not sure:

Type "apropos word" to search for commands related to "word"…
Reading symbols from main.elf…
(No debugging symbols found in main.elf)
(gdb) target extended-remote :4242
:4242: Connection timed out.

Please help me fix this issue. Thank you.

2

Answers


  1. GDB connects to remote target via a gdb-server. So you have to start a server on another terminal to be able to connect to the board.
    You can do that by installing openocd using your package manager.
    After installing it you can start a server via openocd and pass it the config files for the interface (in this case, stlink) and target MCU (int this case, stm32f4x), like this:

    openocd -f /usr/share/openocd/scripts/interface/stlink.cfg -f /usr/share/openocd/scripts/target/stm32f4x.cfg -c "init"
    

    The argument after each -f flag are the paths to the interface and target MCU config files respectively, which will be installed with openocd on your system. If there’s no errors, Running the above command will result in this messages:

    Open On-Chip Debugger 0.12.0
    Licensed under GNU GPL v2
    For bug reports, read
            http://openocd.org/doc/doxygen/bugs.html
    Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
    Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
    Info : clock speed 2000 kHz
    Info : STLINK V2J28S7 (API v2) VID:PID 0483:3748
    Info : Target voltage: 3.229005
    Info : [stm32f4x.cpu] Cortex-M4 r0p1 processor detected
    Info : [stm32f4x.cpu] target has 6 breakpoints, 4 watchpoints
    Info : starting gdb server for stm32f4x.cpu on 3333
    Info : Listening on port 3333 for gdb connections
    Info : Listening on port 6666 for tcl connections
    Info : Listening on port 4444 for telnet connections
    

    Severs are started and port 3333 will accept gdb connections.
    Now in another terminal you will be able to connect to the board using gdb main.elf and after that the target extended-remote :3333 command.

    Login or Signup to reply.
  2. No reason for this as you put the value on the vector table.

    LDR  r0, =__stack_end__
    MOV  sp, r0
    

    Can leave it you want but it adds nothing.

    Other than that you can tell from inspection that the result looks good.
    And it should execute fine. (should always inspect before loading into the mcu)

    Disassembly of section .text:
    
    08000000 <vtable>:
     8000000:   20020000    .word   0x20020000
     8000004:   08000009    .word   0x08000009
    
    08000008 <reset_handler>:
     8000008:   4f01        ldr r7, [pc, #4]    ; (8000010 <main_loop+0x4>)
     800000a:   2000        movs    r0, #0
    
    0800000c <main_loop>:
     800000c:   3001        adds    r0, #1
     800000e:   e7fd        b.n 800000c <main_loop>
     8000010:   deadbeef    .word   0xdeadbeef
    

    As answered though you use openocd, no need for gdb (debuggers cause as many problems as they solve), just telnet in (port 4444 in the answer shown) and you can type help but it should be halt, reg, resume or halt, regs, resume and if you do it a few times you should see r0 change.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search