首页 > 解决方案 > OpenOCD 不使用 STM32 Nucleo 板打开/监听任何端口

问题描述

所以我一直对学习嵌入式编程很感兴趣,刚刚拿到了我的 Nucleo F103RB(stm32) 板。我想避免使用 IDE 并使用开源工具在终端中工作。我一直在尝试遵循本教程:

https://cycling-touring.net/2018/12/flashing-and-debugging-stm32-microcontrollers-under-linux

但是当我打字时

openocd -f board/st_nucleo_f103rb.cfg

我只得到这个:

Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
none separate
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : clock speed 950 kHz
Info : STLINK v2 JTAG v29 API v2 SWIM v18 VID 0x0483 PID 0x374B
Info : using stlink api v2
Info : Target voltage: 3.260766
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints

它没有告诉我任何关于监听某些端口的信息,事实上,当在端口 3333 或 4444 上使用 telnet 时,我无法连接它,这是 OpenOCD 应该打开的默认端口。我一直在 OSX 和 Linux(PopOs!)虚拟机上尝试这个,我得到了相同的结果。我怎样才能让 OpenOCD “听”?

我知道这有点困惑,但我对此完全是菜鸟,有点迷茫。

标签: armembeddedstm32openocd

解决方案


现在我将从 0.9.0 开始,它与 ./bootstrap ./configure make 一样好用,你可能需要在其中添加/启用一些东西 ./configure --help

ST-Link Programmer                      yes (auto)
CMSIS-DAP Compliant Debugger            yes (auto)
SEGGER J-Link Programmer                yes (auto)

至少在您的情况下是stlink。

我会在以后的编辑中做 stlink

jlink.cfg

#
# SEGGER J-Link
#
# http://www.segger.com/jlink.html
#

interface jlink

transport select swd



# The serial number can be used to select a specific device in case more than
# one is connected to the host.
#
# Example: Select J-Link with serial number 123456789
#
# jlink serial 123456789

目标.cfg

# script for stm32f1x family

#
# stm32 devices support both JTAG and SWD transports.
#
#source [find target/swj-dp.tcl]
# ARM Debug Interface V5 (ADI_V5) utility
# ... Mostly for SWJ-DP (not SW-DP or JTAG-DP, since
# SW-DP and JTAG-DP targets don't need to switch based
# on which transport is active.
#
# declare a JTAG or SWD Debug Access Point (DAP)
# based on the transport in use with this session.
# You can't access JTAG ops when SWD is active, etc.

# params are currently what "jtag newtap" uses
# because OpenOCD internals are still strongly biased
# to JTAG ....  but for SWD, "irlen" etc are ignored,
# and the internals work differently

# for now, ignore non-JTAG and non-SWD transports
# (e.g. initial flash programming via SPI or UART)

# split out "chip" and "tag" so we can someday handle
# them more uniformly irlen too...)

if [catch {transport select}] {
  echo "Error: unable to select a session transport. Can't continue."
  shutdown
}

proc swj_newdap {chip tag args} {
 if [using_hla] {
     eval hla newtap $chip $tag $args
 } elseif [using_jtag] {
     eval jtag newtap $chip $tag $args
 } elseif [using_swd] {
     eval swd newdap $chip $tag $args
 }
}


#source [find mem_helper.tcl]
# Helper for common memory read/modify/write procedures

# mrw: "memory read word", returns value of $reg
proc mrw {reg} {
    set value ""
    mem2array value 32 $reg 1
    return $value(0)
}

add_usage_text mrw "address"
add_help_text mrw "Returns value of word in memory."

proc mrb {reg} {
    set value ""
    mem2array value 8 $reg 1
    return $value(0)
}

add_usage_text mrb "address"
add_help_text mrb "Returns value of byte in memory."

# mmw: "memory modify word", updates value of $reg
#       $reg <== ((value & ~$clearbits) | $setbits)
proc mmw {reg setbits clearbits} {
    set old [mrw $reg]
    set new [expr ($old & ~$clearbits) | $setbits]
    mww $reg $new
}

