[011] [STM32] MDK使用命令行进行编译与链接

STM32
Contents
MDK背后的命令·
编译
链接
生成可执行文件
Hex文件分析
生成杂项文件

引言

Keil MDK是常用的嵌入式集成开发环境(Integrated Development Environment),使用IDE,很容易操作,点点鼠标就可完成:

  • 添加文件
  • 指定文件路径(头文件路径、库文件路径)
  • 指定链接库
  • 编译、链接
  • 下载、调试

那么每次点击MDK后会执行什么命令?

1 MDK背后的命令

image-20220314132111628

勾选生成批处理文件.bat,使用文本编辑器打开:

SET PATH=E:\MDK\ARM\ARMCC\Bin // 所有系统环境变量,太长后面部分已截取
SET CPU_TYPE=STM32F103RC
SET CPU_VENDOR=STMicroelectronics
SET UV2_TARGET=led_c
SET CPU_CLOCK=0x007A1200
"E:\MDK\ARM\ARMCC\Bin\ArmCC" --Via ".\objects\main.__i"
"E:\MDK\ARM\ARMCC\Bin\ArmAsm" --Via ".\objects\start._ia"
"E:\MDK\ARM\ARMCC\Bin\ArmCC" --Via ".\objects\uart.__i"
"E:\MDK\ARM\ARMCC\Bin\ArmLink" --Via ".\Objects\led_c.lnp"
"E:\MDK\ARM\ARMCC\Bin\fromelf.exe" ".\Objects\led_c.axf" --i32combined --output ".\Objects\led_c.hex"
fromelf  --bin  --output=led.bin  Objects\led_c.axf
fromelf  --text  -a -c  --output=led.dis  Objects\led_c.axf
  • "E:\MDK\ARM\ARMCC\Bin\ArmCC":armcc编译器,编译C文件。
  • "E:\MDK\ARM\ARMCC\Bin\ArmAsm":armasm编译器,编译汇编文件。
  • "E:\MDK\ARM\ARMCC\Bin\ArmLink.exe":链接目标文件
  • "E:\MDK\ARM\ARMCC\Bin\fromelf.exe":生成axf、hex等可执行文件

最后两条是在user中添加的生成bin文件和dis反汇编文件的命令:

image-20220314133359757

注意:勾选了create batch file后,不管文件是否修改,每次点击单编译都会全部编译。

E:\MDK\ARM\ARMCC\Bin目录下可以看到这些编译工具:

image-20220314141720517

git bash here后输入./xxx.exe -h可查看命令信息,如./armar.exe -h

image-20220314142313255

关于各编译工具的命令使用参考:[转]keil编译链接过程以及ARMCC、ARMASM、FROMELF、ARMLINK、ARMAR的使用

可以将路径添加到系统环境变量,这样即可在任意路径下使用编译器工具。

1.1 编译

1.1.1 编译C文件

打开uart.__i文件:

--c99 --gnu -c --cpu Cortex-M3 -g -O0 --apcs=interwork --split_sections -I .\drivers
-IE:\MDK\ARM-pack\Keil\STM32F1xx_DFP\2.2.0\Device\Include
-IE:\MDK\ARM\CMSIS\Include
-D__UVISION_VERSION="533" -DSTM32F10X_HD
-o .\objects\uart.o --omf_browse .\objects\uart.crf --depend .\objects\uart.d "drivers\uart.c"

使用"E:\MDK\ARM\ARMCC\Bin\ArmCC"命令编译(需要整理成一行,中间用空格隔开):

"E:\MDK\ARM\ARMCC\Bin\ArmCC" --c99 --gnu -c --cpu Cortex-M3 -g -O0 --apcs=interwork --split_sections -I .\drivers -IE:\MDK\ARM-pack\Keil\STM32F1xx_DFP\2.2.0\Device\Include -IE:\MDK\ARM\CMSIS\Include -D__UVISION_VERSION="533" -DSTM32F10X_HD -o .\objects\uart.o --omf_browse .\objects\uart.crf --depend .\objects\uart.d "drivers\uart.c"

或者直接执行"E:\MDK\ARM\ARMCC\Bin\ArmCC" --Via ".\objects\uart.__i"

使用cmd切换到工程所在文件夹或用git bash here编译:

image-20220314134855622

这些命令也可以在C/C++中看到:

image-20220314135829825

--c99 --gnu -c --cpu Cortex-M3 -g -O0 --apcs=interwork --split_sections -I ./drivers
-IE:/MDK/ARM-pack/Keil/STM32F1xx_DFP/2.2.0/Device/Include
-IE:/MDK/ARM/CMSIS/Include
-D__UVISION_VERSION="533" -DSTM32F10X_HD
-o .\Objects\*.o --omf_browse .\Objects\*.crf --depend .\Objects\*.d

