LV010-JFlash简介
一、JFlash简介
我们有源码的时候可以使用MDK编译,然后一键下载,那我们要是没有源码怎么办?用串口吗?当然可以,还有别的办法吗?有啊,下边我们就来了解一下吧。
J-Flash 是单独的Flash ISP烧写软件,是一种独立Flash编程软件了,可以把单独的bin文件或者hex文件烧写到单片机的flash里面去。它是在安装 J-Link 驱动时自带的一款Flash ISP软件,支持bin格式、hex格式、srec格式(Motorola的)。
二、安装jFlash
这个软件一般是随着J-Link驱动安装一起自动安装的,所以在我们安装好J-Link驱动的时候,这个软件就已经被安装好了,没有必要再单独安装,我们找到后直接双击打开使用就好,打开后界面如下:

三、基本使用
1. 创建工程
- (1)【Create new project】→【Start J-Flash】

① 创建新工程;
② 开始创建。
2. 配置工程
- (2)配置工程

① 选择目标芯片设备;
② 过滤框,可以添加一系列的过滤条件,快速找到我们的芯片;
③ 选择我们使用的芯片系列,然后点击OK即可;
④ 这里可以选择使用SWD或者是JTAG,我们还是选择引脚较少的SWD;
⑤ 选择下载的速率,我一般都是填的默认。
最后点击OK,就可以进入我们新创建的工程啦:

3. 连接设备
- (3)连接设备
如果选择的是SWD模式,就要连接SWDIO、SWCLK、GND这三根线,连接好之后,点击【Target】→【Connect】,如果连接成功,在下面的LOG窗口会显示连接成功。

4. 打开烧写的文件
- (4)打开烧写的文件
JLink支持Hex、Bin等多种文件类型,【File】→【Open data file】

注意:这里如果选择的是bin文件,还需要指定烧写的起始地址(Flash的起始地址,一般就是0x8000 0000),因为bin文件是不包含烧写地址的,而hex文件是包含的。
5. 开始烧写
- (5)开始烧写
打开Hex文件之后,点击【Target】→【Producion Programming】,或者使用快捷键F7,等待几秒之后,程序就下载进去了,下载成功后,会在底部窗口显示烧写成功。

6. 运行程序
- (6)运行程序
烧写成功之后,此时程序还没有运行,点击【Target】→【Manual Programming】→【Start Application】,或者按快捷键F9,程序才开始运行,或者按复位键也可以让程序运行。

7. 保存工程
- (7)保存工程
退出的时候会提示我们保存工程,我们可已经这个工程保存到一个指定的目录,下一次再为这个芯片烧写的时候就不用再进行工程配置了,工程文件的后缀名为 .jflas 。
四、程序自动运行
- 程序自动运行:如果想让每次下载完成后,程序自动运行,而不用复位。可以使用工程配置下的自动运行选项。打开【Option】→【Project Setting】,切换到【Production】选项,勾选【Start Application】,就可以让程序自动运行。

五、读取单片机内部程序
选择【Target】→【Manual Programming】→【Read Back】,一共有三个选项,用于读取不同的Flash地址范围。

- Selected sectors
意思是被选择的扇区,可以在工程配置选项【Project settings】 → 【Flash】,查看哪些扇区被选择了。

Entire chip:整个Flash区域,一般选择这个选项,读取整个Flash区域的程序。
Range:手动指定读取的Flash地址范围:

一般来说,这里我们选择Entire chip就可以了,读取整个Flash区域,地址范围:0x8000000~0x807FFFF

等几秒钟,就可以看到底部窗口显示读取成功的信息。然后我们点击OK,就会看到在数据区域出现了我们读出来的数据,我们可以看一下,读取的数据跟我们烧写进去的数据是一样的。

然后我们也可以保存读取到的数据,选项【File】→ 【Save data file】(当是我们读取到的数据的时候这里才可选,不然是灰色的,无法使用,将光标放在我们读取的数据的区域即可)或者是【Save data file as】,保存类型根据需要选择,建议选择Hex格式,已经包含了地址信息。保存好数据后,我使用beyond compare比较工具比较一下读取的和烧写的数据,结果发现还是有很大的不同的,这个不清楚是为什么,可能还是地址信息的问题导致的,但是从软件中看到的信息说明我们烧写进去的数据与读回的数据是一致的。我们也可以将读取的hex文件重新烧写到板子上,看看是不是一样的现象就可以确定我们读取的数据是否与烧写的一致。
既然能这么简单的读取到单片机的程序,那么我们自己的程序应该如何保护起来呢?很显然,我们可以对Flash设置读保护功能,即大家说的“加密”功能,可以防止对Flash的非法访问,这里的加密是针对整个Flash区域的,如果设置了读保护功能,那么程序只能正常的从RAM中加载运行,而不能通过调试器读出来,那么别人就不能破解了。在ST提供的固件库中已经有相关函数了,后边学习到的时候再说。
六、 命令行调用
GUI 适合偶尔烧一次。要把烧写放进构建脚本、CI 或者一键发布流程里,就得用命令行。JFlash.exe 自带一组命令行参数,完整清单在 GUI 里用 -help 弹出(下图),脚本里常用的只有其中几个。

