常见的ARM微控制器开发组件有很多,ARM Keil微控制器开发套件(MDK)就是其中之一。Keil MDK基于Windows环境,并且提供以下组件:

  • μVision集成开发环境(IDE);

  • C编译器、汇编器、链接器和工具;

  • 调试器;

  • 模拟器;

  • RTX实时内核,微控制器用的嵌入式OS;

  • 多种微控制器的启动代码;

  • 多种微控制器的Flash编程算法;

  • 编程实例和开发板支持文件;

keil MDK使用的C编译器同ARM RealView开发组件(RealView Development Suite,RVDS)具有相同的编译器引擎,其提供了极佳的性能和代码密度,不同的是,RVDS面向的是更高端的应用,具有以下特性:

  • 支持包括Cortex-A9/A8/A5的所有现代ARM处理器;

  • RealView调试器支持多种处理器调试以及完全版的CoreSight调试;

  • 支持Windows、Linux及Unix;

典型地,使用RVDS的软件编译流程如下:

RVDS编译流程RVDS编译流程.png

如今,RVDS已不再更新,官方推荐使用 Arm Development Studio 来进行开发。

1. 编译过程

MDK编译过程主要分为:编译、链接、格式转化等三步骤。

    (1)编译

    MDK软件使用的编译器为armcc 和 armas,它们根据每个c/c++和汇编文件编程以 “.o” 为后缀的对象文件(Object Code,也称为目标文件),其内容主要是从源文件编译得到机器码,包含了代码、数据以及调试使用信息;

    (2)链接

    链接器armlink将各个.o文件及库文件链接成一个映像文件 “.axf” 或 “.elf”;

    (3)格式转化

    一般来说 Windows 或 Linux 系统使用链接器直接生成可执行映像文件 elf 后,内核根据该文件的信息加载后,就可以运行程序了。但在单片机平台上,需要把该文件的内容加载到芯片上,所以还需要对链接器生成的elf映像文件利用格式转换器 fromelf 转换为 “.bin” 或 “.hex” 文件,交给下载器下载到芯片的FLASH或者ROM中。

安装 Keil_MDK 后,查看 C:\Keil_v5\ARM\ARMCC\bin 目录内容,如下:

armcc工具目录.png

2. 工程设置选项

keil工程中包含许多可用的设置,如:编译和代码生成、将程序下载到Flash、使用调试器、使用模拟器等。

工程选项菜单中包含许多标签,如下:

Keil工程菜单Keil工程菜单.png

具体说明如下:

工程选项菜单工程选项菜单.png

3. After Build/Rebuild

如果正在使用NXP LPC11xx(Cortex-M0),在这些NXP产品中,地址0x1C~0x1F(32位)用作校验,并在Flash存储器编程期间自动产生。由于链接器生成的程序映像不包含这个校验,Flash编程器在确认已编程映像并且同原始文件相比较时,会报告一个错误。

为了解决这个问题,Keil MDK中包含了一个称为 ElfDwt 的工具,这是一个签名创建器,它会将链接器产生的校验插入程序映像中。

after_buildafter_build.png

也可以增加使用 fromelf.exe  工具,将.axf文件转为.bin文件。

C:\Keil_v5\ARM\BIN\ElfDwT.exe ..\OBJ\iTransmitter.axf

C:\Keil_v5\ARM\ARMCC\bin\fromelf.exe --bin -o  ..\OBJ\iTransmitter.bin ..\OBJ\iTransmitter.axf

after_build_配置after_build_配置.png

最终查看生成的bin文件,验证:

查看生成的bin文件查看生成的bin文件.png

4. 在RAM中运行

除了可以将程序下载到Flash存储器中,也可以将其下载到RAM中,这样测试程序时就不会更改Flash存储器的内容。

RAM中运行_更改ROM位置RAM中运行_更改ROM位置.png

生成的部分map文件:

RAM中map文件RAM中map文件.png

取消FLASH编程选项:

取消Flash下载取消Flash下载.png

若进行debug时,则需要创建一个启动脚本ram_debug.ini ,用以初始化栈指针和程序计数器加载到正确位置。内容如下(以 STM32F1xx 为例):

reset

// 对于 Cortex-M3 内核,重映射中断向量表到RAM
_WDWORD(0xE000ED08, 0x20000000); 		// 向量表偏移寄存器(VTOR):0xE000_ED08

LOAD ..\OBJ\iTransmitter.axf INCREMENTAL   // 将映像下载到开发板中

SP = _RDWORD(0x20000000);           // 设置栈指针
PC = _RDWORD(0x20000004);           // 设置程序计数器

g, main              // 跳转到main

为了在调试会话开始时能够调用这个调试启动脚本,需要设置调试选项。如下:

ram_debug_configram_debug_config.png

在调试会话时,程序会被加载到SRAM中,程序计数器(PC)也会被自动设置为正确的程序映像起点,之后应用程序开始执行。

5. 定制启动代码

Keil 的启动代码提供了向量表以及许多配置信息,比如:栈大小和堆大小。如果应用程序需要更大的栈空间或堆空间,就需要编辑启动代码进行修改。

启动代码中栈和堆启动代码中栈和堆.png

以STM32F0xx为例,修改文件 startup_stm32f0xx.s

Stack_Size      EQU     0x00000400

                AREA    STACK, NOINIT, READWRITE,
Stack_Mem       SPACE   Stack_Size
__initial_sp


; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00000200

                AREA    HEAP, NOINIT, READWRITE,
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

                PRESERVE8

6. Keil中分散加载特性

除了使用存储器分布对话框定义工程的存储器分布外,也可以使用分散文件来定义微控制器的存储器分布,这样就可以创建更加复杂的存储器布局。

使用自定义scatter使用自定义scatter.png

可以查看到,工程自动生成的 .sct 文件内容,如下:

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

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

更详细的介绍,请查看官方文档:DUI0203J_rvct_developer_guide.pdf

注意:本站所有文章除特别说明外,均为原创,转载请务必以超链接方式并注明作者出处。 标签:ARM,Cortex-M0,Cortex-M0应用开发