add_usage_text mmw "address setbits clearbits"
add_help_text mmw "Modify word in memory. new_val = (old_val & ~clearbits) | setbits;"



if { [info exists CHIPNAME] } {
   set _CHIPNAME $CHIPNAME
} else {
   set _CHIPNAME stm32f1x
}

set _ENDIAN little

# Work-area is a space in RAM used for flash programming
# By default use 4kB (as found on some STM32F100s)
if { [info exists WORKAREASIZE] } {
   set _WORKAREASIZE $WORKAREASIZE
} else {
   set _WORKAREASIZE 0x1000
}

#jtag scan chain
if { [info exists CPUTAPID] } {
   set _CPUTAPID $CPUTAPID
} else {
   if { [using_jtag] } {
      # See STM Document RM0008 Section 26.6.3
      set _CPUTAPID 0x3ba00477
   } {
      # this is the SW-DP tap id not the jtag tap id
      set _CPUTAPID 0x1ba01477
   }
}

swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID

if { [info exists BSTAPID] } {
   # FIXME this never gets used to override defaults...
   set _BSTAPID $BSTAPID
} else {
  # See STM Document RM0008
  # Section 29.6.2
  # Low density devices, Rev A
  set _BSTAPID1 0x06412041
  # Medium density devices, Rev A
  set _BSTAPID2 0x06410041
  # Medium density devices, Rev B and Rev Z
  set _BSTAPID3 0x16410041
  set _BSTAPID4 0x06420041
  # High density devices, Rev A
  set _BSTAPID5 0x06414041
  # Connectivity line devices, Rev A and Rev Z
  set _BSTAPID6 0x06418041
  # XL line devices, Rev A
  set _BSTAPID7 0x06430041
  # VL line devices, Rev A and Z In medium-density and high-density value line devices
  set _BSTAPID8 0x06420041
  # VL line devices, Rev A
  set _BSTAPID9 0x06428041
}

if {[using_jtag]} {
 swj_newdap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \
    -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \
    -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 \
    -expected-id $_BSTAPID6 -expected-id $_BSTAPID7 \
    -expected-id $_BSTAPID8 -expected-id $_BSTAPID9
}

set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME

$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0

# flash size will be probed
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME stm32f1x 0x08000000 0 0 0 $_TARGETNAME

# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz
adapter_khz 1000

adapter_nsrst_delay 100
if {[using_jtag]} {
 jtag_ntrst_delay 100
}

reset_config srst_nogate

if {![using_hla]} {
    # if srst is not fitted use SYSRESETREQ to
    # perform a soft reset
    cortex_m reset_config sysresetreq
}

$_TARGETNAME configure -event examine-end {
    # DBGMCU_CR |= DBG_WWDG_STOP | DBG_IWDG_STOP |
    #              DBG_STANDBY | DBG_STOP | DBG_SLEEP
    mmw 0xE0042004 0x00000307 0
}

$_TARGETNAME configure -event trace-config {
    # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync
    # change this value accordingly to configure trace pins
    # assignment
    mmw 0xE0042004 0x00000020 0
}

请注意,没有提及 telnet 或 4444,但它默认存在。

窗口 1

sudo openocd -f jlink.cfg -f target.cfg 
Open On-Chip Debugger 0.9.0 (2020-01-14-14:35)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : JLink SWD mode enabled
swd
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
none separate
cortex_m reset_config sysresetreq
Info : J-Link ARM-OB STM32 compiled Jun 30 2009 11:14:15
Info : J-Link caps 0x88ea5833
Info : J-Link hw version 70000
Info : J-Link hw type J-Link
Info : J-Link max mem block 15344
Info : J-Link configuration
Info : USB-Address: 0x0
Info : Kickstart power on JTAG-pin 19: 0x0
Info : Vref = 3.300 TCK = 1 TDI = 1 TDO = 1 TMS = 0 SRST = 1 TRST = 1
Info : J-Link JTAG Interface ready
Info : clock speed 1000 kHz
Info : SWD IDCODE 0x1ba01477
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints

窗口 2

sudo telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> 

然后窗口 1 说

Info : accepting 'telnet' connection on tcp/4444

窗口 2

> halt
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x41000000 pc: 0x080000d4 msp: 0x20003fe8
> mdw 0 20
0x00000000: 20004000 080000c1 080000c7 080000c7 080000c7 080000c7 080000c7 080000c7 
0x00000020: 080000c7 080000c7 080000c7 080000c7 080000c7 080000c7 080000c7 080000c7 
0x00000040: 080000c7 080000c7 080000c7 080000c7 
> 
> halt
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x41000000 pc: 0x080000d4 msp: 0x20003fe8
> mdw 0 20
0x00000000: 20004000 080000c1 080000c7 080000c7 080000c7 080000c7 080000c7 080000c7 
0x00000020: 080000c7 080000c7 080000c7 080000c7 080000c7 080000c7 080000c7 080000c7 
0x00000040: 080000c7 080000c7 080000c7 080000c7 
> flash write_image erase blinker.elf  
auto erase enabled
device id = 0x20036410
flash size = 64kbytes
wrote 1024 bytes from file blinker.elf in 0.111541s (8.965 KiB/s)
> reset
> 

并且LED在闪烁

遇到麻烦使用重置停止。

从这里替换 jlink.cfg 与您的主板匹配的 stlink 之一,您可以使用 lsusb 来判断

Bus 003 Device 023: ID 1366:0101 SEGGER J-Link PLUS
Bus 003 Device 024: ID 0483:374b STMicroelectronics ST-LINK/V2.1 (Nucleo-F103RB)

grep 374b *
stlink-v2-1.cfg:hla_vid_pid 0x0483 0x374b

整理了0.10.0的问题。

几乎按照页面说明构建...

sudo apt remove openocd
sudo apt build-dep openocd
git clone https://git.code.sf.net/p/openocd/code openocd-code
cd openocd-code
./bootstrap
./configure
make
sudo make install

(我没有安装,我不想破坏我的自定义构建)

jlink.cfg(适用于 0.10.0)

#
# SEGGER J-Link
#
# http://www.segger.com/jlink.html
#

interface jlink

transport select swd


# The serial number can be used to select a specific device in case more than
# one is connected to the host.
#
# Example: Select J-Link with serial number 123456789
#
# jlink serial 123456789

目标.cfg

# script for stm32f1x family

#
# stm32 devices support both JTAG and SWD transports.
#
#source [find target/swj-dp.tcl]

# ARM Debug Interface V5 (ADI_V5) utility
# ... Mostly for SWJ-DP (not SW-DP or JTAG-DP, since
# SW-DP and JTAG-DP targets don't need to switch based
# on which transport is active.
#
# declare a JTAG or SWD Debug Access Point (DAP)
# based on the transport in use with this session.
# You can't access JTAG ops when SWD is active, etc.

# params are currently what "jtag newtap" uses
# because OpenOCD internals are still strongly biased
# to JTAG ....  but for SWD, "irlen" etc are ignored,
# and the internals work differently

# for now, ignore non-JTAG and non-SWD transports
# (e.g. initial flash programming via SPI or UART)

# split out "chip" and "tag" so we can someday handle
# them more uniformly irlen too...)

if [catch {transport select}] {
  echo "Error: unable to select a session transport. Can't continue."
  shutdown
}

proc swj_newdap {chip tag args} {
 if [using_hla] {
     eval hla newtap $chip $tag $args
 } elseif [using_jtag] {
     eval jtag newtap $chip $tag $args
 } elseif [using_swd] {
     eval swd newdap $chip $tag $args
 }
}


#source [find mem_helper.tcl]

# Helper for common memory read/modify/write procedures

# mrw: "memory read word", returns value of $reg
proc mrw {reg} {
    set value ""
    mem2array value 32 $reg 1
    return $value(0)
}

