一、文档背景
Keil MDK在实际开发过程中,除了 GUI 操作,Keil 还支持命令行方式执行各种任务,如编译、链接、烧录、调试和工程管理等。命令行方式的优势在于能够与自动化构建系统、脚本工具(如 Batch、PowerShell、CMake)或 CI/CD(如 Jenkins、GitHub Actions)集成,实现无人值守的高效开发流程。
此外,通过Keil 命令行也能在资源受限或远程开发环境下(如Docker中)提供更灵活的控制方式。通过本文,可以掌握如何利用 Keil 命令行提高开发效率,实现基本的自动化构建和调试流程。如图1所示。

图1
亦或者,可以搭配第三方软件工具,比如:VS Code进行代码的编写,然后调试时,在VS Code的终端输入调试命令,来快速打开原生的KEIL进行调试,详情请见下方GIF_0。(注意:使用命令行调试,调试退出后,软件也会自动退出。)

二、KEIL的命令行使用
(1)、Keil MDK 的命令行工具通过 UV4.exe 提供,支持多种命令和选项,但是要想在CMD终端窗口中运行Keil的命令行语句,首先需要JNH官网为UV4.exe这个可执行程序提前设置好环境变量,否则JNH官网将无法在任意目录下使用Keil的命令行语句(不添加环境变量,就只可以在keil安装目录中的UV4文件夹下使用这些命令行语句),设置并添加环境变量的方法如图2所示:

图2
(2)接下来,是命令行的基本命令格式,如下代码块所示:

