[APM32F4] 聊聊 MCU 下载算法(FLM)在 Keil MDK 里的那些事儿:从入门到硬核

[复制链接]
发表于 1970-1-1 08:00 | 显示全部楼层
不错 说得很详细
发表于 1970-1-1 08:00 | 显示全部楼层
但看不懂的请报道
 楼主| 发表于 2025-8-7 16:22 | 显示全部楼层 |阅读模式
本帖最后由 DKENNY 于 2025-8-7 16:33 编辑

#申请原创# #技术资源# @21小跑堂
前言
      嗨,嵌入式开发的小伙伴们!用 Keil MDK(µVision)搭配 J-Link 或 DAPLink 调试器刷代码到 MCU 的 Flash,是咱们日常开发的老套路了。里面有个关键角色——Flash 编程算法(FLM 文件),就像个“幕后大佬”,帮调试器搞定 Flash 的擦除、编程和验证。可不少人(尤其是刚入门的小白)对 FLM 有点懵:这东西存哪儿?为啥非得加载到 SRAM?谁来管加载和跳转?今天咱们就来把 FLM 的前世今生扒个底朝天,聊清楚它的加载和运行机制。

一、FLM 下载算法是个啥?
      例如,F4的pack包中就包含了各种的flm文件。
flm文件.png

1.1 FLM 文件:刷 Flash 的“临时工”
      简单来说,FLM(Flash Loader Module)文件就是 Keil MDK 用来刷 MCU Flash 的“说明书”。它告诉调试器(J-Link 或 DAPLink)咋擦除 Flash、咋写代码、咋校验数据。FLM 文件一般由 MCU 厂商或者 Keil 提供,藏在 Keil 的 CMSIS-Pack 包里,或者装在 Keil 的安装目录(比如`C:\Keil_v5\ARM\Flash`)。
      对小白来说,FLM 文件就像个“临时工”:刷代码时它上场,干完活就撤,不占 MCU 的地儿。它跟你的用户代码没啥关系,专门负责跟 Flash 硬件打交道。你在 Keil 点“Download”,FLM 就在后台默默把代码刷进 Flash,省心得很。

1.2 FLM 文件里装了啥?
      FLM 文件是个二进制的“黑盒子”,里头有几块关键内容:
      - 算法代码:干活的核心逻辑,比如初始化 Flash 控制器、擦扇区、写数据、校验啥的。一般是用 C 或者汇编写,针对某个 MCU 的 Flash 硬件量身定做。
      - 元数据:相当于“说明书”,告诉你算法咋跑。比如:
        - AlgoRamStart:算法代码要加载到 SRAM 的哪个地址(比如`0x20000000`)。
        - AlgoRamSize:算法占多少 SRAM(比如 4KB)。
        - EntryPoint:代码从哪儿开始跑(比如`0x20000004`)。
        - DevInfo:Flash 的“户口本”,比如基地址`0x08000000`、页面大小 2KB、扇区大小 16KB。
      - 函数表:一堆标准化的“接口”,比如`Init`(初始化)、`EraseSector`(擦扇区)、`ProgramPage`(写页面),调试器靠这些接口调用算法。

      对新手来说,FLM 就像个“神秘盒子”,你看不到代码细节,但 Keil 和调试器能读懂它,靠它把代码刷进 Flash。

      图片 1:FLM 文件的“黑盒”结构
6d7a52f0698430f04d61948b92a6717a

1.3 FLM 文件打哪儿来?
      FLM 文件的来路有这几种:
      - Keil 官方的 Pack 包:Keil 给主流 MCU(比如 APM32F4、APM32F1、STM32F4)准备了一堆 FLM 文件,装完 Keil 就能在`ARM\Flash`目录找到。
      - MCU 厂商:像 ST、Geehy 这些厂商会为自家的 MCU 定制 FLM 文件,确保跟硬件完美匹配。
      - 自己动手:硬核玩家可以用 Keil 的 Flash Algorithm Development Kit 自己写 FLM 文件,适合搞非标 Flash 或者特殊场景(比如外接 SPI Flash)。
      写 FLM 文件得对 MCU 硬件了如指掌,比如 Flash 控制器的寄存器咋用、时序咋控制。论坛上有大佬分享过,我就不阐述怎么做了。

二、为啥 FLM 算法非得加载到 SRAM?

