|
|
本帖最后由 magic_key 于 2026-9-12 23:02 编辑
当我们使用OpenOCD驱动J-Link烧录固件,可能就会碰到这个问题,报错如下:
Warn : Failed to open device: LIBUSB_ERROR_NOT_FOUND
Error: No J-Link device found
J-Link及其相关工具,例如J-Link Commander、J-Flash 、J-Link RTT Viewer ..... 使用LibUSB驱动。
而OpenOCD使用WinUSB驱动J-Link,导致了这个报错。
糟糕且治标不治本的办法,就是使用USBDriverTool,常驻后台,来回切换USB驱动。
OpenOCD + J-Link与J-Link Commander、Keil MDK的USB驱动,互相排斥,无法同时使用。
这样整的话,迟早会弄伤我们的鳞片。哦,我的天呐,这也太不体面了!
这就好比,用恒河水做的印度糊糊。吃完,还要让你说一句:干净又卫生啊,兄弟们。
在CLion下开发QT界面,通常都会使用外部工具,去调用QT的UI布局设计工具。
业务代码实现与ui布局设计分离,还不用重复造轮子。
巧的是,J-Link软件提供了外部调用和接口,配合CLion IDE的外部工具加按键映射。
使用快捷键,就能实现一键烧录固件。
CLion => 设置 => 工具 => 外部工具
名称: jlink_flash
程序: C:\Program Files\SEGGER\JLink_V976\JLink.exe
实参: -if SWD -speed 12000 -autoconnect 1 -CommanderScript $ProjectFileDir$/flash.jlink
工作目录: $ProjectFileDir$
CLion => 设置 => 按键映射 => 外部工具 => jlink_flash,添加键盘快捷键或鼠标快捷方式。
一些好一点点的鼠标有双滚轮,多出来的一个滚轮,用来做快捷键再适合不过了。
鼠标向下滚动滚轮,一键烧录单片机固件。实在是太方便,太优雅了!(旁白:你说的,一点都对!)
项目根目录下,创建flash.jlink文件,内容如下:
// 1. 指定单片机型号(换芯片只需改这一行)
device AT32F403ACGT7
// 复位并停止 CPU
r
halt
// 烧录固件(路径相对于 CLion 的工作目录)
// 注意:如果使用了 .elf 或.hex文件,J-Link 会自动解析地址,bin文件需在后面指定烧录地址 例如默认的0x08000000
loadfile "cmake-build-debug-atfe/CLion_ATfE_project.hex"
// 再次复位,让程序从头开始运行
r
go
// 退出 J-Link Commander
exit
运行窗口输出信息如下:
"C:\Program Files\SEGGER\JLink_V976\JLink.exe" -if SWD -speed 12000 -autoconnect 1 -CommanderScript D:\TODO\project\CLion_ATfE_project/flash.jlink
SEGGER J-Link Commander V9.76 (Compiled Sep 9 2026 15:09:42)
DLL version V9.76, compiled Sep 9 2026 15:08:38
J-Link Command File read successfully.
Processing script file...
J-Link>device AT32F403ACGT7
J-Link connection not established yet but required for command.
Connecting to J-Link ...O.K.
Firmware: J-Link V9 compiled May 7 2021 16:26:12
Hardware version: V9.60
J-Link uptime (since boot): N/A (Not supported by this model)
S/N: 20684568
License(s): RDI,FlashBP,FlashDL,JFlash,GDB
VTref=3.327V
J-Link>r
Target connection not established yet but required for command.
Device "AT32F403ACGT7" selected.
Connecting to target via SWD
InitTarget() start
DAP initialized successfully.
No Protection is set.
InitTarget() end - Took 5.01ms
Found SW-DP with ID 0x2BA01477
DPIDR: 0x2BA01477
CoreSight SoC-400 or earlier
Scanning AP map to find all available APs
AP[1]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x24770011, ADDR: 0x00000000)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xE00FF000
CPUID register: 0x410FC241. Implementer code: 0x41 (ARM)
Found Cortex-M4 r0p1, Little endian.
FPUnit: 6 code (BP) slots and 2 literal slots
CoreSight components:
ROMTbl[0] @ E00FF000
[0][0]: E000E000 CID B105E00D PID 000BB00C SCS-M7
[0][1]: E0001000 CID B105E00D PID 003BB002 DWT
[0][2]: E0002000 CID B105E00D PID 002BB003 FPB
[0][3]: E0000000 CID B105E00D PID 003BB001 ITM
[0][4]: E0040000 CID B105900D PID 000BB9A1 TPIU
[0][5]: E0041000 CID B105900D PID 000BB925 ETM
Memory zones:
Zone: "Default" Description: Default access mode
Cortex-M4 identified.
Reset delay: 0 ms
Reset type: NORMAL (https://kb.segger.com/J-Link_Reset_Strategies)
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.
J-Link>halt
PC = 08001230, CycleCnt = 00000000
R0 = 00000000, R1 = 00000000, R2 = 00000000, R3 = 00000000
R4 = 00000000, R5 = 00000000, R6 = 00000000, R7 = 00000000
R8 = 00000000, R9 = 00000000, R10= 00000000, R11= 00000000
R12= 00000000
SP(R13)= 20018000, MSP= 20018000, PSP= 00000000, R14(LR) = FFFFFFFF
XPSR = 01000000: APSR = nzcvq, EPSR = 01000000, IPSR = 000 (NoException)
CFBP = 00000000, CONTROL = 00, FAULTMASK = 00, BASEPRI = 00, PRIMASK = 00
FPS0 = 00000000, FPS1 = 00000000, FPS2 = 00000000, FPS3 = 00000000
FPS4 = 00000000, FPS5 = 00000000, FPS6 = 00000000, FPS7 = 00000000
FPS8 = 00000000, FPS9 = 00000000, FPS10= 00000000, FPS11= 00000000
FPS12= 00000000, FPS13= 00000000, FPS14= 00000000, FPS15= 00000000
FPS16= 00000000, FPS17= 00000000, FPS18= 00000000, FPS19= 00000000
FPS20= 00000000, FPS21= 00000000, FPS22= 00000000, FPS23= 00000000
FPS24= 00000000, FPS25= 00000000, FPS26= 00000000, FPS27= 00000000
FPS28= 00000000, FPS29= 00000000, FPS30= 00000000, FPS31= 00000000
FPSCR= 00000000
J-Link>loadfile "cmake-build-debug-atfe/CLion_ATfE_project.hex"
'loadfile': Performing implicit reset & halt of MCU.
Reset type: NORMAL (https://kb.segger.com/J-Link_Reset_Strategies)
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.
Downloading file [cmake-build-debug-atfe/CLion_ATfE_project.hex]...
J-Link: Flash download: Bank 0 @ 0x08000000: 1 range affected (6144 bytes)
J-Link: Flash download: Total: 0.339s (Prepare: 0.044s, Compare: 0.055s, Erase: 0.150s, Program: 0.043s, Verify: 0.010s, Restore: 0.035s)
J-Link: Flash download: Program & Verify speed: 112 KB/s
O.K.
J-Link>r
Reset delay: 0 ms
Reset type: NORMAL (https://kb.segger.com/J-Link_Reset_Strategies)
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.
J-Link>go
Memory map 'after startup completion point' is active
J-Link>exit
Script processing completed.
进程已结束,退出代码为 0
====================================== 一点都不华丽的分割线 ======================================
J-Link还有很多工具,由此衍生一些其他玩法。
比如CLion外部工具调用J-Link RTT Viewer ,输出J-Link RTT 打印信息
名称: J-Link RTT Viewer Printf
程序: C:\Program Files\SEGGER\JLink_V976\JLinkRTTViewer.exe
实参: --device AT32F403ACGT7 --interface SWD --speed 12000 --autoconnect
工作目录: $ProjectFileDir$
CLion外部工具调用PowerShell脚本,PowerShell脚本里又调用J-Link RTT Logger,
实现自动化保存指定时长的RTT Printf日志文件
名称: jlink_rtt_logger
程序: powershell.exe
实参: -NoProfile -ExecutionPolicy Bypass -File "$ProjectFileDir$\jlink_rtt_logger.ps1"
工作目录: $ProjectFileDir$
项目根目录下,创建jlink_rtt_logger.ps1文件,内容如下:
# =====================================================================
# J-Link RTT Logger 定时日志记录脚本(此文件必须保存为 UTF-8 with BOM)
# ---------------------------------------------------------------------
# 功能:启动 JLinkRTTLogger 记录指定时长的 RTT 数据,到时自动停止。
# 用途:通过 CLion 外部工具一键调用,无需手动打开/关闭 RTT Viewer。
# =====================================================================
# 强制 PowerShell 以 UTF-8 输出,否则 CLion 控制台(按 UTF-8 解析)会乱码
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8
# =====================================================================
# 【配置区】换芯片、换速度、换时长,只改下面这几行即可
# =====================================================================
# J-Link 安装目录下 RTT Logger 的完整路径
$JLinkPath = "C:\Program Files\SEGGER\JLink_V976\JLinkRTTLogger.exe"
# 目标单片机型号,必须与 J-Link 设备库中的名称完全一致
# 换芯片时只改这一行,例如:AT32F403ACGT7 / STM32F407IG
$Device = "AT32F403ACGT7"
# 调试接口类型,可选 SWD 或 JTAG,绝大多数 ARM 芯片用 SWD
$Interface = "SWD"
# 接口时钟速度,单位 kHz。12000 即 12 MHz。连接不稳可降到 4000
$Speed = 12000
# RTT 通道号。0 通常是 Terminal 通道(对应 SEGGER_RTT_printf)
$RttChannel = 0
# 记录时长,单位秒。到时脚本会自动结束 JLinkRTTLogger 进程
# 常用值:8(快速抓一段)、60(一般测试)、3600(长时间挂机)
$Duration = 8
# =====================================================================
# 【内部变量】以下一般不需要修改
# =====================================================================
# 日志文件路径:与当前脚本同目录,文件名为 rtt_log.txt
# $PSScriptRoot 自动展开为脚本所在目录,无需关心从哪里调用
$LogFile = Join-Path $PSScriptRoot "rtt_log.txt"
# =====================================================================
# 【执行流程】
# =====================================================================
# -------- 打印配置信息 --------
Write-Host ""
Write-Host "============================================================"
Write-Host " J-Link RTT Logger"
Write-Host "============================================================"
Write-Host " 设备型号 : $Device"
Write-Host " 接口类型 : $Interface"
Write-Host " 接口速度 : $Speed kHz"
Write-Host " RTT 通道 : $RttChannel"
Write-Host " 记录时长 : $Duration 秒"
Write-Host " 日志文件 : $LogFile"
Write-Host "============================================================"
Write-Host ""
# -------- 步骤 1:清理可能残留的 JLinkRTTLogger 进程 --------
# 上次异常退出时,Logger 可能仍占用 J-Link,导致本次连接失败
Get-Process JLinkRTTLogger -ErrorAction SilentlyContinue | Stop-Process -Force
# -------- 步骤 2:启动 Logger 并精确控制生命周期 --------
# 参数逐项传入,避免路径含空格时的解析问题
# -PassThru 让我们拿到进程对象,稍后可精确终止
$process = Start-Process -FilePath $JLinkPath `
-ArgumentList '-Device', $Device, '-If', $Interface, '-Speed', $Speed, '-RTTChannel', $RttChannel, $LogFile `
-NoNewWindow -PassThru
# -------- 步骤 3:等待指定时长 --------
Start-Sleep -Seconds $Duration
# -------- 步骤 4:强制结束进程 --------
if (-not $process.HasExited) {
Stop-Process -Id $process.Id -Force
}
# -------- 步骤 5:输出日志文件信息 --------
Write-Host ""
Write-Host "============================================================"
if (Test-Path $LogFile) {
$info = Get-Item $LogFile
Write-Host " [成功] RTT 日志已生成"
Write-Host "------------------------------------------------------------"
Write-Host " 文件名 : $($info.Name)"
Write-Host " 文件大小 : $($info.Length) 字节"
Write-Host " 修改时间 : $($info.LastWriteTime)"
} else {
Write-Host " [失败] 未找到日志文件:$LogFile"
Write-Host " 请检查:J-Link 连接、芯片型号、目标板供电。"
}
Write-Host "============================================================"
PowerShell脚本运行输出:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File D:\TODO\project\CLion_ATfE_project\jlink_rtt_logger.ps1
============================================================
J-Link RTT Logger
============================================================
设备型号 : AT32F403ACGT7
接口类型 : SWD
接口速度 : 12000 kHz
RTT 通道 : 0
记录时长 : 8 秒
日志文件 : D:\TODO\project\CLion_ATfE_project\rtt_log.txt
============================================================
SEGGER J-Link RTT Logger
Compiled Sep 9 2026 15:10:16
(c) 2016-2017 SEGGER Microcontroller GmbH, www.segger.com
Solutions for real time microcontroller applications
Default logfile path: C:\Users\uesr\AppData\Roaming\SEGGER
------------------------------------------------------------
------------------------------------------------------------
Connected to:
SEGGER J-Link
S/N: 20684568
Searching for RTT Control Block...OK.
3 up-channels found:
0: Terminal
1:
2:
Selected RTT Channel description:
Index: 0
Name: Terminal
Size: 1024 bytes.
Output file: D:\TODO\project\CLion_ATfE_project\rtt_log.txt
Getting RTT data from target. Press any key to quit.
------------------------------------------------------------
Transfer rate: 0 Bytes/s Data written: 1.18 KB
============================================================
[成功] RTT 日志已生成
------------------------------------------------------------
文件名 : rtt_log.txt
文件大小 : 1243 字节
修改时间 : 09/12/2026 17:24:23
============================================================
进程已结束,退出代码为 0
====================================== 一点都不华丽的分割线 ======================================
鸣谢
骚话: 印度老吃家
旁白: 印度老吃家
编辑·: 本人
赞助商: 不存在的呀
|
|