目录

clionarm-cm3MSYS-mingw-jlink配置用于嵌入式开发

clion+arm-cm3+MSYS-mingw +jlink配置用于嵌入式开发

0.前言

正文可以跳过这段

初识clion,应该是2015年首次发布的时候, 那会还是大三,被一则推介广告吸引到,当时还在用vs studio,但是就喜欢鼓捣新工具,然后下载安装试用了clion,但是当时对cmake规则知之甚少,而且觉得还麻烦,所以之后就没有再用clion了。一晃10年已逝。

从事嵌入式MCU开发工作的,现在用过Keil MDK、IAR、VS-Code、RT-thread studio(eclipse核),现在从我辈楷模这里了解用Clion也能做嵌入式开发,那必须试试,

1.为了从github上 clone 稚晖的项目学习进步;

2.了解多种IDE的开发方式,知己知彼,后续可以根据项目适用哪种平台,灵活的选择开发方式:

比如,我现在喜欢RT-Thread Studio,因为基于HAL库的初始化代码可以很方面的使用cubemx的ioc工程配置,rt-thread系统的管理 也很方便。

Clion 也可以使用ioc工程完成基于HAL库的的初始化配置。

所以可以根据项目的特点 选择最易开发的平台。

3.另外就是大家说的开源问题,商业软件都涉及licenses,能用开源的方式还是开源的方式,虽然clion也不是开源的,但是商业化的便捷也可以试试到底有多好用。

参考 ,随着系统版本更新,各软件也都更新,与时俱进,参考配置的过程也不是一帆风顺,故记录一下,我的配置环境和过程,方便交流学习。

1.环境及所需工具

软件环境:

软件名版本号描述
Windows 11
STM32CubeMXV6.5.0
Clion2024.3.4
MinGW-W64MSYS2更新最新版
OpenOCD是用于对STM32进行下载仿真的工具,是一个开源软件包
arm-none-eabi-gcc

关于交叉编译工具链的详细可跳转到我的另外一篇博文

硬件环境:

软件名版本号描述
STM32F103VET6
J-LinkV9

2.需要重点注意的点

稚晖的文档已经很详细了,我这里只说点卡点

Clion的配置上,在配置预设的MinGW和Cmake环境上,我是使用MSYS2安装的MinGW-W64环境,

这是正确的配置图

https://i-blog.csdnimg.cn/direct/72e1c14d38e94bc8b912bb21f9ee8f2d.png

提供一个错误的配置图,该mingw64-环境 是用于配置rt-thread studio的环境和工具链的,这个mingw64-环境是我在其它平台上正常可以使用的环境,也不知道为什么不能正常工作,这里先将其配置为msys下配置的mingw环境 先解决问题;

https://i-blog.csdnimg.cn/direct/dc273381deb14858a59874d41aa0b755.png

其实 对于 插件管理式的平台,针对嵌入式开发 离不开这些环境的配置;比如vscode eclipse clion等。

目前clion的这个环境文件很重要,即使我不更改下面的其它可执行文件,即为配置成这样也可以正常构建

https://i-blog.csdnimg.cn/direct/799e61cd59bf4a35ab246758def7352c.png

我现在有一个问题是 clion 是 如何查找捆绑的cmake gdb的 ?

上述配置完成后 基本上是可以 构建程序了 完成了很重要的一步。

openocd下载和运行

openocd 在稚晖君的教程中需要配置一下 这个 进入方式

https://i-blog.csdnimg.cn/direct/b92f9266021941898924068da48b6041.png

进入后需要在该界面下新建一个openocd下载和运行的配置环境,类似于keil里面需要下载什么文件进去,使用什么调试工具。

https://i-blog.csdnimg.cn/direct/c05968a79d4e401da39728ced205d484.png

按照教程 配置 和稚晖的区别是他使用的DAP 可能windows下 clion支持挺好的 , 我用的jlink 就出现一个错误

使用的stm32f1x.cfg文件内容如下

# 选择 J-Link 适配器
adapter driver jlink