2.1 Flash 的“怪脾气”
      Flash 是 MCU 里存代码的“仓库”,掉电也不丢数据,可它有几个“怪脾气”,让 FLM 算法没法在 Flash 里跑:
      - 擦除时不可用:Flash 要写新数据,得先擦掉老数据(通常按 4KB 或 8KB 的扇区擦)。擦除期间,Flash 忙得不可开交,压根儿没法跑代码。比如,擦一个扇区可能要 50 毫秒,Flash 这时候就是个“哑巴”。
      - 寄存器操作:Flash 编程得通过 Flash 控制器搞一堆寄存器(比如控制寄存器 CR、状态寄存器 SR)。这些操作要快、要灵活,Flash 自个儿的读写速度太慢,干不了这活。
      - 慢得要命:Flash 的写操作慢得像乌龟,可能得 100 微秒才能写一次数据,读也比 SRAM 慢多了(SRAM 是纳秒级,Flash 是微秒级)。跑复杂算法(比如循环写数据、查错)在 Flash 里简直是灾难。
      - 占地方:FLM 算法只是下载时用用,长期搁在 Flash 里纯属浪费空间。比如 APM32F4 的 Flash 就 512KB,存个 4KB 的 FLM,挤占用户代码的地儿,太不划算。
      所以,Flash 只能当“仓库”,没法当 FLM 算法的“工作台”。

2.2 SRAM:灵活又高效的“工作台”
      SRAM(Static Random Access Memory)是 MCU 里的易失性存储器,干 FLM 算法的活简直完美:
      - 快如闪电:SRAM 读写速度超快,访问延迟就几个时钟周期(比如 APM32F4 的 SRAM 访问只要 1-2 个周期,纳秒级)。跑寄存器操作、循环逻辑啥的,效率杠杠的。
      - 随时上场:SRAM 能直接加载代码,CPU 一声令下就能跑,不像 Flash 还得先擦后写。
      - 地址清楚:MCU 的 SRAM 地址范围都写在数据手册里,比如 APM32F4 的 SRAM 从`0x20000000`开始,NXP LPC 系列可能是`0x10000000`。FLM 算法可以放心加载到 SRAM 的“安全地带”。
      - 用完就丢:SRAM 是易失性的,FLM 算法干完活就清空,不占资源,MCU 照常跑用户代码。

      图片 2:Flash vs. SRAM 的“性格”对比
57913c63436a63e50ed89cf17e13a465

2.3 调试器(J-Link/DAPLink)为啥不存 FLM?
      有些小伙伴想:能不能把 FLM 算法塞到 J-Link 或 DAPLink 里?答案是:想得美!原因有几大块:
      - 地方太小:J-Link 和 DAPLink 的固件存储就几百 KB(比如 J-Link 的 Flash 才 256KB-1MB)。FLM 文件少则几 KB,多则几十 KB,调试器得支持上百种 MCU,每个 MCU 可能要个 FLM 文件,哪儿装得下?
      - 得灵活点:J-Link 和 DAPLink 是“万金油”调试器,啥 MCU 都能用。把 FLM 硬塞进去,遇到新 MCU 或者自定义 FLM 就抓瞎了,升级固件也麻烦。
      - 传数据麻烦:就算 FLM 存在调试器里,每次还得通过 SWD/JTAG 传到 SRAM,速度慢不说,还增加通信开销。还不如让主机(PC)存 FLM,调试器只管传数据,省事儿又高效。
      - 固件得简单:调试器的固件就干点 SWD/JTAG 的活,塞太多功能(比如管 FLM 文件)会让固件复杂得像个“胖子”,维护起来头大。

      图片 3:调试器存储 FLM 的“不可能任务”
8f3e6452011ec49ed1b3b2c64d27728c

2.4 为啥不搁 Flash 里?
      把 FLM 算法塞到 Flash 里也不靠谱:
      - 擦了就没了:Flash 编程得先擦扇区,FLM 算法要是住在 Flash 里,擦除的时候自个儿就没了,咋跑?
      - 浪费空间:FLM 就下载时用一次,长期占着 Flash 的地儿,挤占用户代码的空间。
      - 慢得要命:Flash 的读写速度慢(写一次得 100 微秒),跑 FLM 算法效率低得可怜,SRAM 的纳秒级速度完胜。