1. 常用参数
| 参数 | 作用 |
|---|---|
-openprj <file> | 打开一个已保存的 .jflash 工程 |
-open <file>[,<addr>] | 打开数据文件;bin 必须带烧写起始地址,hex 不用 |
-auto | 执行 Production Programming:擦除 → 烧写 → 校验 |
-production | 与 -auto 相同 |
-startapp | 启动目标应用 |
-erasechip / -program / -verify | 只擦除 / 只烧写 / 只校验 |
-readchip / -readrange <s>,<e> | 读回整片 / 读回指定地址范围 |
-saveas <file> | 把当前数据另存为文件 |
-usb <SN> | 接了多台 J-Link 时按序列号指定用哪一台 |
-jflashlog <file> / -jlinklog <file> | 把 J-Flash / J-Link 日志写到文件 |
-min / -hide | 最小化 / 隐藏窗口启动 |
-exit | 动作完成后自动退出进程 |
2. 脚本化之前必须知道的三件事
(1)JFlash.exe 不往控制台输出任何东西。它是 GUI 子系统程序,-help 弹的是上图这个对话框,而不是往终端打印帮助文本。脚本想看执行结果,只能用 -jflashlog 把日志落到文件再读。
(2)必须显式等待进程结束。PowerShell 里直接 & JFlash.exe ... 会立即返回,拿到的退出码不是 J-Flash 的。要用 Start-Process -Wait -PassThru 读 .ExitCode:实测烧写成功返回 0,工程文件不存在返回 1。cmd 下的 start /wait 在 Git Bash 等环境里同样传不回退出码,别用它判成败。
(3)-auto 做什么完全由工程文件决定。擦不擦、校验不校验、烧完跑不跑,对应工程 Production 页的勾选项,也就是工程文件里的 AutoPerformsErase、AutoPerformsProgram、AutoPerformsVerify、AutoPerformsStartApp,命令行上不重复指定。所以脚本化的第一步是在 GUI 里把工程配好并保存成 .jflash,命令行只负责"打开它、执行、退出"。
3. 最小可用命令
工程已经配好时,四行就够:
$p = Start-Process -FilePath "C:\Program Files\SEGGER\JLink\JFlash.exe" `
-ArgumentList '-openprj','stm32_upgrade.jflash','-auto','-exit' -PassThru -Wait
if ($p.ExitCode -ne 0) { throw "J-Flash failed: $($p.ExitCode)" }临时换数据文件、留日志,就在参数里加两项:
-ArgumentList '-openprj','stm32_upgrade.jflash','-open','app.hex','-jflashlog','flash.log','-auto','-exit'-open 会覆盖工程里记录的数据文件,bin 文件记得带地址:-open app.bin,0x08000000。
4. 换 hex 而不碰仓库里的工程
工程文件是纯文本(INI 风格),数据文件路径记在 [GENERAL] 段的 CurrentFile 里。脚本把工程复制一份、改掉这一行再调用,仓库里的工程就始终保持不动:
function Invoke-JFlash {
param(
[string]$Project, # 仓库里已配好的 .jflash
[string]$DataFile, # 本次要烧的 hex / bin
[switch]$NoRun # 烧完保持停机,不启动应用
)
$copy = Join-Path $env:TEMP 'run.jflash'
$text = [System.IO.File]::ReadAllText($Project)
$text = [regex]::Replace($text, '(?m)^\s*CurrentFile\s*=.*$', " CurrentFile = `"$DataFile`"")
if ($NoRun) {
$text = [regex]::Replace($text, '(?m)^(\s*AutoPerformsStartApp\s*=\s*)\d+\s*$', '${1}0')
}
[System.IO.File]::WriteAllText($copy, $text)
$log = Join-Path $env:TEMP 'jflash.log'
$p = Start-Process -FilePath 'C:\Program Files\SEGGER\JLink\JFlash.exe' `
-ArgumentList "-openprj `"$copy`" -auto -jflashlog `"$log`" -exit" -PassThru -Wait
if ($p.ExitCode -ne 0) {
Get-Content $log | Select-String -Pattern 'ERROR|Failed' | ForEach-Object { Write-Host $_ }
throw "J-Flash failed (exit $($p.ExitCode)), log: $log"
}
}这个封装取自一个真实工程的构建脚本(atk-f103 bootloader 的 build_flash.ps1):MDK 编出 hex 后调它烧写,-NoRun 用于调试时让 CPU 停在复位后不复位运行。