# 选择 SWD 协议
transport select swd

# 配置目标芯片(STM32F103VE)
source [find target/stm32f1x.cfg]

错误情况:

Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Warn : Failed to open device: LIBUSB_ERROR_NOT_SUPPORTED
Error: No J-Link device found

使用 OpenOCD 调试模式

openocd -d3 -f stm32f103c8_blue_pill.cfg

得到的详细debug 报告

PS D:\MyProjectRepos\MCUDevelopProject\Ctrl-FOC-Lite\2.Firmware\STM32_HAL_version\Ctrl-FOC-Lite-fw> openocd -d3 -f stm32f103c8_blue_pill.cfg
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
User : 3 2 options.c:52 configuration_output_handler(): debug_level: 3
User : 4 4 options.c:52 configuration_output_handler():
Debug: 5 6 options.c:233 add_default_dirs(): bindir=D:/a/msys64/mingw64/bin
Debug: 6 7 options.c:234 add_default_dirs(): pkgdatadir=D:/a/msys64/mingw64/share/openocd
Debug: 7 9 options.c:235 add_default_dirs(): exepath=D:/msys64/mingw64/bin
Debug: 8 11 options.c:236 add_default_dirs(): bin2data=../share/openocd
Debug: 9 13 configuration.c:33 add_script_search_dir(): adding C:/Users/leesincere/AppData/Roaming/OpenOCD
Debug: 10 16 configuration.c:33 add_script_search_dir(): adding D:/msys64/mingw64/bin/../share/openocd/site
Debug: 11 19 configuration.c:33 add_script_search_dir(): adding D:/msys64/mingw64/bin/../share/openocd/scripts
Debug: 12 22 command.c:155 script_debug(): command - ocd_find stm32f103c8_blue_pill.cfg
Debug: 13 24 configuration.c:88 find_file(): found stm32f103c8_blue_pill.cfg
Debug: 14 28 command.c:155 script_debug(): command - adapter driver jlink
Debug: 15 30 command.c:155 script_debug(): command - transport select swd
Debug: 16 32 command.c:155 script_debug(): command - ocd_find target/stm32f1x.cfg
Debug: 17 35 configuration.c:88 find_file(): found D:/msys64/mingw64/bin/../share/openocd/scripts/target/stm32f1x.cfg
Debug: 18 38 command.c:155 script_debug(): command - ocd_find target/swj-dp.tcl
Debug: 19 41 configuration.c:88 find_file(): found D:/msys64/mingw64/bin/../share/openocd/scripts/target/swj-dp.tcl
Debug: 20 44 command.c:155 script_debug(): command - transport select
Debug: 21 46 command.c:155 script_debug(): command - ocd_find mem_helper.tcl
Debug: 22 48 configuration.c:88 find_file(): found D:/msys64/mingw64/bin/../share/openocd/scripts/mem_helper.tcl
Debug: 23 52 command.c:155 script_debug(): command - add_usage_text mrw address
Debug: 24 54 command.c:155 script_debug(): command - add_help_text mrw Returns value of word in memory.
Debug: 25 56 command.c:155 script_debug(): command - add_usage_text mrh address
Debug: 26 59 command.c:155 script_debug(): command - add_help_text mrh Returns value of halfword in memory.
Debug: 27 62 command.c:155 script_debug(): command - add_usage_text mrb address
Debug: 28 64 command.c:155 script_debug(): command - add_help_text mrb Returns value of byte in memory.
Debug: 29 67 command.c:155 script_debug(): command - add_usage_text mmw address setbits clearbits
Debug: 30 69 command.c:155 script_debug(): command - add_help_text mmw Modify word in memory. new_val = (old_val & ~clearbits) | setbits;
Debug: 31 73 command.c:155 script_debug(): command - transport select
Debug: 32 74 command.c:155 script_debug(): command - expr  [ string first "jtag" $_TRANSPORT ] != -1
Debug: 33 76 command.c:155 script_debug(): command - transport select
Debug: 34 78 command.c:155 script_debug(): command - expr  [ string first "jtag" $_TRANSPORT ] != -1
Debug: 35 81 command.c:155 script_debug(): command - transport select
Debug: 36 82 command.c:155 script_debug(): command - expr  [ string first "swd" $_TRANSPORT ] != -1
Debug: 37 85 command.c:155 script_debug(): command - swd newdap stm32f1x cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x1ba01477
Debug: 38 88 tcl.c:557 jim_newtap_cmd(): Creating New Tap, Chip: stm32f1x, Tap: cpu, Dotted: stm32f1x.cpu, 8 params
Debug: 39 92 core.c:1474 jtag_tap_init(): Created Tap: stm32f1x.cpu @ abs position 0, irlen 0, capture: 0x0 mask: 0x0
Debug: 40 95 command.c:155 script_debug(): command - dap create stm32f1x.dap -chain-position stm32f1x.cpu
Debug: 41 98 command.c:155 script_debug(): command - transport select
Debug: 42 100 command.c:155 script_debug(): command - expr  [ string first "jtag" $_TRANSPORT ] != -1
Debug: 43 103 command.c:155 script_debug(): command - target create stm32f1x.cpu cortex_m -endian little -dap stm32f1x.dap
Debug: 44 107 command.c:289 register_command(): command 'tpiu' is already registered
Debug: 45 109 command.c:289 register_command(): command 'rtt' is already registered
Debug: 46 111 command.c:155 script_debug(): command - stm32f1x.cpu configure -work-area-phys 0x20000000 -work-area-size 0x1000 -work-area-backup 0
Debug: 47 115 target.c:2199 target_free_all_working_areas_restore(): freeing all working areas
Debug: 48 118 target.c:2199 target_free_all_working_areas_restore(): freeing all working areas
Debug: 49 120 target.c:2199 target_free_all_working_areas_restore(): freeing all working areas
Debug: 50 123 command.c:155 script_debug(): command - flash bank stm32f1x.flash stm32f1x 0x08000000 0 0 0 stm32f1x.cpu
Debug: 51 126 tcl.c:1305 handle_flash_bank_command(): 'stm32f1x' driver usage field missing
Debug: 52 129 command.c:155 script_debug(): command - adapter speed 1000
Debug: 53 132 adapter.c:251 adapter_config_khz(): handle adapter khz
Debug: 54 134 adapter.c:215 adapter_khz_to_speed(): convert khz to adapter specific speed value
Debug: 55 136 adapter.c:215 adapter_khz_to_speed(): convert khz to adapter specific speed value
Debug: 56 139 command.c:155 script_debug(): command - adapter srst delay 100
Debug: 57 142 command.c:155 script_debug(): command - transport select
Debug: 58 144 command.c:155 script_debug(): command - expr  [ string first "jtag" $_TRANSPORT ] != -1
Debug: 59 147 command.c:155 script_debug(): command - reset_config srst_nogate
Debug: 60 149 command.c:155 script_debug(): command - transport select
Debug: 61 150 command.c:155 script_debug(): command - expr  [ string first "hla" $_TRANSPORT ] != -1
Debug: 62 153 command.c:155 script_debug(): command - cortex_m reset_config sysresetreq
Debug: 63 155 command.c:155 script_debug(): command - stm32f1x.cpu configure -event examine-end
        # DBGMCU_CR |= DBG_WWDG_STOP | DBG_IWDG_STOP |
        #              DBG_STANDBY | DBG_STOP | DBG_SLEEP
        mmw 0xE0042004 0x00000307 0