2.5 咋挑 SRAM 地址?
      FLM 算法加载到 SRAM 的地址(比如`0x20000000`)不是随便挑的,有讲究:
      - MCU 内存地图:每个 MCU 的 SRAM 地址范围都写在数据手册里。比如 APM32F4 的 SRAM 从`0x20000000`开始,NXP LPC1768 是`0x10000000`。
      - 安全第一:FLM 算法选 SRAM 的低地址(比如`0x20000000`),避开用户代码的堆栈、变量啥的。用户代码一般用高地址(比如`0x20010000`),大家井水不犯河水。
      - 厂商定好了:MCU 厂商做 FLM 文件时,参考 SRAM 大小和硬件特性,挑个安全地址。比如 APM32F4 的 SRAM 有 192KB,FLM 算法占 4KB 绰绰有余,选低地址稳妥。

三、FLM 算法咋加载到 SRAM 又咋跑起来的?

3.1 整个流程:谁干啥?
      FLM 算法从 PC 加载到 MCU 的 SRAM,再到跑起来,是个团队作战的过程,Keil MDK、调试器(J-Link 或 DAPLink)、目标 MCU 各干各的活。咱们一步步拆开看:
3.1.1 Keil MDK:大脑指挥中心
      Keil MDK 是你开发时的“总指挥”,负责读懂 FLM 文件、发号施令:
      - 读 FLM 文件:Keil 打开 FLM 文件(比如`APM32F4xx_512.FLM`),从里头掏出关键信息:
        - SRAM 起始地址(`AlgoRamStart`,比如`0x20000000`):算法代码放哪儿。
        - 算法大小(`AlgoRamSize`,比如 4KB):得占多少地儿。
        - 入口地址(`EntryPoint`,比如`0x20000004`):代码从哪儿开始跑。
        - Flash 参数(`DevInfo`):Flash 的地址、大小啥的,比如基地址`0x08000000`、页面 2KB。
      - 发指令:Keil 把 FLM 的代码和地址信息打包,通过调试器协议(J-Link 协议或 CMSIS-DAP 协议)甩给调试器,说:“兄弟,把这算法塞到 SRAM 里去!”
      - 管全局:Keil 还得管整个下载流程:先加载 FLM 算法,再调用算法的函数(比如擦扇区、写数据),最后把用户代码刷进 Flash。
      Keil 就像个“导演”,不亲自干活,但得把任务分配好。

3.1.2 调试器:勤劳的搬运工
      调试器(J-Link 或 DAPLink)是干活的“搬运工”,负责把 FLM 算法塞进 SRAM,还要让它跑起来:
      - J-Link
        - 软件端:J-Link 软件(J-Link DLL)接到 Keil 的指令,拿着 FLM 算法的代码和 SRAM 地址(比如`0x20000000`)。
        - 硬件端:J-Link 的固件通过 SWD/JTAG 接口,直接把算法代码写到 MCU 的 SRAM 里。SWD 就用两条线(SWDIO 和 SWCLK),效率高得很。
        - 启动:写完后,J-Link 再把 MCU 的程序计数器(PC)设到入口地址(比如`0x20000004`),通过调试寄存器(DHCSR)让 CPU 跑起来。
        - 优点:J-Link 速度快(SWD 可达 50MHz),跟 Keil 配合得像老搭档,日志也详细(J-Link Commander 能告诉你每一步干了啥)。
      - DAPLink
        - 软件端:DAPLink 靠主机端的工具(比如 pyOCD 或 Keil 的 CMSIS-DAP 驱动)来解析 FLM 文件,生成指令。
        - 硬件端:DAPLink 的固件(跑在开发板的次级 MCU 上,比如 Cortex-M0)通过 CMSIS-DAP 协议,把 FLM 算法写到 SRAM。
        - 启动:跟 J-Link 一样,DAPLink 设好 PC(比如`0x20000004`),让 CPU 跑起来。
        - 特点:DAPLink 速度慢点(SWD 一般 1-10MHz),但便宜,适合 DIY 小伙伴。

3.1.3 目标 MCU:干活的主角
      MCU 是 FLM 算法的“舞台”:
      - SRAM 存货:MCU 的 SRAM 接到调试器送来的 FLM 算法代码,存在指定地址(比如`0x20000000`)。SRAM 快,写个 4KB 的算法分分钟搞定。
      - 跑代码:调试器把 PC 设好(比如`0x20000004`),CPU 从暂停(halt)状态切到运行(run)状态,从 SRAM 里取指令,开始干活。
      - 刷 Flash:FLM 算法跑起来后,直接搞 Flash 控制器的寄存器,擦扇区、写数据、校验啥的,忙得不亦乐乎。

      图片 4:FLM 算法加载流程
