本文面向已经懂得软件基本操作的职业老手,如果是未使用过该软件的小鲜肉,请移步基础篇。这里以STM32芯片为例对工具进行讲解,其他品牌的芯片在工程配置上可能存在差异。
Keil提供了包括C编译器、宏汇编、链接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(μVision)将这些部分组合在一起。
目前软件对中文的支持不友好,不建议安装网上的一些汉化包之类的。另外建立的工程文件路径也尽量不要存在中文,否则可能会出现一些异常。
演示版本:5.24a
RTX(Real Time eXecutive)是ARM公司针对ARM7,ARM9,cortex-m内核推出的一款嵌入式实时操作系统。RTX的源码跟Keil-MDK绑定在一起,安装了Keil-MDK之后,可以在 Keil\ARM\RL\RTX\SRC文件夹下找到源码。
所以在Keil上移植RTX操作系统十分方便。
第一步此选项选择"RTX kernel"。
第二步添加RTX系统的配置文件,配置文件在MDK的安装目录C:\Keil_v474\ARM\RL\RTX\Config下面,文件名RTX_Conf_CM.c
注意:工程里面不能有SysTick,PendSV和SVC三个系统中断的使用,因为RTX系统要使用这三个中断。
其他的移植事项这里就不多赘述了,如果有兴趣,可以单独出一篇RTX的移植。
在"Code Generation"中的"ARM Compiler"下拉选项框中可以选择不同的编译器版本。选择不同编译器版本时,工程配置的一些选项会有相应的变化,这里我们一般默认选用"Use defalut compiler version 5"即可。如果是全新的工程,可以试下V6的编译器,速度更快,但缺点就是跟现在大部分主流工程不兼容,因为使用的编译器完全不一样。
在Xtal(MHz)后面可以填写当前使用的开发板上芯片系统使用的晶振频率。这个只会在仿真调试中使用,如果直接用开发板在线调试,这个可以不用管。
勾选"Use Cross-Module Optimization"选择跨模块优化,此选项可在编译链接后对文件链接再进一步进行优化,从而减少一些开销。选择此功能时,可能会导致编译时间变长,但同样的可以使得编译后所使用的空间减少。
勾选"Use MicroLIB"可选择使用标准缺省库,勾选这个会导致很多库函数用不了,但换来的是节省了大量的空间。
如果是M3、M4内核,且芯片硬件有浮点计算单元,可通过勾选"Floating Point Hardware"打开硬件浮点计算功能。
注意这里有IROM和ROM的区别,IROM是指片内集成的ROM(上面也有一行小字写了on-chip),也就是查芯片手册上规定好的内部Flash的地址段。先讲IROM,一般选好芯片后,工程会默认有一套配置,比如现在选的STM32F302RBTx,其片上Flash是0x8000000开始,大小是128K,也就是这里的0x20000字节。这前后有两个选项,“default"可以勾选启动时是否对此段ROM空间进行初始化。而"Startup"则可以勾选当前程序是要在哪个Flash段开始启动。
举个简单的例子,像正常的只用一段App程序的情况下,只要设置一段ROM即可,起始即为片内Flash起始地址,默认勾选"default”,也就是程序烧录时,会把此段Flash进行初始化,并且程序从此地址开始运行。那如果此时我有两段程序呢?也就是现在常用的一种方式,程序分两段,一段作为引导程序boot,另一段是实际运行的App程序,那么boot应设置在片内起始地址段,大小根据boot实际占用空间大小来定义。App接在boot地址段后面,此时"Startup"应勾选在boot段。
注意这里有IRAM和RAM的区别,IRAM是指片内集成的RAM(上面也有一行小字写了on-chip),也就是查芯片手册上规定好的内部ram的地址段。
注:对于ROM跟RAM的设置,光靠这个界面设置并不全面,最直观的就是这里IRAM/IROM只有两段,而STM32H7B0光IRAM就有三段,根本不足以设置。所以想要设置全面,应该使用.sct文件,这个后面会讲到。
在"System Viewer File"选项中勾选"Use Custom File",可以自主选择芯片的视图文件。现在国产化芯片越来越多,不同厂家芯片支持的视图可能不同。如果使用ST的芯片,这里不用改,使用默认文件即可。
在"Select Folder for Objects"里可以设置输出文件的路径,在"Name of Executable"后面可以设置输出的文件名。这个输出文件路径和文件名也是Keil工程烧录和调试获取文件的依据。
比如这里输出路径设置为/Out,文件名为TestPro,那烧录时,Keil会去查找当前工程路径下/Out路径下是否存在TestPro.axf这个文件,有就烧录,没有就报错。如果要使用.Hex文件烧录,则文件名这里填写TestPro.Hex。
注:调试只能使用.axf文件,因为.Hex文件不带调试信息。
勾选"Create HEX File"即可在编译后生成.hex文件。
当需要封装模块或打包SDK包时,可以勾选"Create Library"这个选项,该选项与"Create Executable"互斥,选择生成.lib文件而不是完整的可执行.axf文件。这种一般是用于提供二次开发的软件包使用。
勾选"Create Batch File"即可在编译后生成.bat的编译执行脚本,即可以不用打开Keil工程,只需要执行编译执行脚本即可编译工程软件。
勾选"Debug Infomation"可以选择是否生成调试信息,注意去掉此勾选项时,无法打断点调试。
勾选"Browse Infomation"可以选择是否生成浏览信息,有这个浏览信息时,可以在Keil里索引函数或变量的定义,调用等,没有这个信息就无法把这些信息关联起来。如果不用Keil作为代码编辑器的小伙伴,去掉这个勾选项,可以减少编译的时间。
Select Folder for Listings…:选择列表文件的输出路径。
Page Width:定义列表文件每行字符数量。
Page Length:定义列表文件每页字符数量。
这两个基本都用不着,按默认设置即可。
Assembler Listing: .\Listings*.lst:为汇编源文件创建列表文件,对应产生源文件名.lst 的文件。
Cross Reference:列出有关符号的交叉引用信息,包括它们的定义位置以及宏的内部和外部的使用位置。
C Compiler Listing: .\Listings*.txt:为 C 源文件创建列表文件,对应产生 源文件名.txt 的文件 和 源文件名.lst 的文件。
C Preprocessor Listing: .\Listings*.i:指示编译器生成预处理文件。 宏调用将被展开并且注释将被删除 对应产生 源文件名.i 的文件。
Linker Listing: .\Listings\TestPro.map:主要是用来生成代码详细信息的map文件,用于后面的代码分析。这里面有选项建议全部勾选上。
Memory Map:包含一个内存映射,其中包含镜像中每个加载区,执行区和输入节的地址和大小,包括调试和链接器生成的输入节。
Callgraph:以HTML格式创建函数的静态调用图文件。调用图给出了镜像中所有函数的定义和参考信息。
Symbols:列出本地,全局和链接器生成的符号以及符号值。
Cross Reference:列出输入节之间的所有交叉引用。
Size Info:给出镜像中每个输入对象和库成员的代码和数据(RO数据,RW数据,ZI数据和调试数据)大小的列表。
Totals Info:提供输入对象和库的代码和数据(RO数据,RW数据,ZI数据和调试数据)大小的总和。
Unused Sections Info:列出从镜像中删除的所有未使用的部分。
Veneers Info:提供链接器生成的Thumb/ARM胶合代码的详细信息。
Before Compile C/C++ File:编辑文件之前
Before Build/Rebuild:编译工程之前
After Build/Rebuild:编译工程之后
一般编译完会生成.axf文件,如果要生成.bin文件,可以在编译后调用keil安装路径下/ARM/ARMCC/bin/fromelf.exe这个工具,提取.axf文件里的.bin文件。为了把这个操作集成在Keil里,这里可以在"After Build/Rebuild"下面的"Run #1"里添加
$K/ARM/ARMCC/bin/fromelf --bin -o "[email protected]" "!L"
勾选前面的选项框就可以在编译后执行。有时候如果不想执行该命令,可以把勾选去掉。
另外"Before Compile C/C++ File"和"Before Build/Rebuild"这两个也同理,只是执行脚本命令的时间不同而已,这个根据实际想要的效果来定。因为这里只有两个选项,所以如果要执行的脚本有很多,建议自己在外面写个批处理调用其他脚本,然后这里只调用那个批处理即可。
常用的几个语法如下:
$:扩展为指定文件的路径名
@ :表示 Output -> Name of Exectable:定义的工程名,比如test1
!:表示当前目录下的扩展路径
!L:表示编译(Build)后,就是 .\obj\xx.axf文件
K:keil develop chaintool 工具链(fromelf.exe)
L:Linker output file,比如工程名为test1,L.bin 编译后,生成的就是最终的test1.bin文件
$K:表示当前Keil安装的根目录
$L:是指axf的文件路径,不含文件名。
@L:是指axf的文件名,不含axf的后缀。
需要知道所有用法的,可以参考官方手册http://www.keil.com/support/man/docs/uv4/uv4_ut_keysequence.htm
Run “After Build” conditionally:After Build/Rebuild的执行条件。没整明白这个有什么用
Beep When Complete:编译完成发出声音。勾选时在编译完成时会响一下。
Start Debugging:启动调试程序。没整明白这个有什么用
Define:用于做一些工程全局宏定义。
注:在这里修改宏定义时,需要全编译才可生效,局部编译是不生效的哦
Execute-only Code:只生成执行代码,生成执行代码防止编译器生成任何数据访问代码部分。
Optimization:优化等级,这个会比较常用,当项目工程较大,对芯片空间比较吃紧时,可以考虑提升优化等级。ST的芯片这里有0~3,4个等级可选。
-O0应用最小优化:
大多数优化都被关闭,生成的代码具有最佳的调试视图。
-O1应用受限优化:
例如,删除未使用的内联函数和未使用的静态函数。在这个优化级别,编译器还应用自动优化,例如删除冗余代码和重新排序指令以避免互锁情况。生成的代码经过合理优化,具有良好的调试视图。
-O2应用高优化(这是默认设置):
在此级别应用的优化利用了ARM对处理器体系结构的深入了解,利用给定目标的特定于处理器的行为。它生成优化良好的代码,但有限调试视图。
-O3应用最积极的优化:
优化符合用户的-Ospace / -Otime选择。默认情况下,多文件编译时启用,这会导致更长的编译时间,但会提供最高级别的优化。
目前就使用经验来看,优化等级2节省的空间最多,具体原理还没去细究。
注:提升优化等级后,对代码的规范严格度提升,调试的友好程度会降低,请适当使用。
Optimize for Time:按时间性能优化,一般对代码执行时间比较敏感的,可以勾选这个选项,但勾选后为了提升时间性能,编译后可能会增加一部分空间占用。(鱼与熊掌不可兼得呀)
Split Load and Store Multiple:加载和储存多个分裂;非对其数据采用多次访问方式,当LMD/STM指令有4个以上产生时,则分裂LMD和指令,以减小中断延迟。
One ELF Section per Function:优化每一段函数ELF段(建议都勾选);每个函数都会产生一个ELF段,勾选该功能允许优化每个ELF,可以减少潜在的共享地址、数据和函数之间的字符串;直白说就是可以减少代码量ROM的大小(内存RAM不会减少)
Strict ANSI C:标准(严格)的ANSI C;即编译时严格按照标准的ANSI C进行检查。为了养成良好的编程习惯,写出更具移植性的代码,建议勾选。
Enum Container always int:枚举时成员变量总为int型。如果空间吃紧,这里就不建议勾选了。
Plain Char is Signed(看情况选择):字符类型为有符号变量。这个不得不说曾经踩过的坑,原本有个项目,从C51平台移植到ST的平台,发现怎么跑都不对劲,后面发现代码里很多8位的变量定义用的是char,在C51平台编译器编译成无符号类型,到ST平台就变成有符号类型。所以很多教材里说signed这个关键字可以省略,不适用于所有情况。为了可移植性,最好都写上,或者IDE里有类似这种选项时,要多留个心眼。
Read-Only Position Independent:为常量生成独立的代码空间;比如我们可以将字库变量定义为常量,勾选该功能后会将这些字库变量放在独立的代码空间中。
Read-Write Position Independent:为可读写代码生成独立的代码空间。
Warnings(建议All Warnings):No Warning:不会有警告提示和输出;All Warnings:所有警告提示和输出。建议选All Warnings,很多告警都不是空穴来风,检查下好点。
Thumb Mode(注意:在工程中该模式为默认,即无法选择):Thumb模式;指定设置文件或文件夹(组)为Thumb模式。
No Auto Includes(一般不勾选):不自动添加头文件;不勾选该项则编译器会在Keil安装路径下寻找工程中的 .h 文件。如果使用了标准库,勾选后Keil只会在工程路径下找库函数的头文件,如果没自己加进来一般是找不到的。
C99 Mode(看情况选择):C99模式,勾选选择启用C99标准,如不勾选,则按C89标准来。为了高移植性,不建议勾选。
Include Paths:包含路径,Keil编译时查找头文件,除了Keil本身安装路径下和自身工程路径,还有一个就是这里添加的路径。
Misc Controls:多功能控件,比如这里添加–gnu,可以使用gnu编程规范。
Compiler control string:编译器控制字符串,这个只是用来看当前的一些编译器设置,通过上面不同的勾选设置,这里会有不同的显示。如果没有Keil这种界面化工具,自己想要给编译器设置,就可以使用该窗口中的这些指令。
这一部分基本可以参考上文C/C++的设置,只不是这里是对汇编进行设置。
Conditional Assembly Control Symbols(有条件的装配控制符号)
Define:定义,指定汇编条件。
Language/Code Generation(语言代码生成)
Read-Only Position Independent:为常量生成独立的代码空间。
Read-Write Position Independent:为可读写代码生成独立的代码空间。
Thurmb Mode:Thumb模式;指定设置文件或文件夹(组)为Thumb模式。
No Warnings:无警告,勾选后不会有warning警告提示。
Split Load and Store Multiple:加载和存储多个分裂。
Execute-only Code:只生成执行代码。
No Auto Includes:不自动添加头文件(一般不勾选)。
Include Paths:头文件包含路径。
Misc Controls:多功能控件。
Assembler control string:编译器控制字符串。
Use Memory Layout from Target Dialog:使用分散文件加载对话框Target页面,这个需要配置"Scatter File"一起使用。当勾选时,其ROM和RAM的设置使用的是前文提到的Target里ROM、RAM的设置。当不勾选时,需要在Scatter File里打开对应的sct文件进行编辑。
Make RW Sections Position Independent:使RW段独立。
启用时:变量区域(包含RW和ZI)具有独立地址。
禁用时:变量区域(包含RW和ZI)位于绝对的内存地址。
Make RO Sections Position Independent:使RO段独立。
启用时:常量和代码区域(RO)具有独立地址。
禁用时:常量和代码区域(RO)位于绝对的内存地址。
一般这两项都是禁用状态,即程序所有编译出来的函数、变量等,都使用绝对地址,在Map文件中查看到的都是一个绝对地址,烧入板子中即可使用。那什么时候会把它开启呢?当有需要用到多个App,且App起始地址不固定时,就要使用此功能了。这个有兴趣可以单独开一篇详细讨论下。
Don’t Search Standard Libraries:不搜索标准库。
Report ‘might fail’ Conditions as Errors:报告’might fail’条件认为是错误。
X/O Base:X/O基地址
R/O Base:R/O基地址
R/W Base:R/W基地址
disable Warnings:禁止告警命令
Misc controls:多功能控件。
Linker control string:链接器控制字符串。
通过单选"Use Simulator"和"Use XXX"选择是用模拟仿真还是在线仿真
Use ST-Link Debugger:选择烧录器类型
Load Application at Startup:从启动文件开始加载。不勾选时,在进入调试时,不会重新从启动开始执行,但不勾选时,需要手动添加.ini文件,把.axf的调试信息放到Keil里,不然进入调试时无法打断点,也无法追踪到当前程序位置。这点在网上查“如何不复位进入调试”很多会提到这个勾选项,但很少有提及这个.ini的事情,有也是一带而过。
Initlalization File:初始化文件,承接上文,只要新建一个XXX.ini文件(文件名随意),点击…按钮,添加该文件,点旁边的"Edit"按钮,在文件中添加 “LOAD %L INCREMENTAL” 这一句即可。
LOAD %L INCREMENTAL
Run to main():跑进main函数,进入调试后,会在main里停止,相当于是在main的第一行打了第一个断点。如果不勾选时,一进入调试就全速跑。
使用上一次调试过程对Breakpoints,Watchpoints,Memory Display和Toolbox(如果这些项被选中的话)
Breakpoints:断点。
Watch Windows:变量调试窗口。
Memory Display:查看内存的窗口。
Toolbox:工具栏。
System Viewer:系统视图。
Driver DLL:驱动动态库文件,后面Parameter是其对应参数。
Dialog DLL:会话框动态库文件,后面Parameter是其对应参数。
这些是仿真的时候需要用到的动态库,一般不用修改,使用默认值就行,这些动态库在Keil的安装路径下了可以找得到。
Unit:当前连接的烧录器设备,当同时连有多个设备时,这里可以切换选择。如果这里没有可选设备,说明当前电脑未识别到烧录器设备。
Serial:设备
Version FW:固件版本
HW:硬件版本号
Port :端口类型,可以选择SW或JTAG接口,如果用的是Nucleo开发板,这里选SW接口。
Clock:时钟设置,可以设置调试的速度。
Req:请求频率
Selected:实际频率
连接跟复位设置(Connect & Reset Options)
Connect:连接设置,Normal
Reset:复位设置
Reset after Connect:连接后复位,不勾选时可以在进入调试时不中断当前设备运行。
缓存设置(Cache Options)
Cache Code:缓存代码,通知调试器已经下载的程序代码不会改变,选中的话uVision将不会从目标系统读取程序代码。
Cache Memory:缓存内存,决定调试程序期间程序停止运行的时候,是否更新存储器显示。
下载设置(Download Options)
Verify Code Download:下载时检验代码。比较目标存储器和调试器上的应用程序的内容。
Download to Flash:下载至Flash。将代码下载到所有的存储器区域,如果不选中,调试器不会把代码下载到Flash Download Setup中指定的存储器地址范围。
SWDIO:通过SWD接口连接的设备列表,其中IDCODE为连接的设备ID,Device Name为连接的设备名称。如果当前烧录器跟芯片之间没有正常连接,此处不显示设备名称。
Core Clock:核心时钟频率。设置跟当前板子相同的时钟频率,可以在调试时按实际运行时间进行追踪调试。
Trace Enable:使能追踪功能。
Erase Full Chip:擦除整片
Erase Sectors:擦除部分
Do not Erase:不擦除
勾选Erase Full Chip时,每次下载时,都会对整片Flash进行擦除操作。勾选Erase Sectors时,下载时只会擦除使用到的扇区。勾选Do not Erase时,则下载时不擦除原本代码。
Program:烧录
Verify:校验
Reset and Run:复位并运行
勾选Program时,下载时才会把代码写入Flash,否则不写入。勾选Verify时,则在烧录代码后,对代码进行校验。某些场合下不能检验,比如代码段跟数据段分开下载,代码里不包含数据部分,而工程里配置的代码段又包含数据段时,此时如果进行校验,可能会因为数据内容不一致导致校验失败。勾选Reset and Run时,则在下载完成后立即复位运行代码,不勾选时则需要手动复位运行。
RAM for Algorithm:给烧录算法的RAM空间,Start和Size分别设置对应Ram空间的起始地址和大小,这个一般选择完芯片后按默认就行,不用修改,如果有需要直接烧写的片外Flash的,可能需要自己写烧写算法的,此时就需要关注这个Ram空间是否容得下自己编写的烧录算法大小,需要做适当的调整。
Programming Algorithm:烧录算法选择,一般选择完芯片后,这里都会自动选择对应的烧录算法,如果不显示则需要手动添加,不然会导致烧录失败。如果是使用国产芯片,也需要手动添加烧录算法。添加方式很简单,把对应的算法文件(后缀是FLM)放到Keil安装根目录Keil_v5/ARM/Flash路径下,点Add按钮,选择对应的文件即可。
基本设置跟在线是一样的,多了一个"Limit Speed to Real-Time"的选项,意思是把速度限制到实际时间。但Keil怎么知道实际速度是怎么样的呢?所以这里还需要设置一个运行频率,即前文说到,在Target里有个频率设置。勾选此选项后,在离线仿真时,代码执行速度就是按设定的运行频率来跑,接近实际板子的速度。如果不勾选,那就直接起飞了(按电脑频率来跑,有多快跑多快)。
Use Target Driver for Flash Programming:使用跟调试一致的烧录器进行Flash下载。
Use Debug Driver:使用调试设备,即下载和调试使用同一种烧录器设备。
Update Target before Debugging:在调试前更新代码,勾选后一般是只有在刚打开工程或编译后,第一次进入调试时,会把当前代码烧录进目标板再进行调试。不勾选则进入调试时不更新代码。
Use External Tool for Flash Programming:使用第三方的工具进行Flash下载。
Command:要使用的Flash烧写工具的命令文件(通常是一个.exe文件)。
Arguments:传递给Flash烧写工具的参数。
Run Independent:当选中的时候,uVision不等待Flash烧写完成。不选中的时候uVision要等待Flash烧写完成并且在输出窗口显示烧写结果。
通过在编译过程中调用FCARM,输入配置映像文件处理(FCARM)的选项。这将把镜像文件转换成c源代码。其中Output File为输出的c文件名,Add Output File to Group这个默认不需要修改,Image Files Root Folder填写需要转换的镜像文件
STM32、RTX、FPU、SVD、Hex、Bin、axf、Lib、sct、烧录算法、启动文件、Map文件。
相关文章:Keil5软件使用-基础使用篇、Keil5软件使用-进阶调试篇、Keil软件包-知识宝藏库