搜索
bottom↓
回复: 0

《STM32MP1 M4裸机HAL库开发指南》第六章 新建MDK工程

[复制链接]

出0入234汤圆

发表于 2022-10-21 10:25:16 | 显示全部楼层 |阅读模式
本帖最后由 正点原子 于 2022-10-21 10:25 编辑

1)实验平台:正点原子STM32MP157开发板
2)购买链接:https://item.taobao.com/item.htm?&id=629270721801
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-318813-1-1.html
4)正点原子官方B站:https://space.bilibili.com/394620890
5)正点原子STM32MP157技术交流群:691905614 lQLPJxaFi2zaB4UWWrDAMgIsFEW2pwLb3abnwDMA_90_22.png
lQDPJxaFi2nfFizMjM0CbLCPlxn_FVheIQLb3aGrwFQA_620_140.jpg

lQLPJxaFi2nfFhLMkM0BXrDNvOUyeU_FPgLb3aGvQNIA_350_144.png


第六章 新建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所示。
第六章 新建MDK工程376.png

图6.1.1新建工程

然后弹出工程命名和保存的操作窗口,工程名字我们取:atk_mp1_m4,然后将工程保存到刚刚新建的最后点击保存即可。具体操作窗口如图6.1.2所示。
第六章 新建MDK工程464.png

图6.1.2工程命名和保存

接下来会弹出一个选择Device的界面,就是选择我们的芯片设备型号,大家根据自己使用的芯片型号依次选择即可。STM32MP157开发板的芯片型号是:STM32MP157DAA1,所以我们选择:STMicroelectronicsSTM32MP1 SeriesSTM32MP157STM32MP157DAAxSTM32MP157DAAx:Cortex-M4(如果使用的是其他芯片,选择相应的型号就可以了),如图6.1.3所示。
第六章 新建MDK工程697.png

图6.1.3选择芯片型号

特别注意:一定要安装对应的器件支持包(即pack包)才会显示这些内容哦,如果没得选择,请关闭MDK,然后安装光盘:3、软件\MDK5\Keil.STM32MP1xx_DFP.1.3.0.pack这个安装包后重试。
点击OK后,弹出Manage Run-Time Environment对话框,如图6.1.4所示:
第六章 新建MDK工程869.png

图6.1.4 Manage Run-Time Environment界面

在这个界面,我们可以添加自己需要的组件,从而方便构建开发环境,不过这里我们不需要。我们直接点击Cancel即可。这样就得到了我们的初步工程,如图6.1.5所示。
第六章 新建MDK工程989.png

图6.1.5 初步创建好的工程

这只是一个最基本的工程框架,此时的工程文件夹“汇编LED灯实验”中的内容如图6.1.6所示:
第六章 新建MDK工程1055.png

图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所示:
第六章 新建MDK工程1352.png

图6.2.1 新建文件

        点击以后就会在MDK右侧的编辑区新建一个默认名为“Text1”的代码编辑文件,如图6.2.2所示:
第六章 新建MDK工程1416.png

图6.2.2 新创建好的文件        

        此时“Text1”这个文件还没有保存到“汇编LED灯实验”里面,鼠标放到图6.2.2中“Text1”的代码编辑区,然后按下键盘的CTRL+C组合键来保存文件(或者点击MDK的File->Save)。此时会弹出文件保存对话框,这里我们要创建一个汇编文件,因此文件名后缀要为.s,文件名为:startup_stm32mp15xx.s,文件保存到我们前面创建的“汇编LED灯实验”文件夹里面,如图6.2.3所示:
第六章 新建MDK工程1639.png

图6.2.3 保存文件

        用同样的方法创建一个名为:main.s的汇编文件,完成以后“汇编LED灯实验”文件夹如图6.2.4所示:
第六章 新建MDK工程1707.png

图6.2.4 新建文件以后的工程文件夹

        此时main.s和startup_stm32mp157xx.s这两个汇编文件只是存在于工程文件夹中,但是还并没有添加到工程里面,所以接下来就是将这两个文件添加到工程里面。在MDK的Project区,鼠标放到Target1->Source Group 1上,然后点击右键,弹出如图6.2.5所示列表:
第六章 新建MDK工程1880.png

图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所示:
第六章 新建MDK工程2091.png

图6.2.6 添加文件选择

         选中图6.2.6中的“startup_stm32mp15xx.s”,然后点击“Add”按钮即可将此文件添加到MDK工程中。同样的方法,main.s也添加到MDK工程中,添加完成以后的MDK工程如图6.2.7所示:
第六章 新建MDK工程2216.png

图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 startup_stm32mp15xx.s文件内容
;**********************************************************************
;* @file                 : startup_stm32mp15xx.s
;* @author               : 正点原子Linux团队
;* @version              : V1.0
;* @date                  : 2020-05-03
;* @Description   : STM32MP1设备的中断向量表
;*                           本文件功能:
;*                     - 初始化SP
;*                     - STM32P1启动以后先执行Reset_Handler函数
;*                     - Reset_Handler函数里面跳转去运行Start函数
;* @license              : Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
;**********************************************************************

1  Stack_Size              EQU     0x00000400            ;栈大小为0X400,C语言运行要使用
2  
3                                  AREA    STACK, NOINIT, READWRITE, ALIGN=3
4  __stack_limit
5  Stack_Mem               SPACE   Stack_Size
6  __initial_sp                                         ;初始化SP
7  
8                                       AREA    RESET, DATA, READONLY
9                                  EXPORT  __Vectors
10                                 EXPORT  __Vectors_End
11                                 EXPORT  __Vectors_Size
12                  
13 __Vectors                    DCD      __initial_sp            ;栈顶
14                                 DCD      Reset_Handler          ;复位中断向量表
15
16
17 __Vectors_End
18 __Vectors_Size          EQU      __Vectors_End - __Vectors
19  
20                                      AREA     |.text|, CODE, READONLY
21                  
22 Reset_Handler           PROC                     ;复位中断函数
23                                      IMPORT  Start
24              
25                                      LDR R0, =Start               ;跳转执行Start函数
26                                      BX      R0
27                                 ENDP
        示例代码6.3.1.1中前面的序号是为了代码阅读方便后面添加的,大家在参考写程序的时候不要将这些序号写进去!
        在main.s中输入如下内容:
示例代码6.3.1.2 main.s文件内容
;**********************************************************************
;* @file                  : main.s
;* @author               : 正点原子Linux团队
;* @version              : V1.0
;* @date                 : 2020-05-03
;* @description         : MP157开发板M4裸机例程main汇编文件
;*                         本文件功能:
;*                         - 定义所要使用的寄存器
;*                          - Start函数编写,复位中断函数Reset_Handler会执行Start函数
;*                         - 使能GPIOI时钟,初始化GPIOI_0这个IO为推挽输出
;*                         - 循环里面周期性的点亮/熄灭LED0
;* @license             : Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
;**********************************************************************