97101746ccae37f81841722b45429c71

3.2 为啥代码里找不到 SRAM 地址?
      好多小伙伴翻 FLM 工程的 C 代码,愣是找不到`0x20000000`这样的地址,为啥?答案藏在这些地方:
      - 链接脚本:FLM 工程里有个链接脚本(Keil 用`.sct`,GNU 用`.ld`),指定了算法代码的“住址”。比如:
        - 代码加载到 SRAM 的`0x20000000`,占 4KB。
        - 入口地址是`0x20000004`(ARM Cortex-M 的 Thumb 指令得用奇数地址)。
      - FLM 元数据:编译好的 FLM 文件里,元数据明确说了:
        -`AlgoRamStart`:SRAM 起始地址(比如`0x20000000`)。
        -`AlgoRamSize`:占多大地方(比如`0x1000`,也就是 4KB)。
        -`EntryPoint`:从哪儿开始跑(比如`0x20000004`)。
      - 厂商的安排:MCU 厂商做 FLM 文件时,参考数据手册的内存地图,挑个安全的 SRAM 地址。
      - 编译过程:Keil 的编译器和链接器把 C 代码和链接脚本“捏”成 FLM 文件,地址信息直接嵌到元数据里。你看 C 代码没地址,是因为这活儿都让链接脚本干了。

      图片 5:SRAM 地址的“安全地带”
2b16a6071f52594c519039104a161284

3.3 入口地址和跳转咋搞?
      FLM 文件不光说了 SRAM 地址,还指定了入口地址(`EntryPoint`,比如`0x20000004`),这是代码跑起来的“起跑线”。跳转过程是这样的:
      - 设 PC:调试器通过 SWD/JTAG 搞 MCU 的调试端口(Debug Port, DP),把 PC 寄存器设到入口地址(比如`0x20000004`)。这得用 DCRSR 寄存器来写。
      - 配寄存器:调试器可能还得设下堆栈指针(SP,比如`0x20001000`)和其他寄存器(R0-R3),让算法跑得顺顺当当。
      - 跑起来:调试器通过 DHCSR 寄存器把 MCU 从“暂停”切到“跑”,CPU 就从 SRAM 里取指令,开始执行 FLM 算法。
      - 干活:FLM 算法跑起来后,调试器通过函数表调用它的接口(比如擦扇区的`EraseSector`、写数据的`ProgramPage`),把用户代码刷进 Flash。

四、深挖 FLM 算法的底层原理:硬核来了!
      好了,前面聊了 FLM 是啥、为啥用 SRAM、咋加载和跑起来,现在咱们来点硬核的,深入扒一扒 FLM 算法的底层机制,从编译生成到寄存器操作,再到性能优化。

4.1 FLM 文件咋生成的?
      FLM 文件不是凭空冒出来的,它得经过编译和打包,过程有点复杂:
      - 写代码:FLM 工程的源代码(一般是 C 或汇编)是核心,负责实现 Flash 编程的逻辑。比如:
        - 解锁 Flash:往 KEYR 寄存器写特定值(比如 APM32F4 要写`0x45670123`和`0xCDEF89AB`)。
        - 擦扇区:设 CR 寄存器的 ERASE 位,指定扇区地址。
        - 写数据:循环把数据写到 Flash 的页面,每次写完查 SR 寄存器的状态。
        - 这些代码得对 MCU 的 Flash 控制器了如指掌,比如寄存器地址、时序要求。
      - 链接脚本:FLM 工程有个链接脚本(Keil 用`.sct`,GNU 用`.ld`),定好代码的“住址”。比如:
        - 算法代码放 SRAM 的`0x20000000`,占 4KB。
        - 入口地址设为`0x20000004`(Thumb 指令要求奇数地址)。
        - 链接脚本还得保证代码对齐,避开 SRAM 的“雷区”(比如用户代码的地儿)。
      - 编译打包:Keil 的编译器(比如 ARMCC 或 ARMClang)把 C/汇编代码编译成二进制,链接器按脚本生成 FLM 文件,顺手把 SRAM 地址、入口地址、Flash 参数塞进元数据。
      - 元数据结构:FLM 文件的头部是个结构化数据块,包含:
        - `AlgoRamStart`:SRAM 起始地址(比如`0x20000000`)。
        - `AlgoRamSize`:占多大空间(比如`0x1000`)。
        - `EntryPoint`:入口地址(比如`0x20000004`)。
        - `DevInfo`:Flash 参数,比如基地址`0x08000000`、页面大小 2KB。
        - 这些元数据是 Keil 和调试器的“导航图”,告诉它们算法咋加载、咋跑。
      再提一下哈,为啥源代码里看不到 SRAM 地址?因为地址是链接脚本和元数据的事儿,C 代码只管逻辑,地址全靠编译器和链接器搞定。

