debug - MDK - arm-none-eabi - 将MDK工程编译过程的所有命令行参数找出来

文章目录

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

bash 复制代码
@echo off
rem @file uv5_cmd_build.bat

set path=C:\Keil_v5\core\UV4\;%path%

rem clear prj out
rem UV4.exe -c arm-gcc.uvprojx

rem rebuld prj
UV4.exe -r arm-gcc.uvprojx -o build.log

cmd

批处理里面有2个命令,测试时,注释掉一条,只执行一条(不是清除工程,就是重新编译工程)

建立arm-gcc环境的cmd命令行

因为MDK5是要用arm-gcc工具链来编译,不确定是不是要在cmd也整出arm-gcc的path环境出来。

也是搞个脚本来弄。

bash 复制代码
@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"

用命令行来编译

bash 复制代码
// 运行 my_arm_gnu_env_only.bat
// 转到自己的MDK工程目录
D:\my-arm-gnu-toolchain>cd /d D:\my_tmp\uv5\arm-gcc

D:\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的命令行参数有点怪啊。

bash 复制代码
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

bash 复制代码
"D:\Arm GNU Toolchain arm-none-eabi\14.3 rel1\bin\arm-none-eabi-as" @".\startup_lpc17xx._ia"
bash 复制代码
D:\my_tmp\uv5\arm-gcc\startup_lpc17xx._ia
bash 复制代码
-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

bash 复制代码
"D:\Arm GNU Toolchain arm-none-eabi\14.3 rel1\bin\arm-none-eabi-gcc" @".\main.__i"
bash 复制代码
D:\my_tmp\uv5\arm-gcc\main.__i
bash 复制代码
-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

bash 复制代码
"D:\Arm GNU Toolchain arm-none-eabi\14.3 rel1\bin\arm-none-eabi-gcc" @".\arm-gcc.lnp"

编译elf文件

bash 复制代码
D:\my_tmp\uv5\arm-gcc\arm-gcc.lnp
bash 复制代码
-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直接将命令行参数写上了,没有用参数文件。

bash 复制代码
"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的编译命令行参数不一样?),只能一步一步的实验。

END

相关推荐
LostSpeed17 小时前
MDK-ARM的所有版本名称
mdk
春日见18 小时前
虚拟机上由于网络问题无法正常git clone
linux·服务器·网络·人工智能·git·ubuntu·debug
春日见3 天前
ubuntu以前可以联网,突然无法上网了
linux·服务器·ubuntu·debug
Lei活在当下3 天前
【项目踩坑实录】并发环境下,Glide缓存引起的图片加载异常
android·debug·glide
无人装备硬件开发爱好者6 天前
深度解析:STM32 MDK 工程 HEX 文件转 BIN 文件 —— 原理、方法、优缺点与实战指南(下)
stm32·嵌入式软件·mdk·hex2bin
Aspect of twilight7 天前
vscode python debug方式
ide·vscode·python·debug
sulikey13 天前
如何使用 Visual Studio 代替 OllyDbg 完成汇编语言实验
汇编·ide·debug·visual studio·ollydbg
vim怎么退出1 个月前
React 项目诡异白屏事故复盘:JSON.stringify、循环引用、setState 死循环,一个都没跑
前端·debug
艾小码1 个月前
为什么你的Vue组件总出bug?可能是少了这份测试指南
前端·vue.js·debug
eason_fan1 个月前
解决 Monorepo 项目中 node-sass 安装失败的 Python 版本兼容性问题
前端·debug