第六章新建MDK工程
本教程所有例程都是在MDK下编写、编译和调试的,因此首先要学习的就是如何新建MDK工程,本章就来讲解一下最基本的MDK工程创建方法,工程创建成功以后用汇编语言编写一个最简单的点灯程序,测试工程创建是否正确。
本章将分为如下几个小节:
6.1、新建MDK工程;
6.2、工程测试;
6.3、程序编写与编译;
6.4、代码调试验证;
6.1 新建MDK工程
不管你以前有没有学习过STM32单片机,会不会使用MDK,此时请务必做一次本章实验,因为会有一些新的、很重要的知识点!
首先创建一个文件夹来存放例程工程,名字以及位置自定义即可,这里我在桌面上新建了一个名为“汇编LED灯实验”的文件夹。打开Keil uVision5,点击菜单Project ->New Uvision Project,如图6.1.1所示。
图6.1.1新建工程
然后弹出工程命名和保存的操作窗口,工程名字我们取:atk_mp1_m4,然后将工程保存到刚刚新建的最后点击保存即可。具体操作窗口如图6.1.2所示。
图6.1.2工程命名和保存
接下来会弹出一个选择Device的界面,就是选择我们的芯片设备型号,大家根据自己使用的芯片型号依次选择即可。STM32MP157开发板的芯片型号是:STM32MP157DAA1,所以我们选择:STMicroelectronicsàSTM32MP1 SeriesàSTM32MP157àSTM32MP157DAAxàSTM32MP157DAAx:Cortex-M4(如果使用的是其他芯片,选择相应的型号就可以了),如图6.1.3所示。
图6.1.3选择芯片型号
特别注意:一定要安装对应的器件支持包(即pack包)才会显示这些内容哦,如果没得选择,请关闭MDK,然后安装光盘:3、软件\MDK5\Keil.STM32MP1xx_DFP.1.3.0.pack这个安装包后重试。
点击OK后,弹出Manage Run-Time Environment对话框,如图6.1.4所示:
图6.1.4界面
在这个界面,我们可以添加自己需要的组件,从而方便构建开发环境,不过这里我们不需要。我们直接点击Cancel即可。这样就得到了我们的初步工程,如图6.1.5所示。
图6.1.5初步创建好的工程
这只是一个最基本的工程框架,此时的工程文件夹“汇编LED灯实验”中的内容如图6.1.6所示:
图6.1.6工程文件夹MDK-ARM 目录
这里我们说明一下,atk_mp1_m4.uvprojx是工程文件,非常关键,不能删除,MDK5.31生成的工程文件是以.uvprojx为后缀,如果要打开工程,双击此文件即可打开工程。DebugConfig,Listings和Objects三个文件夹是MDK自动生成的文件夹,其中DebugConfig文件夹用于存储一些调试配置文件,Listings和Objects文件夹用来存储MDK编译过程的一些中间文件。
6.2 新建程序和编写文件
工程创建好以后就是编写程序了,首先要创建一个代码编写文件,点击File->New,如图6.2.1所示:
图6.2.1 新建文件
点击以后就会在MDK右侧的编辑区新建一个默认名为“Text1”的代码编辑文件,如图6.2.2所示:
图6.2.2 新创建好的文件
此时“Text1”这个文件还没有保存到“汇编LED灯实验”里面,鼠标放到图6.2.2中“Text1”的代码编辑区,然后按下键盘的CTRL+C组合键来保存文件(或者点击MDK的File->Save)。此时会弹出文件保存对话框,这里我们要创建一个汇编文件,因此文件名后缀要为.s,文件名为:startup_stm32mp15xx.s,文件保存到我们前面创建的“汇编LED灯实验”文件夹里面,如图6.2.3所示:
图6.2.3 保存文件
用同样的方法创建一个名为:main.s的汇编文件,完成以后“汇编LED灯实验”文件夹如图6.2.4所示:
图6.2.4 新建文件以后的工程文件夹
此时main.s和startup_stm32mp157xx.s这两个汇编文件只是存在于工程文件夹中,但是还并没有添加到工程里面,所以接下来就是将这两个文件添加到工程里面。在MDK的Project区,鼠标放到Target1->Source Group 1上,然后点击右键,弹出如图6.2.5所示列表:
图6.2.5 添加文件到工程中
点击图6.2.5中的“Add Existing Files to Group ‘Source Group 1’…”,也就是添加现有文件到工程中,此时会弹开对话框,对话框里面的“文件类型”默认是“C Source file(*.c)”,也就是默认只能添加C文件,不能添加.s汇编文件。所以我们要设置“文件类型”为“All files (*.*)”,也就是所有文件,如图6.2.6所示:
图6.2.6 添加文件选择
选中图6.2.6中的“startup_stm32mp15xx.s”,然后点击“Add”按钮即可将此文件添加到MDK工程中。同样的方法,main.s也添加到MDK工程中,添加完成以后的MDK工程如图6.2.7所示:
图6.2.7 创建好的MDK工程
至此,MDK工程创建好了,接下来就是在相应的文件中编写代码。
6.3 程序编写与编译
6.3.1 程序编写
由于我们还没有学习过STM32MP157,现在还不能写程序,因此这里直接参考开发板的“实验0 汇编LED灯实验”,路径:开发板光盘à1、程序源码à3、M4裸机驱动例程MP157-M4 HAL库V1.1à实验0 汇编LED灯实验。在startup_stm32mp15xx.s中输入如下内容:
示例代码6.3.1.1中前面的序号是为了代码阅读方便后面添加的,大家在参考写程序的时候不要将这些序号写进去!
在main.s中输入如下内容:
6.3.2 设置分散加载文件
对于以前学习过STM32单片机的朋友来说这里可能会有疑问,程序编写好就可以编译了呀,为什么这里还要创建分散加载文件。分散加载文件也叫做链接脚本,用来描述程序在编译的时候应该怎么链接,比如代码部分应该链接到哪个地址范围?数据部分应该链接到哪个地址范围,甚至可以单独指定某一个.c或.s文件连接到哪个地址范围。以前STM32单片机不需要链接脚本,只需要直接在MDK上设置好ROM和RAM地址范围即可,以STM32F103为例,设置如图6.3.2.1所示:
图6.3.2.1 STM32F103 ROM和RAM设置
图6.3.2.1中设置了STM32F103的ROM起始地址为0X8000000,大小为0X80000,这就是STM32F103内部Flash地址范围;RAM起始地址为0X20000000,大小为0X1000,这就是STM32F103的内存RAM范围。此时MDK在编译的时候就会将代码从0X8000000这个地址空间开始存储,内存的话就会从0X20000000这个地方开始。
前面在5.3.1小节讲解STM32MP157的内存映射的时候说过,STM32MP157内部SRAM1~4是供M4内核使用的,可以用来作为ROM和RAM,这段内存起始地址为0X10000000,大小为384KB。那么我们可不可以按照6.3.2.1中的STM23F103那样直接配置ROM和RAM地址空间呢?事实上我们新建MDK工程的时候MDK默认已经这么分配了,如图6.3.2.2所示:
图6.3.2.2 STM32MP157 ROM和RAM默认分配
从图6.3.2.2可以看出,默认情况下MDK将0X10000000开始的128KB(0X20000)内存空间作为ROM使用,用来存放代码。将0X10020000开始的128KB(0X20000)作为RAM。
既然MDK默认已经设置好了ROM和RAM范围,为什么不能直接编译,需要另外创建分散加载文件,这不是多此一举吗?原因在于STM32MP157中M4内核的中断向量表要放到RETRAM区域,也就是0X00000000地址处,相当于第一行代码要放到0X00000000处,这个时候就涉及到将某个文件链接到指定地址,这个功能就需要借助分散加载文件,关于分散加载文件后面会详细讲解,这里大家知道有这个东西即可。
这里我们直接使用开发板例程里面的分散加载文件,找到“实验0 汇编LED灯实验”这个例程,将此例程中的stm32mp15xx_m4.sct这个文件复制到本例程中。设置MDK工程,使用这个分散加载文件,点击
,打开相应的配置界面,点击Linker标签,按照图6.3.2.3所示设置:
图6.3.2.3 链接脚本设置
图6.3.2.3中:
①、点击Linker标签,进行链接相关配置。
②、取消勾选“Use Memory Layout from Target Dialog”,不使用MDK默认的配置,也就是不使用图6.3.2.2中的链接配置,因为要使用我们自己创建的分散加载文件。
③、点击此按钮找到要使用的分散加载文件。
④、选择好的分散加载文件。
⑤、如果要编辑分散加载文件的话就直接点击“Edit”即可在MDK下编辑。
6.3.3 编译程序
程序和分散加载文件准备好以后就可以编译了,按照4.1小节讲解的方法编译工程,由于本章程序都是直接复制例程的,因此编译不会出错,结果如图6.3.3.1所示:
图6.3.3.1 编译结果
从图6.3.3.1可以看出,此时有0个错误(Error),3个警告(Warning),这三个警告可以忽略不计,如果编译有错误(Error)的话就自行检查错误。
6.4 代码调试验证
代码编译完成以后就可以进行调试验证了,因为是全新创建的工程,因此在调试验证之前需要对工程进行一些设置。点击
,打开配置项,点击Output选项,选择创建HEX文件文件,如图6.4.1所示:
图6.4.1 Output选项卡
虽然STM32MP157 M4内核用不到hex文件,但是这里还是选择上。继续点击“Debug”选项卡,根据自己的实际使用,选择调试器,比如我使用ST LINk,因此就选择ST-Link Debuger,如图6.4.2所示:
图6.4.2 Debug选项卡
图6.4.2中选择仿真器为“ST-Link Debugger”,然后勾选“Run to main()”,虽然本章节是汇编语言编写的,没有main函数,但是为了例程一致性,还是勾选上此选项。
点击图6.4.2中的“Settings”按钮,打开调试设置界面,设置ST LINK的一些参数,如图6.4.3所示:
图6.4.3 ST LINK模式设置
①、表示MDK找到了ST-LINK/V2仿真器。
②、设置接口方式,这里选择SW(比JTAG省IO)。
③、表示MDK通过仿真器的SW接口找到了目标芯片,ID为:0x6BA02477。如果这里显示:No target connected,则表示没找到任何器件,请检查仿真器和开发板连接是否正常?开发板是否供电了?如果一切都正常,但还是提示No target connected,点击图6.4.3中的“Pack”标签,如图6.4.4所示:
图6.4.4 Pack设置
勾选图6.4.4中的“Enable”,点击“确认”退出。然后重新点击“Debug”标签,查看图6.4.3中③的芯片ID有没有识别出来。识别出来以后就再重新点击“Pack”,然后取消图6.4.4中刚刚勾选的 “Enable”,否则无法仿真。
最后设置Utilities选项卡里面设置下载时的目标编程器,如图6.4.5所示:
图6.4.5 FLASH编程器选择
①、勾选“Use Debug Driver”,选择ST LINK来调试、下载。
②、“Update Target before Debuggin”顾名思义,就是在调试之前先将代码下载到目标器件中,由于STM32MP157 M4没有内部Flash,因此绝对不能勾选此选项!否则仿真就会失败,对于那些内置Flash的STM32单片机需要勾选此选项。
③、对于内置Flash的STM32单片机,还需要设置烧写算法,STM32MP157 M4内核不需要设置这一步。
到这里MDK就配置好了,接下来就可以仿真运行了。按照4.2.2小节讲的方法进行调试验证,选择全速运行,如果开发板上的红色LED灯闪烁的话就说明代码运行正常。一个完整的、简单的MDK工程创建就到此结束了,本章讲解的是最基本的MDK工程创建,后面学习到HAL库的时候就会接触到更加复杂的操作。
6.5 清理工程
编译的过程中会产生很多中间文件,如果我们要清除中间文件以及编译后生成的最终文件,可以选择MDK自带的清理工程选项,不过此选项清理的工程并不完全:
图6.5.1清理工程
或者可以使用通过批处理来实现,正点原子的源代码工程就是用批处理来清除的,该批处理文件keilkill.bat在我们实验工程的每个代码中:
图6.5.2正点原子提供的批处理文件
只要双击该文件,就可以把我们编译生成的所有文件删除。自己也可以修改批处理脚本keilkill.bat来选择删除哪些文件,如下:
以上脚本中是删掉哪些文件,*号是通配符,例如第1行,删掉所有.bak后缀的文件。两个冒号“::”表示注释该行,相当于C语言的“//”,被注释的行不会被执行,如果我们不想删除.axf文件,则把第18行用两个冒号注释掉即可。
::del *.axf /s