4.2 SWD/JTAG 接口:调试器的“魔法通道”
      J-Link 和 DAPLink 靠 SWD(Serial Wire Debug)或 JTAG 接口跟 MCU 聊天,加载 FLM 算法全靠这俩通道:
      - 内存写入:调试器通过 SWD/JTAG 访问 MCU 的内存接口(通常是 AHB 或 APB 总线),把 FLM 算法写到 SRAM(比如`0x20000000`)。
        - SWD 用两条线(SWDIO 和 SWCLK),简单高效,速度可达 50MHz(J-Link)。
        - JTAG 用四条线(TCK、TMS、TDI、TDO),老派但可靠,适合复杂场景。
      - 寄存器操作:调试器通过调试端口(Debug Port, DP)和访问端口(Access Port, AP)搞寄存器:
        - 设 PC:用 DCRSR 寄存器把 PC 写成入口地址(比如`0x20000004`)。
        - 设 SP:堆栈指针(SP)可能设到 SRAM 的高地址(比如`0x20001000`),保证算法跑得稳。
        - 控制 CPU:用 DHCSR 寄存器把 CPU 从 halt 切到 run,启动算法。
      - 调试模式:MCU 在调试模式下暂停(halt),调试器可以随便折腾内存和寄存器,干完活再让 CPU 跑起来。
      SWD/JTAG 是调试器的“魔法通道”,让 FLM 算法从 PC 到 SRAM,再到跑起来,全程无缝衔接。

      图片 6:SWD/JTAG 的“魔法通道”
a20661404dc33187595088f5b294c0c0

4.3 FLM 算法的“内功心法”
      FLM 算法跑起来后,直接跟 Flash 控制器的寄存器“过招”,干这些活:
      - 初始化(Init)
        - 解锁 Flash:比如 APM32F4 要往 KEYR 寄存器写`0x45670123`和`0xCDEF89AB`,解开 Flash 的“锁”。
        - 设参数:调 Flash 控制器的时钟(FLASH_ACR 寄存器)、电压、模式,保证后续操作不出岔子。
      - 擦扇区(EraseSector)
        - 往 CR 寄存器写 ERASE 命令,指定扇区地址(比如`0x08004000`)。
        - 盯着 SR 寄存器的 BSY 位,等擦除完成(可能要 50ms)。
        - 检查错误:比如看 WRPERR(写保护错误)或 PGERR(编程错误)位。
      - 写数据(ProgramPage)
        - 把用户代码按页面(比如 2KB)写进 Flash,每次写完查 SR 寄存器的 EOP(操作结束)位。
        - 循环写:一般是 32 位或 64 位对齐写,效率高点。
      - 校验(Verify)
        - 读 Flash 的数据,跟原数据比对,确认没写错。
        - 可能用 CRC 或校验和,确保数据靠谱。
      - 错误处理:FLM 算法得有点“智商”,比如检测 Flash 控制器的错误标志(PGERR、WRPERR),返回给调试器,报个错。
      这些操作全靠 FLM 算法直接戳 Flash 控制器的寄存器,效率高、针对性强。

      图片 7:FLM 算法的“内功心法”
909a2b7344d56e0dd67ff416143f43dd