将其中的*.通配符替换生成需要编译源文件的名称,然后在末尾追加文件相对路径,如:"drivers\uart.c",然后在前面加上"E:\MDK\ARM\ARMCC\Bin\ArmCC"命令编译即可(依然需要整理成一行,中间用空格隔开)。


使用git编译main函数出现以下错误:

image-20220314141220208

"E:\MDK\ARM\ARMCC\Bin\ArmCC"  --Via ".\objects\main.__i"

image-20220314141446841

1.1.2 编译汇编文件

打开start._ia文件:

--cpu Cortex-M3 -g --apcs=interwork 
-IE:\MDK\ARM-pack\Keil\STM32F1xx_DFP\2.2.0\Device\Include
-IE:\MDK\ARM\CMSIS\Include
--pd "__UVISION_VERSION SETA 533" --pd "STM32F10X_HD SETA 1"
--list .\listings\start.lst --xref -o .\objects\start.o --depend .\objects\start.d "start.s"

使用"E:\MDK\ARM\ARMCC\Bin\ArmAsm"命令编译:

"E:\MDK\ARM\ARMCC\Bin\ArmAsm" --cpu Cortex-M3 -g --apcs=interwork -IE:\MDK\ARM-pack\Keil\STM32F1xx_DFP\2.2.0\Device\Include -IE:\MDK\ARM\CMSIS\Include --pd "__UVISION_VERSION SETA 533" --pd "STM32F10X_HD SETA 1" --list .\listings\start.lst --xref -o .\objects\start.o --depend .\objects\start.d "start.s"

或者直接执行"E:\MDK\ARM\ARMCC\Bin\ArmAsm" --Via ".\objects\start._ia"

image-20220314140203575

汇编文件编译时没有输出log信息。

这些命令也可以在Asm中看到:

image-20220314140240474

--cpu Cortex-M3 -g --apcs=interwork 
-I E:\MDK\ARM-pack\Keil\STM32F1xx_DFP\2.2.0\Device\Include 
-I E:\MDK\ARM\CMSIS\Include 
--pd "__UVISION_VERSION SETA 533" --pd "STM32F10X_HD SETA 1" --list ".\Listings\*.lst" --xref -o "*.o" --depend "*.d" 

使用方法与编译C文件一样。如果汇编文件与工程在同一目录下则无需添加路径:

image-20220314140413328

1.2 链接

打开led_c.lnp文件:

--cpu Cortex-M3
".\objects\main.o"
".\objects\start.o"
".\objects\uart.o"
--strict --scatter ".\Objects\led_c.sct"
--entry Reset_Handler --summary_stderr --info summarysizes --map --load_addr_map_info --xref --callgraph --symbols
--info sizes --info totals --info unused --info veneers
--list ".\Listings\led_c.map" -o .\Objects\led_c.axf

使用"E:\MDK\ARM\ARMCC\Bin\ArmLink"命令链接:

"E:\MDK\ARM\ARMCC\Bin\ArmLink" --cpu Cortex-M3 ".\objects\main.o" ".\objects\start.o" ".\objects\uart.o" --strict --scatter ".\Objects\led_c.sct" --entry Reset_Handler --summary_stderr --info summarysizes --map --load_addr_map_info --xref --callgraph --symbols --info sizes --info totals --info unused --info veneers --list ".\Listings\led_c.map" -o .\Objects\led_c.axf

或者直接执行"E:\MDK\ARM\ARMCC\Bin\ArmLink" --Via ".\Objects\led_c.lnp"

image-20220314140545017

输出结果与MDK一致:

image-20220314140606235

这些命令也可以在Linker中看到:

image-20220314140637941

--cpu Cortex-M3 *.o 
--strict --scatter ".\Objects\led_c.sct" 
--entry Reset_Handler --summary_stderr --info summarysizes --map --xref --callgraph --symbols 
--info sizes --info totals --info unused --info veneers 
 --list ".\Listings\led_c.map" 
-o .\Objects\led_c.axf 

1.3 生成可执行文件

"E:\MDK\ARM\ARMCC\Bin\ArmLink" --Via ".\Objects\led_c.lnp"
"E:\MDK\ARM\ARMCC\Bin\fromelf.exe" ".\Objects\led_c.axf" --i32combined --output ".\Objects\led_c.hex"
fromelf  --bin  --output=led.bin  Objects\led_c.axf
fromelf  --i32  --output=led.hex  Objects\led_c.axf				// intel hex
fromelf  --text  -a -c  --output=led.dis  Objects\led_c.axf