这个命令格式一共分为了4部分,逐个解析如下:
①UV4:在这里是命令的标识符;
②command:是后面表中列出的命令之一。(如 -b 构建、-c 清理)如果未指定命令,uVision 将以交互式构建模式(这里交互式构建模式的意思其实就是直接打开keil这个软件)打开项目文件。
③projectfile:是 uVision 项目文件的名称,带有 .uvprojx 扩展名;多项目文件的扩展名为 .uvmpw。如果未指定项目文件,uVision 将打开最近的项目。
④options:是用于指定目标名称或输出文件的附加参数。(如 -t 指定目标、-o 输出日志,后面也有一个对应的命令表)。
(3)command参数可以使用的命令选项:
命令 | 描述 |
-b | 功能:编译和构建当前目标(target),构建完成后自动退出。 应用场景:可用于自动化构建流程。例如,配合 CI/CD 工具(如 Jenkins)在每次代码提交后进行编译验证。 示例:UV4 -b PROJECT1.uvprojx |
-c | 功能:清除当前目标的构建产物。(其实就是清理Objects和Listings文件夹) 应用场景:清理旧文件,确保重新构建时没有残留文件的干扰。 示例:UV4 -c PROJECT1.uvprojx |
-cr | 功能:清理并重新构建 应用场景:清理完旧文件后,迅速进行新的构建用以调试等 示例:UV4 -cr PROJECT1.uvprojx |
-d | 功能:在调试模式下启动µVision。(调试还是要用IDE界面) 应用场景:将此命令与调试初始化文件一起使用以执行自动化测试过程。使用EXIT命令退出调试会话 。 示例:UV4 -d PROJECT1.uvprojx |
-f | 功能:下载程序到 Flash,并在下载完成后退出。 应用场景:生产线中的批量烧录,或开发中的快速固件烧写。 示例:UV4 -f PROJECT1.uvprojx |
-r | 功能:仅重新编译,并在构建过程完成后退出。 应用场景:修改某一模块后,用以验证程序是否有误 示例:UV4 -r PROJECT1.uvprojx |
-5 | 功能:将µVision 4 uvproj文件转换为µVision 5 uvprojx文件。该命令的唯一有效选项是-l,用于写入日志文件。 应用场景:转换旧项目到新格式,仅此而已。 示例:UV4 -5 myoldproject.uvproj -l log.txt 如果转换失败,将返回错误代码20。 |
-et | 功能:导出目标配置,将项目目标导出到<projectName>.<targetName>.cprj文件。使用选项-t targetname可以指定要导出的目标,否则将使用当前目标。请注意, 带有选项-t的-et命令不会更改项目中的当前目标配置。该命令不支持其他选项。 应用场景:方便、快速的去移植目标配置给其他的项目。比如跨团队共享配置,或作为备份模板。 示例:UV4 -et myProject.uvprojx 将myProject.uvprojx中的当前目标导出到myProject.<targetName>.cprj文件。 示例:UV4 -et myProject.uvprojx -t “my-target” 将myProject.uvprojx中的目标“ my-target”导出到myProject.my-target.cprj文件。 (注意:这个选项,没有被成功调用) |
-ep | 功能:将所有项目目标导出到相应的 <projectName>.<targetName>.cprj文件。 示例:UV4 -ep myProject.uvprojx (注意:这个选项,没有被成功调用) |
-X | 功能:在当前目标的输出文件夹中,生成预处理符号文件co-arm_<target_name >.h/hpp 。 示例:UV4 -X myProject.uvprojx UV4 -X myProject.uvprojx -T “Target 1” 请注意,生成过程可能需要一段时间。如果要查看进度,请使用uvision.com而不是uv4.exe。 (注意:这个选项,没有被成功调用) |
-X1 | 功能:在所有目标的输出文件夹中,生成预处理符号文件 co-arm_<target_name>.h/hpp 。 示例:UV4 -X1 myProject.uvprojx 请注意,生成过程可能需要一段时间。如果要查看进度,请使用uvision.com而不是uv4.exe。 (注意:这个选项,没有被成功调用) |
(4)、option参数可以使用的命令选项:
命令 | 描述 |
-j0 | 功能:隐藏 µVision GUI。消息将被抑制。此选项适用于批处理测试。 应用场景:脚本化操作,避免弹窗干扰。 示例:UV4 -j0 PROJECT1.uvprojx |
-i import_file.xml | 功能:使用 XML 文件中提供的数据创建新项目或更新现有项目。XML 文件需符合位于 ..UV4 目录下的 project_import.xsd 模式。使用此选项时,GUI 将自动隐藏。 示例: UV4 MyProject.uvprojx -i MyImport.xml (注意:这个选项,暂未经过尝试) |
-l logfile | 功能:将命令的输出保存到指定的日志文件中。 应用场景:方便随时查看命令的输出。 示例: UV4 -5 myoldproject.uvproj -l log.txt 如果转换失败,将返回错误代码 20。 |
-n device_name | 功能:使用指定的 device_name 创建新项目。使用此选项时,GUI 将自动隐藏。 应用场景:快速创建指定芯片的项目。 示例: UV4 MyProject.uvprojx -n Device1234 UV4 MyProject.uvprojx -i MyImport.xml -n Device5678 -t FlashDebug |
-np device_name | 功能:如果项目不存在,则使用指定的 device_name 创建新项目。如果项目已经存在,则更新所有目标的设备选择为指定的 device_name。使用此选项时,GUI 将自动隐藏。 应用场景:快速创建指定芯片的项目,或快速更新现有目标的芯片型号。 示例: UV4 MyProject.uvprojx -np Device1234 |
-o outputfile | 功能:指定输出日志文件。 应用场景:记录警告和错误,或者构建历史。 示例: UV4 -r PROJECT1.uvprojx -o "listmake.prn" UV4 -r "C:MyProjectsARMExample-mpw.uvmpw" -o "c:templog.txt" |
-q | 功能:重建多项目文件中所选的目标。确保每个目标有独立的对象输出文件夹。可通过菜单 Projects - Options for Target - Output - Select Folder for Objects 进行设置。 示例: UV4 -r "C:MyProjectsARMExample-mpw.uvmpwx" -q -o "c:templog.txt" (注意:这个选项,暂未经过尝试) |
-s port | 功能:启用 UV Socket 端口,并将其分配为指定的端口值。 示例: UV4 MyProject.uvprojx -s 4328 (注意:这个选项,暂未经过尝试) |
-t targetname | 功能: 指定目标的名称。如果未指定,则使用上一次已知的目标。 应用场景:多目标工程中选择特定构建。 示例: UV4 -r PROJECT1.uvprojx -t "MCB2100 Board" |
-x | 启用 DDE 模式并返回完整的命令输出。此选项仅能与 -d 命令一起使用。 (注意:这个选项,暂未经过尝试) |
-y | 启用 DDE 模式并仅返回命令确认。此选项仅能与 -d 命令一起使用。 (注意:这个选项,暂未经过尝试) |
-z | 功能:重建项目或多项目文件的所有目标。 应用场景:确保每个目标有独立的对象输出文件夹。可通过菜单 Projects - Options for Target - Output - Select Folder for Objects 进行设置。 示例: UV4 -b PROJECT1.uvproj -z -o "c:templog.txt" UV4 -b "C:MyProjectsARMExample-mpw.uvmpwx" -q -z -o "c:templog.txt" |
-sg | 功能:禁用来自 uvguix 文件的用户 GUI 布局。在整个会话期间将使用默认的编辑和调试模式窗口布局,并在关闭项目时不会将布局修改存储到 uvguix.<user> 文件中。 应用场景:适用于以批处理模式运行 µVision 时,避免对 uvguix 文件的非预期修改。 示例: UV4 -sg myProject.uvproj |
(5)
实战示例1:
UV4 -b "E:18、文档预研新建文件夹STM32_ProjectTest0102.uvprojx"
-b构建项目,如果项目里的c文件等没有改动,生成文件也不会改动。(注意,会弹一下keil软件然后立马关闭)如GIF_1所示:(因为没有需要构建的文件,所以很快,一闪而过)

