使用MDK-Arm Keil uVision5创建STM32工程指南

 一、准备工程·芯片/设备包

 Step-1  安装“芯片/设备包”

“Project -> Manager -> Pack Installer” ,打开包安装窗口。 左侧 [Device] 选择对应芯片“STM32F407ZGTx”,右侧[Pack] 安装需要的包。

  Step-2  选定 “芯片/设备包”版本

“Project -> Manager -> Select Software Packs” ,打开包版本选择窗口。 [Select] 栏 可以使用多个策略:latest/最新  fixed/固定  exclude/排除。

常用包:

ARM::CMSIS(Cortex  Microcontroller  Software  Interface  Standard) :“ARM Cortex™  微控制器软件接口标准”:

ARM::CMSIS-Driver

Keil::ARM_Compiler

Keil::MDK_Middleware

Keil::STM32F4xx_DFP

二、新建·工程

Step-1 选择目录与命名工程

Step-2 选择“芯片/设备”类型

这里根据真实野火STM32F407霸天虎V2使用的MCU芯片“ STM32F407ZGT6”,  选择“STM32F407ZGTx”

也可以工程建立后,在 “Project -> Option for Target -> Device…” 中后期修改

 Step-3 选择“运行时环境”

也可以工程建立后,在 “Project -> Manager -> Run-Time Environment…” 中后期修改

工程必选配置:

下面三个选项,不选是不能用的。

 其中Classic(Standlone) 和 STM32CubeMX,  根据情况二选一。

 工程可选硬件配置(HAL):

  工程可选驱动配置(Driver):

【注意】

根据依赖关系提示, 添加相应库,如下图:

HAL:Common 依赖 Framework下面的二选一。

三、代码编辑

 Step-1  添加·头文件路径

“Project -> Option for Target “”,打开“目标选项窗口”,在“C/C++”-> Include Paths -> …按钮,

填写常用头文件所在目录,例如硬件抽象层和驱动头文件所在目录:

C:\Users\Administrator\AppData\Local\Arm\Packs\Keil\STM32F4xx_DFP\2.16.0\Drivers\STM32F4xx_HAL_Driver\Inc\

 Step-2  通过头文件"RTE_Device.h", 启用芯片/外围设备功能

// RTE_Device.h
#define RTE_I2C1                        1   //1启用I2C    0关闭I2C
#define RTE_SPI1                        1   //1启用SPI    0关闭SPI
#define RTE_USART1                      1   //1启用USART  0关闭USART

Step-3  创建编辑main.c文件,加入到工程中

//main.c

#include <stdio.h>
int main()
{

	printf("[%s:%d] Hello world.\n",__FUNCTION__, __LINE__);

}

Project -> Manager -> Project Items” ,打开包版本选择窗口

常用文件与分组关系:

分组 文件 原文件包 安装位置
/User/

main.c

stm32f4xx_hal_msp.c

stm32f4xx_it.c

\Arm\Packs\Keil\STM32F4xx_DFP\2.16.0

\MDK\Templates\src\

/User/

stm32f4xx_hal_conf.h

stm32f4xx_it.h
main.h

FreeRTOSConfig.h

\Arm\Packs\Keil\STM32F4xx_DFP\2.16.0

\MDK\Templates\inc\

/User/bsp/

/User/app/

/User/ RTE_Device.h 

\Arm\Packs\Keil\STM32F4xx_DFP\2.16.0

\CMSIS\Driver\Config

/CMSIS-Driver/

USART_STM32F4xx.c

CAN_STM32F4xx.c

USART_STM32F4xx.h

CAN_STM32F4xx.h

\Arm\Packs\Keil\STM32F4xx_DFP\2.16.0

\CMSIS\Driver\

/Device/

/Inc/stm32f4xx_hal_def.h 

/Inc/stm32f4xx_hal.h

/Src/stm32f4xx_hal.c     
/Src/stm32f4xx_hal_cortex.c

/Src/stm32f4xx_hal_dma.c

/Src/stm32f4xx_hal_dma_ex.c

/Src/stm32f4xx_hal_gpio.c

/Src/stm32f4xx_hal_pwr.c

/Src/stm32f4xx_hal_pwr_ex.c

/Src/stm32f4xx_hal_rcc.c

/Src/stm32f4xx_hal_rcc_ex.c

/Src/stm32f4xx_hal_rtc.c

/Src/stm32f4xx_hal_usart.c

/Src/stm32f4xx_hal_crc.c

/Src/stm32f4xx_hal_tim.c

/Src/stm32f4xx_hal_wwdg.c

\Arm\Packs\Keil\STM32F4xx_DFP\2.16.0

\Drivers\STM32F4xx_HAL_Driver\Src\

/STARTUP/ startup_stm32f407xx.s

\Arm\Packs\Keil\STM32F4xx_DFP\2.16.0\

Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm\

/CMSIS/ system_stm32f4xx.c

\Arm\Packs\Keil\STM32F4xx_DFP\2.16.0\

Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\

/CMSIS/

stm32f407xx.h

system_stm32f4xx.h

\Arm\Packs\Keil\STM32F4xx_DFP\2.16.0\

Drivers\CMSIS\Device\ST\STM32F4xx\Include

/CMSIS/

/Include/core_cm4.h

/Include/cmsis_version.h

/Include/cmsis_compiler.h

