我使用的是 Ubuntu 22.04,我有一个 STM32F4 Discovery 板,上面有一个 stf32f407vg MCU。 我正在尝试了解链接器脚本和启动文件。 我编写了一个小链接器(ld 文件)和启动文件,其中我仅声明闪存和内存的大小,然后声明堆栈的末尾,在启动文件中我只是使代码从闪存的开头开始(0x08000000)。或者至少这就是我正在尝试做的:)。我猜它们不是很正确,因为这是我第一次尝试这样的事情,但由于我不完全确定它们与问题的相关性,我将它们发布在下面:
启动文件:
// 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
和链接器文件:
/* 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 */
然后我编译并创建了一个 elf 文件,然后将其转换为二进制文件,我已使用 STM32 编程器将其烧录到板上。刷新后,我尝试使用 GDB 连接到开发板,当我在端口 4242 上收到连接超时时,据我了解,这应该是 STM 设备的默认端口 - 尽管对此我不确定:
输入“apropos word”来搜索与“word”相关的命令... 从 main.elf 读取符号... (在main.elf中没有找到调试符号) (gdb)目标扩展远程:4242 :4242: 连接超时。
请帮我解决这个问题。谢谢你。
GDB 通过 gdb 服务器连接到远程目标。因此,您必须在另一个终端上启动服务器才能连接到开发板。 您可以通过使用包管理器安装 openocd 来做到这一点。 安装后,您可以通过 openocd 启动服务器并向其传递接口(在本例中为 stlink)和目标 MCU(在本例中为 stm32f4x)的配置文件,如下所示:
openocd -f /usr/share/openocd/scripts/interface/stlink.cfg -f /usr/share/openocd/scripts/target/stm32f4x.cfg -c "init"
每个
-f
标志后面的参数分别是接口和目标MCU配置文件的路径,这些文件将与openocd一起安装在您的系统上。如果没有错误,运行上述命令将导致以下消息:
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
服务器已启动,端口 3333 将接受 gdb 连接。 现在,在另一个终端中,您将能够使用
gdb main.elf
连接到开发板,然后使用 target extended-remote :3333
命令。