gpt4 book ai didi

gdb - 如何从终端使用 GDB(Gnu Debugger)和 OpenOCD 进行微 Controller 调试?

转载 作者:行者123 更新时间:2023-12-02 03:05:24 33 4
gpt4 key购买 nike

对 ARM 微 Controller 进行编程的标准(低成本)方法是使用 Eclipse,其中插入了一个复杂的工具链。 Eclipse 绝对有它的优点,但我想独立于这个 IDE。我想了解当我构建(编译 - 链接 - 闪存)我的软件以及运行调试 session 时幕后发生的事情。为了获得如此深入的理解,从命令行运行整个过程会很棒。

注意:我使用的是 64 位 Windows 10。但是这里解释的大部分内容也适用于 Linux 系统。请以管理员权限打开所有命令终端。这可以为您节省很多问题。

1. 构建软件

第一个“使命”完成了。我现在可以通过命令行将我的软件编译和链接成二进制 .bin.elf 图像。成功的关键是找出 Eclipse 将其生成文件放置在特定项目的位置。一旦你知道它们在哪里,你所要做的就是打开一个命令终端,然后输入 GNU make 命令。

enter image description here

您不再需要 Eclipse 了!特别是如果您可以阅读(并理解)makefile 并在您的项目推进时根据您的需要调整它。

请注意,在安装 SW4STM32(STM32 的系统工作台)后,我在以下文件夹中找到了 GNU 工具(编译器、链接器、make 实用程序、GDB 等):

C:\Ac6\SystemWorkbench\plugins\fr.ac6.mcu.externaltools.arm-none.win32_1.7.0.201602121829\tools\compiler\

接下来,我在硬盘上创建了一个新文件夹,并将所有这些 GNU 工具复制到其中:
C:\Apps\AC6GCC
|-> arm-none-eabi
|-> bin
'-> lib

我将这些条目添加到“环境路径变量”中:
 - C:\Apps\AC6GCC\bin
- C:\Apps\AC6GCC\lib\gcc\arm-none-eabi\5.2.1

欢呼吧,现在我在我的系统上启动并运行了所有的 GNU 工具!我将以下 build.bat 文件放在与 makefile 相同的文件夹中:
@echo off
echo.
echo."--------------------------------"
echo."- BUILD -"
echo."--------------------------------"
echo.

make -j8 -f makefile all

echo.

运行这个 bat 文件应该可以完成这项工作!如果一切顺利,您将得到一个 .bin 和一个 .elf 二进制文件作为编译结果。

2.刷入和调试固件

