程序员开发实例大全宝库

网站首页 > 编程文章 正文

《STM32入门学习第三阶段》Keil MDK的编译过程及文件类型分析讲解

zazugpt 2024-08-30 04:41:58 编程文章 19 ℃ 0 评论

接上文:欢迎关注逗比小憨憨

上文讲到armlink等文件在keil MDK安装路径中:E:\keilmdk5Setup\ARM\ARMCC\Bin

为其配置环境变量,步骤

1,右键 "此电脑(或我的电脑)"

2, 找到 "相关设置" 中的 "高级系统设置"

3,点击 "高级系统设置",出现如下界面

4,点击 "环境变量",在用户变量一栏中找到名为 “Path” 的变量,若没有该变量,则新建一个。编辑“Path”变量,在它的变量值中输入工具链的路径。

5,点击确定

6,验证:"win + R" ,在弹出对话框中输入 "cmd" , 然后输入 "armlink" ,若跳出提示信息则说明环境变量配置好。

若提示 "不是内部名外部命令 ,也不是可运行的程序…" 信息,说明路径不对,请重新配置环境变量,并确认该工作目录下有编译工具链。

备注说明:

这个过程本质就是让命令行(读法:hang)通过 “Path” 路径找到 “armlink.exe” 程序运行,默认运行“armlink.exe”时它会输出自己的帮助信息,这就是工具链的调用过程,MDK在编译程序时,本质上就是调用这些工具链进行相应的操作,只是它集成为 GUI,相对于命令行对用户更友好。

配置好后,我们可以使用这些文件进行编译(armcc),链接(armlink)文件了。

比如:我们在命令行中输入 "armcc",可以查看其用法,用法格式:armcc [options] fifile1 fifile2 …

options:此选项有很多,比如我们查看可以支持的cpu版本,输入:armcc -cpu=list 出现如下信息:

备注:此命令的用法其实和gcc的用法差不多,可以类比学习。

打开keil MDK 的 Options for Targe->c/c++ 菜单,可看到 keil MDK 对编译器的控制命令,如下图所示:

Compiler control string中有如下字符串:

--c99 -c --cpu Cortex-M3 -g -O0 --apcs=interwork --split_sections -I ../CORE -I ../STM32F10x_StdPeriph_Driver/inc -I ../APP/led -I ../APP/button -I ../BIT_Operation -I ../CORE -I ../delay -I ../APP/timer -I ../USART -I ../APP/pwm -I ../APP/capture -I ../APP/ADC -I ../APP/I_temperature -I ../APP/LCD1602 -I ../APP/iwdg -I ../APP/AT24C0X -I ../APP/MPU60X0 -I ../APP/DHT11 -I ../APP/DHT11_2 -I ../APP/myiic

-IC:/Users/PC/Desktop/STM32F103C8T6/program/STM32F103C8T6升级版/USER/RTE

-IE:/keilmdk5Setup/Keil/STM32F1xx_DFP/2.3.0/Device/Include

-IE:/keilmdk5Setup/ARM/CMSIS/Include

-D__UVISION_VERSION="521" -DSTM32F10X_MD -DSTM32F10X_MD -DUSE_STDPERIPH_DRIVER

-o .\obj\*.o --omf_browse .\obj\*.crf --depend .\obj\*.d

从上述可知,keil MDK在编译工程中的C/C++文件时,使用的是“armcc” 进行编译的,并且使用了上述提供的参数,这些参数详细讲解在 MDK 的帮助手册《ARM Development Tools》 中


对 Compiler control string中的字符串进行解释:

-c99 :表示启用C99源代码的编译
--cpu Cortex-M3: 表示cpu版本是Cortex-M3 (我们课程中使用的单片机型号是STM32F103C8T6,它就是Cortex-M3的内核)
-g: 表示生成调试信息,如果我们需要使用相应的工具进行程序调试,这点很重要
-O0:表示优化等级为0,(因为我们在编写程序时,会出现很多冗余代码,指定优化等级后,编译器会进行优化)
备注:一般是有四种优化等级,分别是:O0,O1,O2,O3,数字越大优化等级越大
--apcs=interwork: 生成有或没有ARM/Thumb交互支持的代码。默认值为/nointerwork,
ARMv5T及更高版本除外,默认值为/interwork。
--split_sections :为源文件中的每个函数生成一个ELF节。输出节的名称与生成该节的函数的名称相同,但带有i.前缀。
-I:表示指定头文件路径
-Dname[(parm-list)][=def]:定义相应的宏
-o:表示输出文件,-o .\obj\*.o:表示输出所有的.o文件到工程文件中的/obj/目录中
--omf_browse:支持生成和存储源浏览器信息。--omf_browse .\obj\*.crf:生成的所有.crf文件
存放到工程文件中的/obj/目录中
 --depend:在编译期间将makefile依赖项行写入文件。 
 --depend  .\obj\*.d:要输出的依赖项文件的名称,在/obj/目录中可以查找到

-I ../CORE -I ../STM32F10x_StdPeriph_Driver/inc -I ../APP/led -I ../APP/button -I ../BIT_Operation -I ../CORE -I ../delay -I ../APP/timer -I ../USART -I ../APP/pwm -I ../APP/capture -I ../APP/ADC -I ../APP/I_temperature -I ../APP/LCD1602 -I ../APP/iwdg -I ../APP/AT24C0X -I ../APP/MPU60X0 -I ../APP/DHT11 -I ../APP/DHT11_2 -I ../APP/myiic

-IC:/Users/PC/Desktop/STM32F103C8T6/program/STM32F103C8T6升级版/USER/RTE

-IE:/keilmdk5Setup/Keil/STM32F1xx_DFP/2.3.0/Device/Include

-IE:/keilmdk5Setup/ARM/CMSIS/Include

(注意:每个人的这里不一样,主要看大家在工程中包含了哪些头文件)

这些就是我们在编译工程,编译器将这些路径中查找相应的头文件(.h文件),我们从课程可以知道,每次写程序时,都要新建一个.c和.h文件,并且还要进行.h头文件路径的包含,上述就是我们包含头文件路径后,软件为我们自动加上的头文件路径(其中有一部分是软件自动要包含的头文件路径,比如-IE:/keilmdk5Setup/ARM/CMSIS/Include,这些是一些系统头文件的路径,比如“stdio.h”)

-D__UVISION_VERSION="521" :定义一个宏__UVISION_VERSION,它的值是521
此宏是MDK软件自动定义的,表示我们使用的软件版本是5.21版本
-DSTM32F10X_MD :定义一个宏,STM32F10X_MD,表示FLASH容量是中容量
中容量范围。大家去《STM32零基础入门第一阶段视频中的库函数工程模板建立那几节视频》
-DUSE_STDPERIPH_DRIVER:定义一个宏,USE_STDPERIPH_DRIVER,表示程序中使用标准库
大家去《STM32零基础入门第一阶段视频中的库函数工程模板建立那几节视频》

对于上述定义的宏:

回顾(STM32课程中,建立库函数工程文件那一节),我们在新建库函数工程模板时,Options for Targe -> c/c++ -> Define中写入了这个字符串:STM32F10X_MD,USE_STDPERIPH_DRIVER

-o .\obj\*.o --omf_browse .\obj\*.crf --depend .\obj\*.d:

打开我们的STM32工程模板,在obj目录中可以查看到很多.o,.crf,.d文件

armasm.exe 是汇编器,它把汇编文件编译成 .o文件。与 armcc 类似,MDK 对 armasm 的调用选项可在“Option for Target->Asm”页面进行配置。

对Assembler control string中字符串进行解释:

--cpu Cortex-M3 -g --apcs=interwork 
-I C:\Users\PC\Desktop\STM32F103C8T6\program\STM32F103C8T6升级版\USER\RTE 
-I E:\keilmdk5Setup\Keil\STM32F1xx_DFP\2.3.0\Device\Include 
-I E:\keilmdk5Setup\ARM\CMSIS\Include 
--pd "__UVISION_VERSION SETA 521" --pd "STM32F10X_MD SETA 1" --list ".\obj\*.lst" --xref -o "*.o" --depend "*.d" 
下面这些语句和armcc中的解释一样
--cpu Cortex-M3 -g --apcs=interwork

