用于Flash和Ram调试的STM32 GDB/OpenOCD命令和初始化

use*_*605 13 eclipse debugging gdb stm32 openocd

我正在寻找有关正确的GDB/OpenOCD初始化和运行命令(外部工具)的帮助,以便在Eclipse中用于flash和ram调试,以及需要合并到flash文件的make文件中的正确修改或添加内容为这个mcu建造,如果这当然重要.

mcu:STM32F103VET6

我正在使用带有Zylin嵌入式CDT的Eclipse Helios,Yagarto Tools和Bins,OpenOCD .4,以及一个Olimex ARM-USB-OCD Jtag适配器.

我已经配置了ARM-USB-OCD并将其作为外部工具添加到Eclipse中.为了初始化OpenOCD,我在Eclipse中使用了以下命令.电路板配置文件引用stm32 mcu:

"openocd -f interface/olimex-arm-usb-ocd-h.cfg -f board/stm32f10x_128k_eval.cfg"

当我在Eclipse中运行它时,一切似乎都在工作(GDB接口,OpenOCD找到mcu等).我也可以telnet到OpenOCD并运行命令.所以,我被困在下一部分; 用于flash和ram调试的初始化和命令,以及擦除闪存.

我阅读了几个教程,并搜索了网络,但未能找到任何特定的处理器.我是新手,所以我可能不会认识到一个公平的产品.

JIMT

spa*_*e78 26

我正在使用相同的工具链来编程和调试STM32F107板.以下是我在此工具链下编程和调试STM32Fxxx芯片的观察结果.


初始起点

所以在这一点上你已经有了一个工作的OpenOCD到ARM-USB-OCD连接,所以你应该在那一端设置.现在的工作是让Eclipse/Zylin/Yagarto GDB组合通过OpenOCD/Olimex连接正确地与STM32Fxxx通信.要记住的一件事是要发出的所有OpenOCD命令都是运行模式命令.用于调用OpenOCD服务器的配置脚本和命令行选项是配置模式命令.发出init命令后,服务器进入运行模式,打开接下来需要的命令集.你可能已经在其他地方完成了它,但当我调用OpenOCD服务器时,我会使用'-c"init"'选项:

openocd -f /path to scripts/olimex-arm-usb-ocd-h.cfg -f /path to targets/stm32f107.cfg -c "init"
Run Code Online (Sandbox Code Playgroud)

我接下来发出的以下命令由Eclipse Debug Configurations对话框完成.在Zylin Embedded debug(Native)部分下,我创建了一个新配置,为它命名,Project(可选),以及我要编程的二进制文件的绝对路径.在Debugger选项卡下,我将调试器设置为Embedded GDB,指向Yagarto GDB二进制路径,设置GDB命令文件,将GDB命令设置为Standard,将协议设置为mi.


命令选项卡 - 将GDB连接到OpenOCD

因此,下一个选项卡是命令选项卡,这就是问题的关键所在.初始化运行有两个空格.不确定区别是什么,除了猜测它们发生在GDB调用之前和之后.无论哪种方式,我都没有发现我的命令运行方式有所不同.

但无论如何,按照我在网上找到的例子,我用以下命令填充了Initialize框:

set remote hardware-breakpoint limit 6
set remote hardware-watchoint-limit 4
target remote localhost:3333
monitor halt
monitor poll
Run Code Online (Sandbox Code Playgroud)

前两行告诉GDB你有多少个断点和观察点.打开OCD手册第20.3节说GDB无法查询该信息,所以我自己说.下一行命令GDB通过端口3333连接到本地主机上的远程目标.最后一行是一个监视器命令,它告诉GDB将命令传递给目标而不自行采取任何操作.在这种情况下,目标是OpenOCD,我给它命令停止.之后我告诉OpenOCD切换到异步操作模式.由于以下某些操作需要一段时间,因此不要使用OpenOCD块并等待每个操作.

旁注#1:如果您对GDB或OpenOCD的状态有疑问,那么在调用此调试配置后,您可以使用Eclipse调试控制台向GDB或OpenOCD发送命令(通过GDB监视器命令).


命令选项卡 - 设置用户Flash

接下来是我在Run命令部分中给出的命令:

monitor flash probe 0
monitor flash protect 0 0 127 off
monitor reset halt
monitor stm32x mass_erase 0
monitor flash write_image STM3210CTest/test_rom.elf
monitor flash protect 0 0 127 on
disconnect
target remote localhost:3333
monitor soft_reset_halt
Run Code Online (Sandbox Code Playgroud)

将在以下部分中解释......

设置对用户闪存的访问权限

首先,我发出一个OpenOCD查询,看看它是否能找到闪存模块并报告正确的地址.如果它响应它发现闪存在地址0x08000000然后我们很好.最后的0指定获取有关闪存库0的信息.