ArmLinkfromelf.exe同时执行(否则失败),最后生成:

  • led_c.axf:不仅包含代码数据,还包含了工程的各种信息
  • led_c.hex:十六进制符号表示的代码记录,记录了代码应该存储到的flash哪个地址和二进制数据等信息
  • led.bin:只存储机器码,文件大小 = ROM Size (Code + RO Data + RW Data)
  • led.dis:反汇编文件

1.4 Hex文件分析

16进制文本表示

image-20220318150508436

  • ::使用冒号表示一条记录的开始

  • ll:主体数据区(绿色区域)长度

  • aaaa:每条记录中的内容应存放到Flash中的起始地址,相对flash起始地址的偏移值

  • tt:表示这条记录的类型:

    image-20220318150947228
    • 00:绿色部分数据记录dd
    • 01:hex文件结束记录
    • 02:扩展地址记录,与04类似
    • 04:如上图第一条可以用绿色0800+橙色0000表示记录开始地址:0x0800 0000,即内部flash的起始地址
    • 05:ARM芯片专用
  • dd:表示一个字节的数据(16进制),一条记录含多个dd,即可以多个字节数据,而ll则表示这条记录字节数

  • cc:本条记录的校验和,即前面所有16进制(冒号除外)两个为一组的和对256取模运算结果的补码。如第一条记录:(0x02+0x00+0x00+0x04+0x08+0x00) % 256= 0x0e,反码为0xf1,补码即为0xf2。

hex与bin对比:

image-20220318193341778

1.5 生成杂项文件

1.5.1 生成各节区详细信息

fromelf --text -v Objects/F103-Fwlib.axf > test.txt
// 或 fromelf --text -v --output=f.txt Objects/F103-Fwlib.axf

image-20220318203228504

  • size in file = Code + RO Data + RW Data
  • size in memory = ZI Data

有时候编译器会做优化,实际可能更小些,如:开辟的数组很多空间没有初始化,则会被分配到bss段,烧录时不占用flash空间。

1.5.2 查看函数调用关系与最大栈调用深度.htm

编译器生成的xx.htm中可查看:image-20220318203934354

静态最大调用栈为160b,调用关系:main ⇒ Usart_Init ⇒ USART_Init ⇒ RCC_GetClocksFreq

但是无法计算动态栈,即实际可能更大一些,如出现:

  • 递归调用
  • 函数指针调用函数

1.5.3 map文件分析

  • Section Cross References:节区跨文件引用
  • Removing Unused input sections from the image:从映像文件中移除未使用的输入节区
  • Image Symbol Table:Value[运行地址]、Type[变量/指令类型]、Size[占用字节, 0表示未计算,而不是没有]、Object(Section) [符号所属的目标节区]
    • Local Symbols
    • Global Symbols
  • Memory Map of the image:映像文件加载域和执行域信息(bss、stack、heap无加载地址)
  • Image component sizes:映像组件大小,即每个Object文件各段大小信息
    END
  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
odrive是一个开源的电机驱动器项目,它的主要设计目标是为了实现高性能的电机控制系统。而STMicroelectronics的MDK则是一款为STM32微控制器提供集成开发环境的软件工具。 移植odrive到STM32 MDK环境中需要进行以下步骤: 1. 首先,需要下载并安装MDK软件工具,确保与所使用STM32微控制器兼容。能够成功编译和下载代码。 2. 然后,需要获取odrive的源代码,这可以通过从GitHub上克隆odrive项目来完成。确保获取了最新稳定版本的代码。 3. 接下来,需要创建一个新的MDK工程,并将odrive的源代码添加到工程中。根据需要对工程进行配置,例如选择正确的编译器、调试接口等。 4. 确保在MDK工程中正确设置了STM32微控制器的引脚配置,以便与odrive的硬件设计相匹配。这可能涉及到对GPIO、SPI、UART等引脚进行适当配置。 5. 确保在MDK工程中包含了odrive的所有依赖项,例如相关的库文件、驱动程序等。 6. 对odrive源代码进行必要的修改和调整,以适应STM32 MDK环境。这可能涉及到修改编译选项、函数调用、变量定义等。 7. 最后,进行编译和下载测试,确保odrive在STM32 MDK环境下能够正常工作。在调试过程中可能会遇到一些问题,需要根据具体情况进行调试和修复。 总之,移植odrive到STM32 MDK环境需要确保正确配置MDK工程和STM32微控制器,适配odrive的源代码,并进行必要的调试和修复。通过这些步骤,便可以将odrive成功移植到STM32 MDK环境中,为电机控制系统提供高性能的驱动功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柯西的彷徨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值