自然的后续步骤是将固件刷入芯片并开始调试 session 。在 Eclipse 中,只需“单击一个按钮”即可 - 至少如果 Eclipse 已为您的微 Controller 正确配置。但是幕后发生了什么?
我读过(部分)来自 Dominic Rath(OpenOCD 的开发者)的硕士论文。你可以在这里找到它: http://openocd.net/ 。这是我学到的:
  • 当您单击“调试”图标时,Eclipse 将启动 OpenOCD 软件。 Eclipse 还为 OpenOCD 提供了一些配置文件 - 这样 OpenOCD 就知道如何连接到您的微 Controller 。 “如何连接”不是一件小事。 OpenOCD 需要找到合适的 USB 驱动程序来连接到 JTAG 适配器(例如 STLink)。 JTAG 适配器及其 USB 驱动程序通常由您的芯片制造商(例如 STMicroelectronics)提供。 Eclipse 还将一个配置文件交给 OpenOCD,该文件描述了微 Controller 的规范。一旦 OpenOCD 知道所有这些事情,它就可以与目标设备建立可靠的 JTAG 连接。
  • OpenOCD 启动两台服务器。第一个是 TCP 端口 4444 上的 Telnet 服务器。它可以访问 OpenOCD CLI(命令行界面)。 Telnet 客户端可以连接 OpenOCD 并向其发送命令。这些命令可以是简单的“停止”、“运行”、“设置断点”……
  • 此类命令足以调试您的微 Controller ,但许多人已经熟悉 Gnu 调试器 (GDB)。这就是 OpenOCD 还在 TCP 端口 3333 上启动 GDB 服务器的原因。GDB 客户端可以连接到该端口,并开始调试微 Controller !
  • Gnu Debugger 是一个命令行软件。许多人更喜欢可视化界面。这正是 Eclipse 所做的。 Eclipse 会启动一个连接到 OpenOCD 的 GDB 客户端——但这对用户来说是隐藏的。 Eclipse 提供了一个图形界面,在幕后与 GDB 客户端交互。

  • 我做了一个图来解释所有这些事情:

    enter image description here

    >> 启动 OpenOCD

    我设法从命令行启动了 OpenOCD。我会解释如何。
  • 首先确保您的 STLink-V2 JTAG 编程器安装正确。您可以使用 STMicroelectronics 的“STLink 实用工具”测试安装。它有一个很好的 GUI,您只需单击连接按钮。
    enter image description here
  • 接下来从这个网站下载 OpenOCD 软件可执行文件: http://gnutoolchains.com/arm-eabi/openocd/ 。安装它,并将其放在硬盘上的一个文件夹中,例如“C:\Apps\”。
  • 打开命令终端,启动 OpenOCD。您需要为 OpenOCD 提供一些配置文件,以便它知道在哪里寻找您的微 Controller 。通常,您需要提供一个描述 JTAG 编程器的配置文件,以及一个定义您的微 Controller 的配置文件。使用命令行中的 -f 参数将这些文件传递给 OpenOCD。您还需要通过将 scripts 参数传递给 OpenOCD 访问 -s 文件夹。这是我使用命令行在我的计算机上启动 OpenOCD 的方式:
    > "C:\Apps\OpenOCD-0.9.0-Win32\bin\openocd" -f "C:\Apps\OpenOCD-0.9.0-Win32\share\openocd\scripts\interface\stlink-v2.cfg" -f "C:\Apps\OpenOCD-0.9.0-Win32\share\openocd\scripts\target\stm32f7x.cfg" -s "C:\Apps\OpenOCD-0.9.0-Win32\share\openocd\scripts"
  • 如果您正确启动 OpenOCD(使用正确的参数),它将启动并显示以下消息:
    Open On-Chip Debugger 0.9.0 (2015-08-15-12:41)
    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
    adapter speed: 2000 kHz
    adapter_nsrst_delay: 100
    srst_only separate srst_nogate srst_open_drain connect_deassert_srst
    Info : Unable to match requested speed 2000 kHz, using 1800 kHz
    Info : Unable to match requested speed 2000 kHz, using 1800 kHz
    Info : clock speed 1800 kHz
    Info : STLINK v2 JTAG v24 API v2 SWIM v4 VID 0x0483 PID 0x3748
    Info : using stlink api v2
    Info : Target voltage: 3.231496
    Info : stm32f7x.cpu: hardware has 8 breakpoints, 4 watchpoints
    Info : accepting 'gdb' connection on tcp/3333
    Info : flash size probed value 1024
  • 请注意,您的终端窗口现在已被阻止。您不能再键入命令。但这是正常的。 OpenOCD 在后台运行,它会阻止终端。现在您有两个选项可以与 OpenOCD 交互:在另一个终端中启动 Telnet session ,然后登录到 TCP 端口 localhost:4444 ,这样您就可以向 OpenOCD 发出命令并接收反馈。或者您启动 GDB 客户端 session ,并将其连接到 TCP 端口 localhost:3333

  • >> 启动 Telnet session 以与 OpenOCD 交互

    这是您启动 Telnet session 以与正在运行的 OpenOCD 程序交互的方式:
    > dism /online /Enable-Feature /FeatureName:TelnetClient

    > telnet 127.0.0.1 4444

    如果运行良好,您将在终端上收到以下消息:
    Open On-Chip Debugger
    > ..

    您已准备好向 OpenOCD 发送命令!但我现在将切换到 GDB session ,因为这是与 OpenOCD 交互的最方便的方式。

    >> 启动 GDB 客户端 session 以与 OpenOCD 交互

    打开另一个终端窗口,然后键入以下命令:
    > "C:\Apps\AC6GCC\bin\arm-none-eabi-gdb.exe"

    此命令只是启动 arm-none-eabi-gdb.exe GDB 客户端。如果一切顺利,GDB 启动时会显示以下消息:
        GNU gdb (GNU Tools for ARM Embedded Processors) 7.10.1.20151217-cvs
    Copyright (C) 2015 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law. Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "--host=i686-w64-mingw32 --target=arm-none-eabi".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word".
    (gdb)..

    现在将此 GDB 客户端连接到 OpenOCD 中的 GDB 服务器:
        (gdb) target remote localhost:3333

    现在您已连接到 OpenOCD!很高兴知道:如果您想使用 native OpenOCD 命令(就像您在 Telnet session 中所做的那样),只需在命令前加上关键字 monitor 。这样 OpenOCD 内的 GDB 服务器不会自己处理命令,而是将其传递给 native OpenOCD 守护进程。

    所以,现在是时候重置芯片,删除它并停止它:
        (gdb) monitor reset halt
    target state: halted
    target halted due to debug-request, current mode: Thread
    xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
    (gdb) monitor halt

    (gdb) monitor flash erase_address 0x08000000 0x00100000
    erased address 0x08000000 (length 1048576) in 8.899024s (115.069 KiB/s)
    (gdb) monitor reset halt
    target state: halted
    target halted due to debug-request, current mode: Thread
    xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
    (gdb) monitor halt

    该芯片现在已准备好接受我们的一些指令。首先我们会告诉芯片它的闪存部分 0 到 7(即我 1Mb 芯片中的所有闪存部分)不应受到保护:
        (gdb) monitor flash protect 0 0 7 off

    (gdb) monitor flash info 0
    #0 : stm32f7x at 0x08000000, size 0x00100000, buswidth 0, chipwidth 0
    # 0: 0x00000000 (0x8000 32kB) not protected
    # 1: 0x00008000 (0x8000 32kB) not protected
    # 2: 0x00010000 (0x8000 32kB) not protected
    # 3: 0x00018000 (0x8000 32kB) not protected
    # 4: 0x00020000 (0x20000 128kB) not protected
    # 5: 0x00040000 (0x40000 256kB) not protected
    # 6: 0x00080000 (0x40000 256kB) not protected
    # 7: 0x000c0000 (0x40000 256kB) not protected

    接下来我再次停止芯片。只是要确定..
        (gdb) monitor halt

    最后我将二进制 .elf 文件交给 GDB:
        (gdb) file C:\\..\\myProgram.elf
    A program is being debugged already.
    Are you sure you want to change the file? (y or n) y
    Reading symbols from C:\..\myProgram.elf ...done.

    现在是关键时刻。我要求 GDB 将这个二进制文件加载到芯片中。手指交叉:
        (gdb) load
    Loading section .isr_vector, size 0x1c8 lma 0x8000000
    Loading section .text, size 0x39e0 lma 0x80001c8
    Loading section .rodata, size 0x34 lma 0x8003ba8
    Loading section .init_array, size 0x4 lma 0x8003bdc
    Loading section .fini_array, size 0x4 lma 0x8003be0
    Loading section .data, size 0x38 lma 0x8003be4
    Error finishing flash operation

    可惜没有成功。我在 OpenOCD 中收到以下消息:
        Error: error waiting for target flash write algorithm
    Error: error writing to flash at address 0x08000000 at offset 0x00000000

    编辑:硬件问题已修复。

    显然这是一个硬件问题。我从没想过我的芯片会有缺陷,因为使用 STLink Utility 工具将二进制文件加载到芯片上没有问题。只有 OpenOCD 提示并给出错误。所以我很自然地责怪 OpenOCD——而不是芯片本身。有关更多详细信息,请参阅下面我的回答。

    编辑:另一种优雅的闪存芯片方式 - 使用 makefile!

    随着问题得到解决,我现在将专注于执行闪存和芯片调试的替代方法。我相信这对社区来说真的很有趣!

    您可能已经注意到,我使用 Windows cmd 命令来执行所有必要的步骤。这可以在批处理文件中自动化。但是有一种更优雅的方法:在 makefile 中自动化所有内容!
    先生/女士Othane 为他/她的 Cortex-M 建议了以下 makefile?芯片。我想 Cortex-M7 芯片的过程非常相似:
                #################################################
    # MAKEFILE FOR BUILDING THE BINARY #
    # AND EVEN FLASHING THE CHIP! #
    # Author: Othane #
    #################################################

    # setup compiler and flags for stm32f373 build
    SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST)))


    CROSS_COMPILE ?= arm-none-eabi-
    export CC = $(CROSS_COMPILE)gcc
    export AS = $(CROSS_COMPILE)gcc -x assembler-with-cpp
    export AR = $(CROSS_COMPILE)ar
    export LD = $(CROSS_COMPILE)ld
    export OD = $(CROSS_COMPILE)objdump
    export BIN = $(CROSS_COMPILE)objcopy -O ihex
    export SIZE = $(CROSS_COMPILE)size
    export GDB = $(CROSS_COMPILE)gdb


    MCU = cortex-m4
    FPU = -mfloat-abi=hard -mfpu=fpv4-sp-d16 -D__FPU_USED=1 -D__FPU_PRESENT=1 -DARM_MATH_CM4
    DEFS = -DUSE_STDPERIPH_DRIVER -DSTM32F37X -DRUN_FROM_FLASH=1 -DHSE_VALUE=8000000
    OPT ?= -O0
    MCFLAGS = -mthumb -mcpu=$(MCU) $(FPU)


    export ASFLAGS = $(MCFLAGS) $(OPT) -g -gdwarf-2 $(ADEFS)
    CPFLAGS += $(MCFLAGS) $(OPT) -gdwarf-2 -Wall -Wno-attributes -fverbose-asm
    CPFLAGS += -ffunction-sections -fdata-sections $(DEFS)
    export CPFLAGS
    export CFLAGS += $(CPFLAGS)


    export LDFLAGS = $(MCFLAGS) -nostartfiles -Wl,--cref,--gc-sections,--no-warn-mismatch $(LIBDIR)


    HINCDIR += ./STM32F37x_DSP_StdPeriph_Lib_V1.0.0/Libraries/CMSIS/Include/ \
    ./STM32F37x_DSP_StdPeriph_Lib_V1.0.0/Libraries/CMSIS/Device/ST/STM32F37x/Include/ \
    ./STM32F37x_DSP_StdPeriph_Lib_V1.0.0/Libraries/STM32F37x_StdPeriph_Driver/inc/ \
    ./
    export INCDIR = $(patsubst %,$(SELF_DIR)%,$(HINCDIR))




    # openocd variables and targets
    OPENOCD_PATH ?= /usr/local/share/openocd/
    export OPENOCD_BIN = openocd
    export OPENOCD_INTERFACE = $(OPENOCD_PATH)/scripts/interface/stlink-v2.cfg
    export OPENOCD_TARGET = $(OPENOCD_PATH)/scripts/target/stm32f3x_stlink.cfg


    OPENOCD_FLASH_CMDS = ''
    OPENOCD_FLASH_CMDS += -c 'reset halt'
    OPENOCD_FLASH_CMDS += -c 'sleep 10'
    OPENOCD_FLASH_CMDS += -c 'stm32f1x unlock 0'
    OPENOCD_FLASH_CMDS += -c 'flash write_image erase $(PRJ_FULL) 0 ihex'
    OPENOCD_FLASH_CMDS += -c shutdown
    export OPENOCD_FLASH_CMDS


    OPENOCD_ERASE_CMDS = ''
    OPENOCD_ERASE_CMDS += -c 'reset halt'
    OPENOCD_ERASE_CMDS += -c 'sleep 10'
    OPENOCD_ERASE_CMDS += -c 'sleep 10'
    OPENOCD_ERASE_CMDS += -c 'stm32f1x mass_erase 0'
    OPENOCD_ERASE_CMDS += -c shutdown
    export OPENOCD_ERASE_CMDS


    OPENOCD_RUN_CMDS = ''
    OPENOCD_RUN_CMDS += -c 'reset halt'
    OPENOCD_RUN_CMDS += -c 'sleep 10'
    OPENOCD_RUN_CMDS += -c 'reset run'
    OPENOCD_RUN_CMDS += -c 'sleep 10'
    OPENOCD_RUN_CMDS += -c shutdown
    export OPENOCD_RUN_CMDS


    OPENOCD_DEBUG_CMDS = ''
    OPENOCD_DEBUG_CMDS += -c 'halt'
    OPENOCD_DEBUG_CMDS += -c 'sleep 10'


    .flash:
    $(OPENOCD_BIN) -f $(OPENOCD_INTERFACE) -f $(OPENOCD_TARGET) -c init $(OPENOCD_FLASH_CMDS)


    .erase:
    $(OPENOCD_BIN) -f $(OPENOCD_INTERFACE) -f $(OPENOCD_TARGET) -c init $(OPENOCD_ERASE_CMDS)


    .run:
    $(OPENOCD_BIN) -f $(OPENOCD_INTERFACE) -f $(OPENOCD_TARGET) -c init $(OPENOCD_RUN_CMDS)


    .debug:
    $(OPENOCD_BIN) -f $(OPENOCD_INTERFACE) -f $(OPENOCD_TARGET) -c init $(OPENOCD_DEBUG_CMDS)

    亲爱的先生/女士Othane,你能解释一下如何在以下步骤中使用这个 makefile:
  • 从源代码
  • 构建二进制文件
  • 闪存芯片

  • 我知道一些关于 makefile 的基础知识,但是你的 makefile 真的很深入。您似乎使用了 GNU make 实用程序的一些功能。请给我们更多的解释,我会给你奖金;-)

    ------------------------------

    最佳答案

    我记得我在使用直接加载命令时也遇到了一些问题,所以我切换到“flash write_image erase my_project.hex 0 ihex”..显然我使用的是十六进制文件,但看起来 elf 文件应该可以使用,参见 http://openocd.org/doc/html/Flash-Commands.html 。 .. 这个命令的好处是它也只删除正在写入的闪存部分,这非常方便,你不需要删除

    在运行上述命令之前,您需要运行“stm32f1x unlock 0”以确保芯片已解锁并允许连接到闪存...请参阅有关此的数据表

    同样对于入门,命令“stm32f1x mass_erase 0”将完全快速地删除芯片,因此最好确保您以已知状态开始

    我知道其中一些命令说它们适用于 f1,但相信我,它们适用于 f4 系列

    顺便说一句,此文件包含我用来刷新 f4 的大部分命令,因此它可能是一个很好的引用 https://github.com/othane/mos/blob/master/hal/stm32f373/stm32f373.mk

    我希望这能让你解脱

    关于gdb - 如何从终端使用 GDB(Gnu Debugger)和 OpenOCD 进行微 Controller 调试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38033130/

    33 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com