Debug: 64 161 command.c:155 script_debug(): command - tpiu create stm32f1x.tpiu -dap stm32f1x.dap -ap-num 0 -baseaddr 0xE0040000
Debug: 65 165 command.c:155 script_debug(): command - stm32f1x.tpiu configure -event pre-enable _proc_pre_enable_stm32f1x.tpiu stm32f1x.cpu
Debug: 66 169 command.c:155 script_debug(): command - adapter speed 10000
Debug: 67 171 adapter.c:251 adapter_config_khz(): handle adapter khz
Debug: 68 173 adapter.c:215 adapter_khz_to_speed(): convert khz to adapter specific speed value
Debug: 69 176 adapter.c:215 adapter_khz_to_speed(): convert khz to adapter specific speed value
User : 70 179 options.c:52 configuration_output_handler(): adapter speed: 10000 kHz
User : 71 181 options.c:52 configuration_output_handler():
Info : 72 184 server.c:297 add_service(): Listening on port 6666 for tcl connections
Info : 73 187 server.c:297 add_service(): Listening on port 4444 for telnet connections
Debug: 74 189 command.c:155 script_debug(): command - init
Debug: 75 191 command.c:155 script_debug(): command - target init
Debug: 76 193 command.c:155 script_debug(): command - target names
Debug: 77 195 command.c:155 script_debug(): command - stm32f1x.cpu cget -event gdb-flash-erase-start
Debug: 78 198 command.c:155 script_debug(): command - stm32f1x.cpu configure -event gdb-flash-erase-start reset init
Debug: 79 201 command.c:155 script_debug(): command - stm32f1x.cpu cget -event gdb-flash-write-end
Debug: 80 204 command.c:155 script_debug(): command - stm32f1x.cpu configure -event gdb-flash-write-end reset halt
Debug: 81 208 command.c:155 script_debug(): command - stm32f1x.cpu cget -event gdb-attach
Debug: 82 210 command.c:155 script_debug(): command - stm32f1x.cpu configure -event gdb-attach halt 1000
Debug: 83 213 target.c:1657 handle_target_init_command(): Initializing targets...
Debug: 84 215 semihosting_common.c:109 semihosting_common_init():
Debug: 85 217 jlink.c:635 jlink_init(): Using libjaylink 0.4.0 (compiled with 0.4.0)
Debug: 86 235 jlink.c:514 jaylink_log_handler(): Found device (VID:PID = 1366:0101, bus:address = 001:018)
Warn : 87 238 jlink.c:514 jaylink_log_handler(): Failed to open device: LIBUSB_ERROR_NOT_SUPPORTED
Debug: 88 241 jlink.c:514 jaylink_log_handler(): Found 0 USB device(s)
Error: 89 242 jlink.c:688 jlink_init(): No J-Link device found
Debug: 90 244 command.c:544 run_command(): Command 'init' failed with error code -100
User : 91 247 command.c:608 command_run_line():
Debug: 92 249 target.c:2199 target_free_all_working_areas_restore(): freeing all working areas