add_usage_text mrw "address"
add_help_text mrw "Returns value of word in memory."

# mrh: "memory read halfword", returns value of $reg
proc mrh {reg} {
    set value ""
    mem2array value 16 $reg 1
    return $value(0)
}

add_usage_text mrh "address"
add_help_text mrh "Returns value of halfword in memory."

# mrb: "memory read byte", returns value of $reg
proc mrb {reg} {
    set value ""
    mem2array value 8 $reg 1
    return $value(0)
}

add_usage_text mrb "address"
add_help_text mrb "Returns value of byte in memory."

# mmw: "memory modify word", updates value of $reg
#       $reg <== ((value & ~$clearbits) | $setbits)
proc mmw {reg setbits clearbits} {
    set old [mrw $reg]
    set new [expr ($old & ~$clearbits) | $setbits]
    mww $reg $new
}

add_usage_text mmw "address setbits clearbits"
add_help_text mmw "Modify word in memory. new_val = (old_val & ~clearbits) | setbits;"

if { [info exists CHIPNAME] } {
   set _CHIPNAME $CHIPNAME
} else {
   set _CHIPNAME stm32f1x
}

set _ENDIAN little

# Work-area is a space in RAM used for flash programming
# By default use 4kB (as found on some STM32F100s)
if { [info exists WORKAREASIZE] } {
   set _WORKAREASIZE $WORKAREASIZE
} else {
   set _WORKAREASIZE 0x1000
}

# Allow overriding the Flash bank size
if { [info exists FLASH_SIZE] } {
    set _FLASH_SIZE $FLASH_SIZE
} else {
    # autodetect size
    set _FLASH_SIZE 0
}

#jtag scan chain
if { [info exists CPUTAPID] } {
   set _CPUTAPID $CPUTAPID
} else {
   if { [using_jtag] } {
      # See STM Document RM0008 Section 26.6.3
      set _CPUTAPID 0x3ba00477
   } {
      # this is the SW-DP tap id not the jtag tap id
      set _CPUTAPID 0x1ba01477
   }
}

swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu

if {[using_jtag]} {
   jtag newtap $_CHIPNAME bs -irlen 5
}

set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap

$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0

# flash size will be probed
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME

# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz
adapter speed 1000

adapter srst delay 100
if {[using_jtag]} {
 jtag_ntrst_delay 100
}

reset_config srst_nogate

if {![using_hla]} {
    # if srst is not fitted use SYSRESETREQ to
    # perform a soft reset
    cortex_m reset_config sysresetreq
}

$_TARGETNAME configure -event examine-end {
    # DBGMCU_CR |= DBG_WWDG_STOP | DBG_IWDG_STOP |
    #              DBG_STANDBY | DBG_STOP | DBG_SLEEP
    mmw 0xE0042004 0x00000307 0
}

$_TARGETNAME configure -event trace-config {
    # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync
    # change this value accordingly to configure trace pins
    # assignment
    mmw 0xE0042004 0x00000020 0
}

与之前相同的命令

sudo ../openocd-code/src/openocd -f jlink.cfg  -f stm32f1x.cfg 
Open On-Chip Debugger 0.10.0+dev-01180-g10b39c3-dirty (2020-04-13-21:29)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
swd
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : J-Link ARM-OB STM32 compiled Jun 30 2009 11:14:15
Info : Hardware version: 7.00
Info : VTarget = 3.300 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x1ba01477
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f1x.cpu on 3333
Info : Listening on port 3333 for gdb connections

它确实提到了在端口上侦听,另一个窗口也是如此,并且 LED 闪烁。

所以现在在大核卡上使用调试头。lsusb 节目

Bus 001 Device 016: ID 0483:374b STMicroelectronics ST-LINK/V2.1 (Nucleo-F103RB)

所以

cat stlink-v2-1.cfg 
echo "WARNING: interface/stlink-v2-1.cfg is deprecated, please switch to interface/stlink.cfg"
source [find interface/stlink.cfg]