附注2: STM32Fxxx特定于器件的数据手册在第4节中有一个存储器映射.在使用芯片时,非常有用.此外,当所有内容都作为内存地址访问时,您将在一点编程时间之后了解这种布局,就像手背一样!

因此,在确认闪存已正确配置后,我们调用该命令关闭对闪存库的写保护.PM0075描述了有关编程闪存的所有信息.您需要了解的此命令是闪存库,起始扇区,结束扇区,以及是否启用写保护.闪存库在传递给OpenOCD的配置文件中定义,并由上一个命令确认.由于我想要禁用整个闪存空间的保护,我指定扇区0到127. PM0075解释了我是如何得到这个数字的,因为它指的是我的(和你的)设备如何将闪存组织成2KB页面.我的设备有256KB的闪存,这意味着我有128页.您的设备有512KB的闪存,因此您将拥有256页.要确认已正确禁用了器件的写保护,可以使用OpenOCD命令检查地址0x40022020处的FLASH_WRPR寄存器:

monitor mdw 0x40022020
Run Code Online (Sandbox Code Playgroud)

它打印的结果字将是0xffffffff,这意味着所有页面都禁用了写保护.0x00000000表示所有页面都启用了写保护.

旁注#3:关于内存命令的主题,我把我的芯片打了两次,因为我在从地址0x1ffff800开始的块中弄乱了选项字节.我第一次在闪存上设置读取保护(如果你这样做很难弄清楚你在做什么),第二次我设置了硬件看门狗,这使得我之后无法做任何事情,因为监视器一直在关闭!通过使用OpenOCD内存访问命令修复它.这个故事的寓意是:能力越大,责任越大....或者另一种观点是,如果我用脚射击自己,我仍然可以通过JTAG解决问题.

旁注#4:如果尝试写入受保护的闪存,就会发生一件事:FLASH_SR:WRPRTERR位将被置位.OpenOCD将报告更加用户友好的错误消息.

擦除Flash

因此,在禁用写保护后,我们需要擦除您要编程的内存.我做了一个擦除所有内容的批量擦除,你也可以选择按扇区或地址擦除(我认为).无论哪种方式,您都需要在编程之前先擦除,因为硬件会在允许写入之前先检查擦除.如果在编程期间FLASH_SR:PGERR位(0x4002200c)被设置,那么您知道还没有擦除那块存储器.

附注#5:在闪存中擦除一点意味着将其设置为1.

编写二进制文件

擦除后的下两行将二进制映像写入闪存并重新启用写保护.没有更多的说法PM0075没有涵盖.基本上,发出flash write_image时发生的任何错误都可能与未禁用闪存保护有关.它可能不是 OpenOCD,但如果你很好奇,你可以启用调试输出并按照它的作用.

GDB调试

所以最后在编程之后我将GDB与远程连接断开,然后将其重新连接到目标,执行软复位,现在我的GDB已准备好进行调试.这个最后一部分我昨晚刚想通了,因为我试图弄清楚为什么在编程之后,GDB在重置后不会在main()处正常停止.它继续进入杂草并炸毁.

我目前的想法以及我在OpenOCD和GDB手册中读到的内容是,首先,远程连接意味着在GDB和已经配置并运行的目标之间使用.好吧,我在运行之前使用GDB配置,所以我认为符号表或其他一些重要信息在编程期间搞砸了.OpenOCD手册说服务器在GDB连接时自动报告内存和符号,但是当芯片被编程时,所有这些信息可能都变得无效.断开连接并重新连接我认为刷新GDB需要正确调试的信息.这导致我创建另一个调试配置,这个只是连接并重置目标,因为我不一定需要每次我想使用GDB时编程芯片.


呼!完成!有点长,但这花了我3个周末才弄清楚,所以不是太糟糕我想...

最后的旁注:在我的调试期间,我发现OpenOCD调试输出对于我了解OpenOCD在幕后做了什么是非常宝贵的.要对STM32x芯片进行编程,您需要解锁闪存寄存器,翻转正确的位,并且一次只能写半个字.有一段时间我质疑OpenOCD是否正确地做了这个,但在查看了OpenOCD调试输出并将其与PM0075指令进行比较之后,我能够确认它确实遵循了执行每个操作的正确步骤.我还发现我正在复制OpenOCD已经在做的步骤,所以我能够删除没有帮助的指令!故事的道德:调试输出是你的朋友!

  • 很棒的答案!不幸的是,大多数OpenOCD教程只解释了如何安装它.顺便提一下,你引用了OpenOCD手册第20.3节,但它现在是21.3.对于不使用Eclipse的人来说,使用`gdb -ex"命令编写gdb命令很容易." (4认同)