根据调试日志分析,根本原因是 ​Windows 系统下 libusb 与 SEGGER 官方驱动冲突,导致 OpenOCD 无法正确访问 J-Link 设备。以下是逐行解析和终极解决方案:

​错误日志关键点分析

Found device (VID:PID = 1366:0101)

J-Link 设备已被系统识别,VID/PID 正确。

Failed to open device: LIBUSB_ERROR_NOT_SUPPORTED

OpenOCD 的 libjaylink 库尝试通过 libusb 访问 J-Link,但被系统拒绝。

No J-Link device found

最终因驱动冲突导致设备访问失败。

​根本原因

​Windows 系统同时存在 libusb 和 SEGGER 驱动,OpenOCD 默认优先使用 libusb,但 SEGGER 官方驱动已独占设备访问权。

​OpenOCD 配置未完全禁用 libusb,导致底层库(libjaylink)仍尝试通过 libusb 通信。

但是尝试了很多办法 不知道如何使clion使用segger的驱动,也尝试了禁用libusb在cfg文件内加入以下代码 好像无效,

# 禁用 libusb,强制使用 SEGGER 驱动
jlink config use_libusb false
jlink usb 0

根据wiki 文档 那segger+jlink就不是一个好的调试选项,因为切换后,因为他更换了jlink的驱动程序,使用keil iar 等程序时,就不太好用了,

那不如换调试器了,DAP或者st link

总结

至此,总算是能完成的搭建好 构建 debug的环境配置了,尽管jlink+openocd不是一个联合调试的好选项。

参考