所以

窗口 1

sudo ../openocd-code/src/openocd -f stlink.cfg  -f stm32f1x.cfg 
Open On-Chip Debugger 0.10.0+dev-01180-g10b39c3-dirty (2020-04-13-21:29)
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 : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 1000 kHz
Info : STLINK V2J28M18 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.247989
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f1x.cpu on 3333
Info : Listening on port 3333 for gdb connections

窗口 2

sudo telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> halt
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x080000ac msp: 0x20000ff0
> flash write_image erase blinker.elf
device id = 0x20036410
flash size = 64kbytes
auto erase enabled
wrote 1024 bytes from file blinker.elf in 0.100447s (9.955 KiB/s)

> reset
> halt
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000054 msp: 0x20000ff0
> 

LED 闪烁然后停止 LED 停止闪烁

通常,界面是最简单的部分,一旦您开始工作,您就可以将该配置换成另一个。我在这里遇到的 0.10.0 的问题是它需要

transport select swd

因为它对 jtag 进行了评论,并且如果您想要不同的界面,则使用传输选择,这就是诀窍。

这就是我在 0.9.0 jlink.cfg 文件中的内容。

在您的 Mac 上,根据年龄,您应该能够使用 mint 或 ubuntu 或其他任何东西的活动拇指驱动器(或 cdrom),并执行这些操作以查看它是 macos 还是其他东西。

apt-get install openocd (或从源代码构建)然后创建/复制文件,似乎你有 telnet 问题,所以即使你可以 telnet localhost 4444 并进入它也是一个胜利,停止,mdw 0 20,类似的事情,双赢。

我在评论中提到过,但是当我得到一个 nucleo 或发现板时,我做的第一件事是从 ST 获取固件更新程序,它是基于 Java 的,因此可以在 Windows、Linux、Mac 上运行,即使你找到的那个可能是旧的在线检查固件我不认为它带有在某个时候停止的版本。然后我更新核卡上的固件。我在早期的 Linux 核卡中遇到问题,即拇指驱动器只允许进行一次写入,然后您必须拔下并重新插入卡,以及固件修复的其他类似问题,这些天他们附带了一个工作版本,但作为一种习惯,我这样做。

尽管 st board 文档说我在非 st 芯片上使用了核头。但是我有一些 5 美元的紫色 jlink swd stm32 卡(在搜索中输入这三个词并增加您的几率,甚至通过亚马逊(不是来自亚洲)以及在亚洲的 eBay 上获得了一些),我没有当我使用它们时不必查找引脚排列,它们就可以工作。每次我都必须查找引脚排列的核。

因此,如果 0.9.0 或 0.10.0 在您的笔记本电脑上的 Linux 上使用 live usb(不是通过虚拟机!),那么它不是您的硬件,而是与软件有关。如果它在您计算机上的 Linux 上不起作用,那么您的 stlink 或其他可能存在硬件问题。

你的核板上有什么芯片?这可能会有所不同 真的是 F103xxxx 目标单片机吗?这就是我在这里演示的内容,等等...

sudo ../openocd-code/src/openocd -f stlink.cfg  -f stm32f1x.cfg 
Open On-Chip Debugger 0.10.0+dev-01180-g10b39c3-dirty (2020-04-13-21:29)
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 : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 1000 kHz
Info : STLINK V2J28M18 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.248358
Warn : UNEXPECTED idcode: 0x5ba02477
Error: expected 1 of 1: 0x1ba01477

这些文件用于 STM32F7xxx,这是我使用的调试器端...

grep -ri 5ba02477 *
target/renesas_s7g2.cfg:    set _CPU_SWD_TAPID 0x5ba02477
target/stm32f7x.cfg:      set _CPUTAPID 0x5ba02477

无论如何,有可能使用基本上未从 repo 修改的文件在 4444 上提供 telnet 访问,无论是否在连接期间打印出该事实。你需要做类似的事情

gdb_port 0
tcl_port 0

禁用对这些端口的访问。


推荐阅读