-I C:\Users\PC\Desktop\STM32F103C8T6\program\STM32F103C8T6升级版\USER\RTE

-I E:\keilmdk5Setup\Keil\STM32F1xx_DFP\2.3.0\Device\Include

-I E:\keilmdk5Setup\ARM\CMSIS\Include
--pd "__UVISION_VERSION SETA 521"
: --predefine命令行选项的同义词。表示指示armasm预执行SETA、SETL或SETS指令之一。

 --pd "STM32F10X_MD SETA 1"
:-predefine命令行选项的同义词。表示指示armasm预执行SETA、SETL或SETS指令之一。

 --list ".\obj\*.lst":指示汇编程序将汇编程序生成的汇编语言的详细列表输出到文件中。 

--xref -o "*.o" :指示汇编程序列出符号的交叉引用信息,
包括它们在宏内部和外部的定义位置和使用位置。-o:表示输出文件

--depend "*.d":将makefile依赖项行写入文件。源文件依赖项列表适用于make实用程序。
SETA、SETL和SETS指令设置局部或全局变量的值。
__UVISION_VERSION SETA 521:表示定义一个局部或全局变量__UVISION_VERSION,它的值是521,
注意,这条语句__UVISION_VERSION SETA 521必须使用引号括起来


armlink.exe 是链接器,它把各个.o文件链接组合在一起生成 ELF 格式的 AXF文件,AXF 文件是可执行的,下载器把该文件中的指令代码下载到芯片后,该芯片就能运行程序了;利用 armlink 还可以控制程序存储到指定的 ROM 或 RAM 地址。在 MDK 中可在“Option for Target->Linker”页面配置 armlink 选项。

对Linker control string中字符串进行解释

--cpu Cortex-M3 *.o 
--ro-base 0x08000000 --entry 0x08000000 --rw-base 0x20000000 --entry Reset_Handler --first __Vectors --strict --summary_stderr --info summarysizes --map --xref --callgraph --symbols 
--info sizes --info totals --info unused --info veneers 
 --list ".\obj\doubixiaohanhan.map" 
-o .\obj\doubixiaohanhan.axf 
--cpu Cortex-M3 *.o :内核版本Cortex-M3,链接所有生成的.o文件
--ro-base 0x08000000 :在指定地址设置包含RO-data输出部分的区域的加载和执行地址。
备注:语法格式:--ro_base=address 
该地址必须字对齐,也就是4字节对齐

--rw-base 0x20000000 :在指定地址设置包含RW-data输出部分的区域的执行地址。

 --entry :指定输入段与输入点
 
 语法:--entry=location 
location可以是:
1,可以是数字,比如--entry 0x08000000
2,可以是符号,比如 --entry Reset_Handler
 
 --first __Vectors :将选定的输入节首先放置在其执行区域中。
 例如,这可以将包含向量表的部分放在image的第一位。

 --strict :指示链接器执行其他一致性检查,例如可能导致失败的报告条件。
 --summary_stderr :
 --info :列出image信息。
 --map :启用内存映射的打印。
 --xref :列出输入部分之间的所有交叉引用。
 --callgraph :创建一个包含函数静态调用图的文件。调用图为image中的所有函数提供定义和参考信息
 --symbols :启用链接步骤中使用的每个本地和全局符号及其值的列表。最终输出会放在.map文件里面
 --list ".\obj\doubixiaohanhan.map" :将诊断输出重定向到文件。
 -o .\obj\doubixiaohanhan.axf :输出最终的.axf文件

对Linker control string中字符串进行解释:

--cpu Cortex-M3 *.o 
--strict --scatter ".\obj\doubixiaohanhan.sct" 
--summary_stderr --info summarysizes --map --xref --callgraph --symbols 
--info sizes --info totals --info unused --info veneers 
 --list ".\obj\doubixiaohanhan.map" 
-o .\obj\doubixiaohanhan.axf 

--scatter ".\obj\doubixiaohanhan.sct":按照分散加载文件的描述创建map文件