实战示例2:
UV4 -r "E:18、文档预研新建文件夹STM32_ProjectTest0102.uvprojx"
-r 重构项目,所有的文件都会被重新构建一遍。(注意,会弹一下keil软件然后立马关闭)如GIF_2所示:(因为需要重新构建,所以会显示一堆正在编译的文件,现象较GIF_1更明显)

实战示例3:
UV4 -r "E:18、文档预研新建文件夹STM32_ProjectTest0102.uvprojx" -o "C:newtest.txt"
-r 重构项目,并且-o把构建输出的结果显示在txt文件中。(注意,会弹一下keil软件然后立马关闭)如GIF_3所示:(重新构建后,将构建窗口中的内容都输出到文本中进行记录,现象较GIF_2更明显)

实战示例4:
UV4 -j0 -sg -r "E:18、文档预研新建文件夹STM32_ProjectTest0102.uvprojx" -o "C:newtest.txt"
-j0隐藏µVision GUI界面,-r重构项目,并且不会弹keil软件(加不加-sg其实都没事,因为根本就没打开IDE),并且-o把构建输出的结果显示在txt文件中。如GIF_4所示:(重新构建后,将构建窗口中的内容都输出到文本中进行记录,且相比于GIF_3,不会再弹出µVision GUI界面,效果会更好一些)

实战示例5:
UV4 -d "E:18、文档预研新建文件夹STM32_ProjectTest0102.uvprojx"
-d是调试,其实这里有些失去了命令行的意义,因为终究还是打开了µVision GUI界面,但如果场景是搭配VS Code,那么确实可以在VS Code调一下该命令,借助原生IDE对内核进行调试,调试退出后原生IDE会自动关闭,也很省心,其实也可以。如GIF_5所示:

实战示例6:
UV4 -f "E:18、文档预研新建文件夹STM32_ProjectTest0102.uvprojx"
-f是烧录,预先配置好软件内的烧录选项,(或者搭配外部的批量烧录工具,进行固件的批量烧录);如GIF_6所示:

三、讨论分析
问:都有什么应用场景?
答:
①自动化编译与构建:在团队开发中,需要频繁编译代码并验证是否通过。这时,JNH官网就可以通过命令行工具,可以将构建过程集成到脚本中。
②批量处理与多项目管理:需要同时清理或构建多个项目或目标,如:同时编译 Debug 和 Release 版本,或者一次生成10个、甚至100个版本的固件(比如Flash烧写算法,就可以使用该命令行,一次性生成各个Flash大小的FLM文件,不必再逐个、按Flash大小、去生成)。
③在服务器上的Docker中使用,即使没有GUI界面,也可以依靠此命令行,完成工程的编译,缓解本地资源。
④批量烧录,在生产线上结合硬件,通过命令行批量烧录固件。
四、结论
Keil 命令行工具的核心价值,我觉得其实在于自动化和可集成性,如:①对于繁杂的大型项目,这无疑能提升效率,减少重复手动操作;②进行规模化处理,比如批量编译、测试或部署;③跨平台协作,在服务器或无 GUI 环境中运行。
掌握这些场景后,JNH官网可以根据实际需求,再进而去设计更高效的开发流程,甚至探索与其他工具(如静态分析工具、硬件测试框架)的深度集成,都是有一定可行性的路线。