4.4 SRAM 地址冲突:隐藏的“雷区”
      FLM 算法用 SRAM 地址得小心,别跟用户代码“抢地盘”:
      - 用户代码的地儿:用户程序可能在 SRAM 里放堆栈、全局变量、缓冲区。比如 APM32F4 的用户代码常从`0x20010000`开始用。
      - 中断向量表:Cortex-M 核的中断向量表可能也在 SRAM(比如`0x20000000`),FLM 得避开。
      - 厂商的招:FLM 算法选 SRAM 低地址(比如`0x20000000`),用户代码用高地址,分开走,互不干扰。
      - 风险:要是地址重了,可能数据被覆盖,程序崩了。比如 FLM 算法占了`0x20000000-0x20001000`,用户代码也用这块,堆栈就废了。
      - 解法:开发自定义 FLM 时,查数据手册的内存地图,挑安全地址。厂商的 FLM 一般都考虑好了这点。

      图片 8:地址冲突的“雷区”示意图
8fd060a7e09760e61031c5e751922267

4.5 性能优化:让刷代码更快点
      FLM 算法的效率直接影响刷代码的速度,几个关键点:
      - SRAM 快:SRAM 访问只要 1-2 个时钟周期,跑算法效率高。
      - 调试器速度:J-Link 的 SWD 最高 50MHz,DAPLink 才 1-10MHz,J-Link 刷得更快。
      - 算法优化
        - 批量写:一次写 2KB 页面,比多次写 256 字节块省时间。
        - 少轮询:优化 FLM 算法,减少查 SR 寄存器 BSY 位的次数。
        - 用缓存:有些 MCU 的 Flash 控制器支持缓存(比如 APM32F4 的 FLASH_ACR),FLM 算法能用上,写得更快。
      - MCU 硬件:Flash 控制器的性能(比如 APM32F4 擦扇区要 50ms)是瓶颈,FLM 得调好参数(比如 FLASH_ACR 的时钟设置)。

      图片 9:性能优化的“加速器”
de072957e5e2bc5f7f3890d4b852bcde

五、总结:FLM 算法的“前世今生”
      FLM 下载算法是 Keil MDK 刷代码的“幕后大佬”,从存储到运行,全程靠团队配合:
      - 是啥:FLM 文件是个二进制“黑盒”,装着 Flash 编程的算法代码和元数据,告诉调试器咋刷 Flash。
      - 为啥用 SRAM:Flash 擦除时不能跑代码,速度还慢;调试器存不下 FLM;SRAM 快、灵活、用完就丢,完美!
      - 咋干的:Keil 读 FLM 文件,调试器(J-Link 或 DAPLink)把算法塞到 SRAM,设好 PC 让它跑,搞定 Flash 擦写。
      - 硬核咋来:FLM 从源代码到二进制,靠链接脚本和元数据定地址;SWD/JTAG 负责内存和寄存器操作;算法直接戳 Flash 控制器,效率拉满。

      图片 10:整体流程的“大合照”
ea2e1311a3a2619c9076f323c7b70a1e
      这篇从 FLM 是啥开始,讲到为啥选 SRAM,再到咋加载、咋跑,最后深挖编译、寄存器、性能优化的硬核细节,层层递进。希望大家看完后,对 FLM 算法不再懵逼,刷代码更有底气!有啥具体问题,欢迎留言与交流!
      最后,附一个工具哈,一个flm文件查看的工具,一些大佬做的,网上也有哈,我这边也放在这里,有需要的可以下载。

flash算法提取器.zip (48.77 KB, 下载次数: 10)

效果:
a6b16de7953a89b9d92001cbbeed22b1

发表于 2025-8-7 21:08 | 显示全部楼层
我一直以后jtag是自己通过指令来完成数据的下载过程呢!
和着,仅是通过指令把这个loader加载到ram,然后,再跑具体的算法。
发表于 2025-8-8 10:04 | 显示全部楼层
好文,点赞
发表于 2025-8-8 10:25 | 显示全部楼层
好东西,学习了
发表于 2025-8-8 10:58 | 显示全部楼层
不错!讲得非常详细,看完后解除了一些疑惑清楚了下载代码的流程
发表于 2025-8-8 13:26 | 显示全部楼层
FLM文件的格式就是ELF格式的,可以用命令直接导出list文件吧。
 楼主| 发表于 2025-8-8 13:58 | 显示全部楼层
William1994 发表于 2025-8-8 13:26
FLM文件的格式就是ELF格式的,可以用命令直接导出list文件吧。

是的,FLM 文件的本质就是编译后代码,内部包含可执行的算法,能被反汇编。
发表于 2025-8-8 14:24 | 显示全部楼层
学习学习
您需要登录后才可以回帖 登录 | 注册

本版积分规则

59

主题

104

帖子

16

粉丝
快速回复 返回顶部 返回列表