doubixiaohanhan.map文件内容如下:

Component: ARM Compiler 5.06 update 3 (build 300) Tool: armlink [4d35c9]

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

Section Cross References

    main.o(i.main) refers to misc.o(i.NVIC_PriorityGroupConfig) for NVIC_PriorityGroupConfig
    main.o(i.main) refers to delay.o(i.delay_init) for delay_init
    main.o(i.main) refers to usart.o(i.Usart1_Init) for Usart1_Init
  因篇幅太长,部分省略
    startup_stm32f10x_md.o(.text) refers to startup_stm32f10x_md.o(STACK) for Stack_Mem
    myiic.o(i.myiic_ack) refers to myiic.o(i.myiic_delay) for myiic_delay
    myiic.o(i.myiic_delay) refers to delay.o(i.delay_us) for delay_us
   
   因篇幅太长,部分省略
    defsig_other.o(.text) refers to defsig_general.o(.text) for __default_signal_display


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

Removing Unused input sections from the image.

    Removing main.o(.bss), (100 bytes).
    Removing main.o(.data), (4 bytes).
    Removing misc.o(i.NVIC_SetVectorTable), (20 bytes).
  ing stm32f10x_adc.o(i.ADC_GetITStatus), (36 bytes).
 因篇幅太长,部分省略
    Removing stm32f10x_tim.o(i.TIM_SelectCOM), (24 bytes).
    Removing stm32f10x_tim.o(i.TIM_SelectHallSensor), (24 bytes).
    Removing stm32f10x_tim.o(i.TIM_SelectInputTrigger), (18 bytes).
    

452 unused section(s) (total 18286 bytes) removed from the image.

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

Image Symbol Table

    Local Symbols

    Symbol Name                              Value     Ov Type        Size  Object(Section)

    ../clib/angel/boardlib.s                 0x00000000   Number         0  boardinit1.o ABSOLUTE
    ../clib/angel/boardlib.s                 0x00000000   Number         0  boardinit2.o ABSOLUTE
  因篇幅太长,部分省略
    .ARM.Collect$rtexit$00000004           0x0800018a   Section        6  rtexit2.o(.ARM.Collect$rtexit$00000004)
    .text                                    0x08000190   Section       60  startup_stm32f10x_md.o(.text)
    .text                                    0x080001cc   Section        2  use_no_semi_2.o(.text)
    .text                                    0x080001d0   Section        0  noretval__2printf.o(.text)
    .text                                    0x080001e8   Section        0  __printf.o(.text)
    .text                                    0x08000250   Section        0  _printf_dec.o(.text)
 因篇幅太长,部分省略
    fac_ms                                   0x20000034   Data           4  delay.o(.data)
    .data                                    0x20000038   Section        8  usart.o(.data)
    sta                                      0x20000038   Data           4  usart.o(.data)
    .bss                                     0x20000040   Section      100  usart.o(.bss)
    usart1_data                              0x20000040   Data         100  usart.o(.bss)
    .bss                                     0x200000a4   Section       96  libspace.o(.bss)
    HEAP                                     0x20000108   Section        0  startup_stm32f10x_md.o(HEAP)
    STACK                                    0x20000108   Section      512  startup_stm32f10x_md.o(STACK)
    Heap_Mem                                 0x20000108   Data           0  startup_stm32f10x_md.o(HEAP)
    Stack_Mem                                0x20000108   Data         512  startup_stm32f10x_md.o(STACK)
    __initial_sp                             0x20000308   Data           0  startup_stm32f10x_md.o(STACK)

    Global Symbols

    Symbol Name                              Value     Ov Type        Size  Object(Section)

    BuildAttributes$THM_ISAv4$P$D$K$B$S$PE$A:L22UL41UL21$X:L11$S22US41US21$IEEE1$IW$USESV6$~STKCKD$USESV7$~SHL$OSPACE$ROPI$EBA8$UX$STANDARDLIB$REQ8$PRES8$EABIv2 0x00000000   Number         0  anon$obj.o ABSOLUTE
    __ARM_use_no_argv                        0x00000000   Number         0  main.o ABSOLUTE
    __ARM_exceptions_init                     - Undefined Weak Reference
    __alloca_initialize                       - Undefined Weak Reference
    __arm_preinit_                            - Undefined Weak Reference
    __cpp_initialize__aeabi_                  - Undefined Weak Reference
 因篇幅太长,部分省略
    my_at24c0x_init                          0x08000c85   Thumb Code     8  at24c0x.o(i.my_at24c0x_init)
    my_at24c0x_read_byte                     0x08000c8d   Thumb Code    18  at24c0x.o(i.my_at24c0x_read_byte)
   因篇幅太长,部分省略
    __libspace_start                         0x200000a4   Data          96  libspace.o(.bss)
    __temporary_stack_top$libspace           0x20000104   Data           0  libspace.o(.bss)



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

