debug - MDK - arm-none-eabi - 将MDK工程编译过程的所有命令行参数找出来
文章目录
- debug - MDK - arm-none-eabi - 将MDK工程编译过程的所有命令行参数找出来
- 概述
- 笔记
- 实验环境
- 前置条件
- 从MDK命令行编译MDK工程
- uv5_cmd_build.bat
- 建立arm-gcc环境的cmd命令行
- 用命令行来编译
- 整理一下工程中参与编译的实现文件的全部命令行参数
- startup_lpc17xx._ia
- main.__i
- arm-gcc.lnp
- elf 转hex
- 备注
- END
debug - MDK - arm-none-eabi - 将MDK工程编译过程的所有命令行参数找出来
概述
前面做了一个实验
NXP - MDK - 解决因为1768.ld规则写错导致不能单步调试的问题
已经可以在MDK中切到arm-none-eabi工具链,编译出来的elf是可以在CMSIS-DAP中单步调试的。
现在想直接做一个小的makefile工程,用arm-none-eabi工具链,将elf编译出来。
实现文件(.s, .ld, .cpp)在MDK工程中都是有的,但是为了编译效果和MDK一摸一样,就需要知道MDK工程的编译过程的全部命令行参数。
但是,MDK是不提供这些的。如果产生了日志,记录的也很简单,无法知道是咋编译的。
确实有需求知道MDK工程编译的全过程用到的命令行全部参数, 也不是说有多大用,就是想落地和验证我的思想火花。
我要不能落地和验证我的调试想法,我就全身不得劲。
人家ARM官方MDK软件不提供啊, 如果想提供,对于官方来说是挺简单的。
想了想,大概也只能用调试工具来测试了,找到线索之后,手工将编译全过程的命令行参数搞出来。
笔记
实验环境
win10
MDK543a
arm-gnu-toolchain-14.3.rel1-mingw-w64-i686-arm-none-eabi
SysinternalsSuite_2025_0213
前置条件
MDK工程已经是编译通过,正常单步调试的版本。
从MDK命令行编译MDK工程
看uv5的帮助文件,可以知道怎么用uv4.exe(MDK5的执行文件也是uv4.exe)命令行清除工程,完全编译工程。
在MDK目标工程的根目录, 写个.bat辅助测试(用命令行[清除工程,重新编译工程])
uv5_cmd_build.bat
@echo off
rem @file uv5_cmd_build.batset path=C:\Keil_v5\core\UV4\;%path%rem clear prj out
rem UV4.exe -c arm-gcc.uvprojxrem rebuld prj
UV4.exe -r arm-gcc.uvprojx -o build.logcmd
批处理里面有2个命令,测试时,注释掉一条,只执行一条(不是清除工程,就是重新编译工程)
建立arm-gcc环境的cmd命令行
因为MDK5是要用arm-gcc工具链来编译,不确定是不是要在cmd也整出arm-gcc的path环境出来。
也是搞个脚本来弄。
@echo off
rem @file my_arm_gnu_env_only.bat
rem @breif 通用的arm-gcc工具链,编译哪个工程都可以
set path=%~dp0arm-gnu-toolchain\bin;%~dp0gnuwin32\bin;%~dp0curl;%path%
rem set path=C:\nxp\MCUXpressoIDE_25.6.136\ide\;%path%
cmd /k "echo my arm gnu env"
用命令行来编译
// 运行 my_arm_gnu_env_only.bat
// 转到自己的MDK工程目录
D:\my-arm-gnu-toolchain>cd /d D:\my_tmp\uv5\arm-gccD:\my_tmp\uv5\arm-gcc>// 将 uv5_cmd_build.bat 中的编译行注释掉,只留下清除行
执行uv5_cmd_build.bat
执行uv5_cmd_build.bat后,工程中间文件已经被清理干净。
打开Procmon64.exe
确认是已经开始捕获的(确认捕获按钮提示信息的,和左下角正在捕获的提示)。
增加2个过滤如下
过滤1 :进程名字包括 arm-none-eabi, 这样就可以将arm-none-eabi-gcc, arm-none-eabi-as, arm-none-eabi-g++…等arm-gcc的程序过滤下来看。
过滤2 :操作是进程开始,如果MDK要调用外部命令行(e.g. arm-gcc工具链的程序编译.s, .c, .cpp), 就会被捕获住。
按下ok, 过滤器就加好了。
然后清一下屏
修改uv5_cmd_build.bat,注释掉清理工程,打开命令行编译MDK5工程。
用命令行生成完工程后,生成的build.log没大用,只能看到是否编译过了,每个实现文件的编译,最后的链接命令行看不到。
执行uv5_cmd_build.bat,重新产生了工程。
此时,Procmon64.exe主view上,已经捕获和过滤留下了只有arm-gcc编译的命令行。
一共有4条命令,分别对应3个文件的编译(因为我的工程就3个文件:startup_x.s, LPC1768.ld, main.cpp), 和这4个命令完全对的上。
最后, MDK5还将elf转成了.bin.
唯一感到疑惑的地方 :我们自己做makefile来编译,都是arm-gcc后面带参数。
但是MDK5的命令行参数有点怪啊。
D:\Arm GNU Toolchain arm-none-eabi\14.3 rel1\bin\arm-none-eabi-as" @".\startup_lpc17xx._ia
开始没看懂,后来想想,参数看着像一个文件啊。工程下面有没有这个文件?找找
确实有这个文件。
虽然不大懂MDK5怎么玩的,先打开文件看看是啥?
可以看到,arm-gcc命令后面跟的是一个参数文件,参数文件中是命令行参数。
大概命令行参数太多了,用参数文件来装简单点。
将这4个命令的参数文件名都看了一下,后缀都不一样,反正参数文件中的内容都是编译参数。
到此,已经得到了全部编译行的命令行参数,整理一下,就可以做自己的makefile, 能编译出一样的效果来。
整理一下工程中参与编译的实现文件的全部命令行参数
startup_lpc17xx._ia
"D:\Arm GNU Toolchain arm-none-eabi\14.3 rel1\bin\arm-none-eabi-as" @".\startup_lpc17xx._ia"
D:\my_tmp\uv5\arm-gcc\startup_lpc17xx._ia
-mcpu=cortex-m3 -mthumb --gdwarf-2 -mthumb-interwork -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" --defsym __UVISION_VERSION=543 --defsym __GCC=1 --defsym __GCC_VERSION=1431 --defsym LPC175x_6x=1
-alhms=./startup_lpc17xx.lst --MD ./startup_lpc17xx.d -o ./startup_lpc17xx.o "startup_LPC17xx.s"
main.__i
"D:\Arm GNU Toolchain arm-none-eabi\14.3 rel1\bin\arm-none-eabi-gcc" @".\main.__i"
D:\my_tmp\uv5\arm-gcc\main.__i
-c -mcpu=cortex-m3 -mthumb -gdwarf-2 -MMD -pedantic -O0 -mapcs-frame -mthumb-interwork -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include" -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/lib/gcc/arm-none-eabi/14.3.1/include" -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1" -I"D:/Arm GNU Toolchain arm-none-eabi/14.3 rel1/arm-none-eabi/include/c++/14.3.1/arm-none-eabi" -D__UVISION_VERSION="543" -D__GCC -D__GCC_VERSION="1431" -DLPC175x_6x
-Wa,-alhms=./main.lst -o ./main.o "main.cpp"
arm-gcc.lnp
"D:\Arm GNU Toolchain arm-none-eabi\14.3 rel1\bin\arm-none-eabi-gcc" @".\arm-gcc.lnp"
编译elf文件
D:\my_tmp\uv5\arm-gcc\arm-gcc.lnp
-T ./LPC1768.ld -mcpu=cortex-m3 -mthumb -mthumb-interwork -Wl,-Map="./arm-gcc.map" -o "./arm-gcc.elf" "./startup_lpc17xx.o" "./main.o" -nostartfiles
elf 转hex
因为参数比较少,MDK5直接将命令行参数写上了,没有用参数文件。
"D:\Arm GNU Toolchain arm-none-eabi\14.3 rel1\bin\arm-none-eabi-objcopy.exe" -O ihex ./arm-gcc.elf ./arm-gcc.hex
备注
如果不是用调试软件测试,将MDK编译工程的所有命令行参数找出来,那么想自己弄一个makefile编译出相同的效果来,基本不可能(至少生成的elf不一样).
为啥我要做这个实验?因为在MDK中建立的工程的elf,是可以被CMSIS-DAP调试器正常单步的。
而基于eclipse的IDE(e.g. MCUXPresso, EclipseCPP)都是可以直接引入makefile工程的,只要能编译过,就可以在IDE中单步调试。
所以想搞一个最小化的makefile版实验工程,用eclipse IDE引入,(相当于将能在MDK5中能正常单步调试的elf,原样搬到基于eclipse的IDE中)看看是否可以正常单步调试?
实验过后,我就能知道是编译参数有问题,还是用的硬件调试器固件版本低或者应该用其他的硬件调试器(不用板载的CMSIS-DAP, 而是用独立的LPC-LINK2, MCU-LINK, 或者实在不行,就用独立的JLINK)
那为啥不用eclipse的IDE直接建立makefile工程?答案是不能。
因为eclipse的IDE只能引入makefile工程,而不能新建makefile工程。
现在遇到的问题,同样的一块官方板子,用MDK5新建的工程能正常调试,用MCUXPressoIDE新建的工程能单步调试,但是引入的makefile工程(Smoothieware)不能单步调试。现在可以通过自己做一个和MDK5一摸一样的makefile工程,引入到类eclipseIDE的嵌入式IDE中实验是否能单步调试?能于不能,都能确认一些问题。
现在找问题呢,暂时不确定问题在哪里(是板载调试器不是最新版?还是MCUXPresso的编译命令行参数不一样?),只能一步一步的实验。