1  PERIPH_BASE                          EQU     (0x40000000)
2  MCU_AHB4_PERIPH_BASE             EQU     (PERIPH_BASE + 0x10000000)
3  RCC_BASE                             EQU     (MCU_AHB4_PERIPH_BASE + 0x0000)
4  RCC_MC_AHB4ENSETR                EQU     (RCC_BASE + 0XAA8)
5  GPIOI_BASE                           EQU     (MCU_AHB4_PERIPH_BASE + 0xA000)
6  GPIOI_MODER                      EQU     (GPIOI_BASE + 0x0000)   
7  GPIOI_OTYPER                     EQU     (GPIOI_BASE + 0x0004)   
8  GPIOI_OSPEEDR                    EQU     (GPIOI_BASE + 0x0008)   
9  GPIOI_PUPDR                      EQU     (GPIOI_BASE + 0x000C)   
10 GPIOI_BSRR                           EQU     (GPIOI_BASE + 0x0018)   
11  
12         AREA    |.text|, CODE, READONLY, ALIGN=2
13         THUMB
14         EXPORT  Start
15         
16 Start
17          ;1、设置RCC_MC_AHB4ENSETR寄存器,使能GPIOI时钟
18          LDR     R0, =RCC_MC_AHB4ENSETR
19          LDR     R1, [R0]                    ;读取RCC_MC_AHB4ENSETR寄存器的值到R1
20          ORR     R1, #(1 << 8)                ;bit4置1,使能GPIOI时钟
21          STR     R1, [R0]                     ;写入到RCC_MC_AHB4ENSETR寄存器
22  
23          ;2、GPIOI_MODER寄存器,设置GPIOI_0输出模式
24          LDR     R0, =GPIOI_MODER
25          LDR     R1, [R0]                                ;读取GPIOI_MODER寄存器的值到R1
26                  BIC     R1, #(3 << (2 * 0))             ;bit1:0清零
27          ORR     R1, #(1 << (2 * 0))            ;bit1:0设置为01
28          STR     R1, [R0]                        ;写入到GPIOI_MODER寄存器
29  
30          ;3、GPIOI_OTYPER寄存器,设置GPIOI_0为推挽模式
31          LDR     R0, =GPIOI_OTYPER      
32          LDR     R1, [R0]                        ;读取GPIOI_OTYPER寄存器值到R1
33          BIC     R1, #(1 << 0)                   ;bit0清零,设置为上拉
34          STR     R1, [R0]                        ;写入到GPIOI_OTYPER寄存器
35  
36          ;4、GPIOI_OSPEEDR寄存器,设置GPIOI_0为高速
37          LDR     R0, =GPIOI_OSPEEDR
38          LDR     R1, [R0]                        ;读取GPIOI_OSPEEDR寄存器的值到R1
39          BIC     R1, #(3 << (2 * 0))             ;bit1:0清零
40          ORR     R1, #(2 << (2 * 0))             ;bit1:0设置为10
41          STR     R1, [R0]                        ;写入到GPIOI_OSPEEDR寄存器   
42  
43          ;5、GPIOI_PUPDR寄存器,设置GPIOI_0上拉
44          LDR     R0, =GPIOI_PUPDR
45          LDR     R1, [R0]                        ;读取GPIOI_PUPDR寄存器的值到R1
46          BIC     R1, #(3 << (2 * 0))             ;bit1:0清零
47          ORR     R1, #(1 << (2 * 0))             ;bit1:0设置为01
48          STR     R1, [R0]                        ;写入到GPIOI_PUPDR寄存器  
49  
50          ;6、GPIOI_BSRR寄存器,设置GPIOI_0为低,点亮LED0
51          LDR     R0, =GPIOI_BSRR
52          LDR     R1, [R0]                                  ;读取GPIOI_BSRR寄存器的值到R1
53          ORR     R1, #(1 << 16)                           ;bit16设置为0
54          STR     R1, [R0]                                   ;写入到GPIOI_BSRR寄存器
55
56 ;循环
57 Loop
58          BL  Led0_on             ;开灯
59          BL  Delay                       ;延时
60          BL  Led0_off            ;关灯
61          BL  Delay               ;延时
62          B Loop
63  
64
65 ;打开LED0
66 Led0_on
67          LDR     R0, =GPIOI_BSRR
68          LDR     R1, [R0]                   ;读取GPIOI_BSRR寄存器的值到R1
69          ORR     R1, #(1 << 16)           ;bit16置1,输出低电平
70          STR     R1, [R0]                  ;写入到GPIOI_BSRR寄存器
71          BX      LR
72
73         ;关闭LED0
74         Led0_off
75          LDR     R0, =GPIOI_BSRR
76          LDR     R1, [R0]                   ;读取GPIOI_BSRR寄存器的值到R1
77          ORR     R1, #(1 << 0)            ;bit15置1,输出高电平
78          STR     R1, [R0]                  ;写入到GPIOI_BSRR寄存器
79          BX      LR
80
81 ;延时函数
82 Delay
83             LDR  R2, =0X4FFFFF
84          LDR R3, =0X0
85 Delay_loop
86             SUB R2, R2, #1           ;R2寄存器减1
87                  CMP R2, R3              ;R2和R3寄存器的值进行比较
88          BNE Delay_loop          ;R2与R3的值不相等,说明没有R2还没有减完,继续
89          BX LR                   ;返回LR
90          END
6.3.2 设置分散加载文件
        对于以前学习过STM32单片机的朋友来说这里可能会有疑问,程序编写好就可以编译了呀,为什么这里还要创建分散加载文件。分散加载文件也叫做链接脚本,用来描述程序在编译的时候应该怎么链接,比如代码部分应该链接到哪个地址范围?数据部分应该链接到哪个地址范围,甚至可以单独指定某一个.c或.s文件连接到哪个地址范围。以前STM32单片机不需要链接脚本,只需要直接在MDK上设置好ROM和RAM地址范围即可,以STM32F103为例,设置如图6.3.2.1所示:
第六章 新建MDK工程8426.png

图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所示:
第六章 新建MDK工程8013.png

图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所示设置:
第六章 新建MDK工程8907.png

图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所示:
第六章 新建MDK工程9225.png

图6.3.3.1 编译结果

        从图6.3.3.1可以看出,此时有0个错误(Error),3个警告(Warning),这三个警告可以忽略不计,如果编译有错误(Error)的话就自行检查错误。
6.4 代码调试验证
        代码编译完成以后就可以进行调试验证了,因为是全新创建的工程,因此在调试验证之前需要对工程进行一些设置。点击,打开配置项,点击Output选项,选择创建HEX文件文件,如图6.4.1所示:
第六章 新建MDK工程9429.png

图6.4.1 Output选项卡

        虽然STM32MP157 M4内核用不到hex文件,但是这里还是选择上。继续点击“Debug”选项卡,根据自己的实际使用,选择调试器,比如我使用ST LINk,因此就选择ST-Link Debuger,如图6.4.2所示:
第六章 新建MDK工程9561.png

图6.4.2 Debug选项卡

        图6.4.2中选择仿真器为“ST-Link Debugger”,然后勾选“Run to main()”,虽然本章节是汇编语言编写的,没有main函数,但是为了例程一致性,还是勾选上此选项。
        点击图6.4.2中的“Settings”按钮,打开调试设置界面,设置ST LINK的一些参数,如图6.4.3所示:
第六章 新建MDK工程9734.png

图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所示:
第六章 新建MDK工程9975.png

图6.4.4 Pack设置

        勾选图6.4.4中的“Enable”,点击“确认”退出。然后重新点击“Debug”标签,查看图6.4.3中③的芯片ID有没有识别出来。识别出来以后就再重新点击“Pack”,然后取消图6.4.4中刚刚勾选的 “Enable”,否则无法仿真。
最后设置Utilities选项卡里面设置下载时的目标编程器,如图6.4.5所示:
第六章 新建MDK工程10153.png

图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自带的清理工程选项,不过此选项清理的工程并不完全:
第六章 新建MDK工程10634.png

图6.5.1清理工程

        或者可以使用通过批处理来实现,正点原子的源代码工程就是用批处理来清除的,该批处理文件keilkill.bat在我们实验工程的每个代码中:
第六章 新建MDK工程10717.png

图6.5.2正点原子提供的批处理文件

        只要双击该文件,就可以把我们编译生成的所有文件删除。自己也可以修改批处理脚本keilkill.bat来选择删除哪些文件,如下:
1   del *.bak /s
2   del *.ddk /s
3   del *.edk /s
4   del *.lst /s
5   del *.lnp /s
6   del *.mpf /s
7   del *.mpj /s
8   del *.obj /s
9   del *.omf /s
10  ::del *.opt /s  ::两个冒号表示该语句被注释了,不会执行
11  del *.plg /s
12  del *.rpt /s
13  del *.tmp /s
14  del *.__i /s
15  del *.crf /s
16  del *.o /s
17  del *.d /s
18  del *.axf /s
19  del *.tra /s
20  del *.dep /s           
21  del JLinkLog.txt /s
22
23  del *.iex /s
24  del *.htm /s
25  del *.map /s
26
27  del *.dbgconf /s
28  del *.LINGZHUNING /s
29  del *.Administrator /s
30  exit
        以上脚本中是删掉哪些文件,*号是通配符,例如第1行,删掉所有.bak后缀的文件。两个冒号“::”表示注释该行,相当于C语言的“//”,被注释的行不会被执行,如果我们不想删除.axf文件,则把第18行用两个冒号注释掉即可。
::del *.axf /s


阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 02:48

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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