Memory Map of the image

  Image Entry point : 0x080000ed

  Load Region LR_IROM1 (Base: 0x08000000, Size: 0x0000107c, Max: 0x00010000, ABSOLUTE)

    Execution Region ER_IROM1 (Base: 0x08000000, Size: 0x0000103c, Max: 0x00010000, ABSOLUTE)

    Base Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x08000000   0x000000ec   Data   RO         3047    RESET               startup_stm32f10x_md.o
    0x080000ec   0x00000008   Code   RO         3255  * !!!main             c_w.l(__main.o)
    0x080000f4   0x00000034   Code   RO         3423    !!!scatter          c_w.l(__scatter.o)
    0x08000128   0x0000001a   Code   RO         3425    !!handler_copy      c_w.l(__scatter_copy.o)
    0x08000142   0x00000002   PAD
   因篇幅太长,部分省略
    0x08000186   0x00000000   Code   RO         3349    .ARM.Collect$rtexit$00000002  c_w.l(rtexit2.o)
     因篇幅太长,部分省略
    0x08000ca0   0x00000070   Code   RO         3121    i.my_at24c0x_test   at24c0x.o
    0x08000d10   0x00000012   Code   RO         3122    i.my_at24c0x_write_byte  at24c0x.o
    0x08000d22   0x0000000c   Code   RO         3053    i.myiic_delay       myiic.o
    0x08000d2e   0x00000002   PAD
    0x08000d30   0x00000050   Code   RO         3054    i.myiic_init        myiic.o
    0x08000d80   0x00000050   Code   RO         3055    i.myiic_noack       myiic.o
    0x08000dd0   0x00000068   Code   RO         3056    i.myiic_read_byte   myiic.o
    0x08000e38   0x0000004c   Code   RO         3057    i.myiic_start       myiic.o
    0x08000e84   0x0000004c   Code   RO         3058    i.myiic_stop        myiic.o
    0x08000ed0   0x0000007c   Code   RO         3059    i.myiic_wait_ack    myiic.o
    0x08000f4c   0x0000005c   Code   RO         3060    i.myiic_write_byte  myiic.o
    0x08000fa8   0x00000042   Code   RO         3061    i.sensor_common_read_byte  myiic.o
    0x08000fea   0x00000030   Code   RO         3062    i.sensor_common_write_byte  myiic.o
    0x0800101a   0x00000002   PAD
    0x0800101c   0x00000020   Data   RO         3421    Region$Table       anon$obj.o


    Execution Region RW_IRAM1 (Base: 0x20000000, Size: 0x00000308, Max: 0x00005000, ABSOLUTE)

    Base Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x20000000   0x00000014   Data   RW         1516    .data               stm32f10x_rcc.o
    0x20000014   0x00000014   Data   RW         3004    .data               system_stm32f10x.o
    0x20000028   0x00000006   Data   RW         3124    .data               at24c0x.o
    0x2000002e   0x00000002   PAD
    0x20000030   0x00000008   Data   RW         3155    .data               delay.o
    0x20000038   0x00000008   Data   RW         3183    .data               usart.o
    0x20000040   0x00000064   Zero   RW         3182    .bss                usart.o
    0x200000a4   0x00000060   Zero   RW         3299    .bss                c_w.l(libspace.o)
    0x20000104   0x00000004   PAD
    0x20000108   0x00000000   Zero   RW         3046    HEAP                startup_stm32f10x_md.o
    0x20000108   0x00000200   Zero   RW         3045    STACK               startup_stm32f10x_md.o


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