\Arm\Packs\ARM\CMSIS\5.7.0

\CMSIS\Include

/CMSIS-Driver/ /Include/Driver_USART.h

\Arm\Packs\ARM\CMSIS\5.7.0

\CMSIS\Driver\Include

四、工程编译分析

ref: (187条消息) STM32F4开发指南笔记49——MDK的编译过程及文件类型全解__Amen的博客-CSDN博客_fromelf 解析lib文件

4.1 keil 文件 .map 详解

==============================================================================   

//1主要是各个源文件生成的模块之间相互引用的关系,节区的跨文件引用

Section Cross References

==============================================================================   

//2将库中没有用到的函数从可执行映像中删除掉,减小程序的体积删除无用节区

Removing Unused input sections from the image.

==============================================================================  

// 3 符号映像表

Image Symbol Table

    Local Symbols        // 本地符号

    Global Symbols     // 全局符号

==============================================================================  

//4 映像的内存分布

Memory Map of the image

 Image Entry point : 0x08000189  // 程序的入口点:这里应该是RESET_Handler的地址

Load Region LR_IROM1 (Base: 0x08000000, Size: 0x0000bea4, Max: 0x00100000, ABSOLUTE, COMPRESSED[0x0000b3d0])

//程序的加载映像地址和长度,2e00=2dc0(代码和常数)+0x20(Region Table是RW的加载和执行地址、ZI与HEAPSTACK的执行地址)+0x20(已经初始化的数据)。

Execution Region ER_IROM1 (Exec base: 0x08000000, Load base: 0x08000000, Size: 0x0000b0b4, Max: 0x00100000, ABSOLUTE)

//这段RO区域的加载映像和执行映像一致。

Execution Region RW_IRAM2 (Exec base: 0x10000000, Load base: 0x0800b3d0, Size: 0x00000000, Max: 0x00010000, ABSOLUTE)

    **** No section assigned to this execution region ****

 Execution Region RW_IRAM1 (Exec base: 0x20000000, Load base: 0x0800b0b4, Size: 0x000073e0, Max: 0x00020000, ABSOLUTE, COMPRESSED[0x0000031c])

//RW数据区 ZI数据区 Heap和Stack数据区。

    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x20000000   COMPRESSED   0x00000034   Data   RW          474    .data               freertos.o

//plc_rte_abi_t plc_rte_default __attribute__((at(0x60010000)))={…};

//程序员在代码中 如上定义,可以指定程序在ROM中存储地址,在map文件中生产如下程序段

Load Region LR$$.ARM.__AT_0x60010000 (Base: 0x60010000, Size: 0x00000030, Max: 0x00000030, ABSOLUTE) 

Execution Region ER$$.ARM.__AT_0x60010000 (Exec base: 0x60010000, Load base: 0x60010000, Size: 0x00000030, Max: 0x00000030, ABSOLUTE, UNINIT) 

    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x60010000   0x60010000   0x00000030   Data   RW         6553    .ARM.__AT_0x60010000  plc_app_default.o

==============================================================================  

// 5 各个模块的输入节的大小

Image component sizes

      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Object Name

============================================================================== 

 // 6 

      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   

     43328       3230       1908       3616      26096    1199253   Grand Totals
     43328       3230       1908        844      26096    1199253   ELF Image Totals (compressed)
     43328       3230       1908        844          0          0   ROM Totals

==============================================================================  

//  7 最后给出总长度

    Total RO  Size (Code + RO Data)                45236 (  44.18kB)
    Total RW  Size (RW Data + ZI Data)             29712 (  29.02kB)
    Total ROM Size (Code + RO Data + RW Data)      46080 (  45.00kB)

==============================================================================  //附录:补充说明

Code:通常是指编译器生成的机器指令,也就是程序的执行代码,这些内容会被存储到ROM区。

RO-data:它指程序中用到的只读数据,因而程序不能被修改的内容,这些数据被存储在ROM区。 RO-data区典型:
例1、C语言中const关键字定义的变量。
例2、C语言中定义的全局常量。
例3、C语言中定义的字符串。

RW-data:即可读写数据区域,一定是初始化为“非0值”的可读写数据,而且应用程序可以修改其内容,这些数据被存储在RAM区
RW-data区典型:
例1、C语言中定义的全局变量,且初始化为“非0值”。
例2、C语言中定义的静态变量。且初始化为“非0值”。

ZI-data:可读写数据区域,一定是未初始化或初始化为“0值”的可读写数据,应用程序同样可以修改其内容,这些数据被存储在RAM区
ZI-data区典型:
例1、C语言中定义的数组,只定义了数组的大小,并没有给每个成员赋非0值。

总结: 在拿到一款单片机的时候,一定要明确单片机的ROM大小和RAM大小。
ROM的最小空间一定要大于: Code + RO Data + RW Data的总和;
RAM的最小空间一定要大于: RW Data + ZI Data之和

注意:
ROM就是单片机的FLASH大小
RAM就是单片机的运行内存大小
以STM32G070为例,ROM = 128kB;RAM = 36kB
 

4.2 文件 .sct 详解

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x20000000 0x00020000  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x10000000 0x00010000  {
   .ANY (+RW +ZI)
  }
}

物联沃分享整理
物联沃-IOTWORD物联网 » 使用MDK-Arm Keil uVision5创建STM32工程指南

发表评论