Image component sizes


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

       156         20          0          6          0       2451   at24c0x.o
         0          0          0          0          0         32   core_cm3.o
       236         32          0          8          0       1759   delay.o
        40          0          0          0          0     231995   main.o
       172         22          0          0          0       2169   misc.o
       758        104          0          0          0       5346   myiic.o
        60         22        236          0        512        808   startup_stm32f10x_md.o
       282          0          0          0          0       2583   stm32f10x_gpio.o
       244         26          0         20          0       3969   stm32f10x_rcc.o
       446          6          0          0          0       6397   stm32f10x_usart.o
       328         28          0         20          0       2185   system_stm32f10x.o
       360         26          0          8        100       4056   usart.o

    ----------------------------------------------------------------------
      3092        286        268         64        612     263750   Object Totals
         0          0         32          0          0          0   (incl. Generated)
        10          0          0          2          0          0   (incl. Padding)

    ----------------------------------------------------------------------

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

         8          0          0          0          0         68   __main.o
       104          0          0          0          0         84   __printf.o
         0          0          0          0          0          0   __rtentry.o
        12          0          0          0          0          0   __rtentry2.o
         6          0          0          0          0          0   __rtentry4.o
        52          8          0          0          0          0   __scatter.o
        26          0          0          0          0          0   __scatter_copy.o
        28          0          0          0          0          0   __scatter_zi.o
        48          6          0          0          0         96   _printf_char_common.o
        36          4          0          0          0         80   _printf_char_file.o
         6          0          0          0          0          0   _printf_d.o
       120         16          0          0          0         92   _printf_dec.o
       178          0          0          0          0         88   _printf_intcommon.o
         0          0          0          0          0          0   _printf_percent.o
         4          0          0          0          0          0   _printf_percent_end.o
        18          0          0          0          0         80   exit.o
         8          0          0          0          0         68   ferror.o
         6          0          0          0          0        152   heapauxi.o
         2          0          0          0          0          0   libinit.o
         2          0          0          0          0          0   libinit2.o
         2          0          0          0          0          0   libshutdown.o
         2          0          0          0          0          0   libshutdown2.o
         8          4          0          0         96         68   libspace.o
        24          4          0          0          0         84   noretval__2printf.o
         2          0          0          0          0          0   rtexit.o
        10          0          0          0          0          0   rtexit2.o
        74          0          0          0          0         80   sys_stackheap_outer.o
         2          0          0          0          0         68   use_no_semi.o
         2          0          0          0          0         68   use_no_semi_2.o

    ----------------------------------------------------------------------
       796         42          0          0        100       1176   Library Totals
         6          0          0          0          4          0   (incl. Padding)

    ----------------------------------------------------------------------

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

       790         42          0          0         96       1176   c_w.l

    ----------------------------------------------------------------------
       796         42          0          0        100       1176   Library Totals

    ----------------------------------------------------------------------

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


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

      3888        328        268         64        712     262582   Grand Totals
      3888        328        268         64        712     262582   ELF Image Totals
      3888        328        268         64          0          0   ROM Totals

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

    Total RO  Size (Code + RO Data)                 4156 (   4.06kB)
    Total RW  Size (RW Data + ZI Data)               776 (   0.76kB)
    Total ROM Size (Code + RO Data + RW Data)       4220 (   4.12kB)

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

doubixiaohanhan.sct中的内容:

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

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

备注:链接器默认是根据芯片类型的存储器分布来生成程序的,该存储器分布被记录在工程里的.sct文件中,若有特殊需要的话可自行编辑该文件,改变链接器的链接方式。

扩展知识点:在链接的过程中,会用到一个描述文件,用来指定链接时的行为。这个描述文件叫做链接文件,如linux下的.ld文件,keil中的分散加载文件(.sct文件)


欢迎关注逗比小憨憨

此文还没写完,待更新。。。。。。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表