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

相关推荐
LostSpeed2 天前
NXP - 用MDK建立基于arm-none-eabi工具链的工程框架
nxp·mdk·arm-none-eabi
Qiuner3 天前
历劫波,明真我——Debug Commune
ai·开源·bug·debug·信息差·信息·交流
无责任此方_修行中6 天前
谁动了我的数据?一个 Bug 背后的“一行代码”真凶
后端·node.js·debug
bryant_meng8 天前
【VSCode】Visual Studio Code
ide·vscode·编辑器·ssh·debug
南方者17 天前
【JAVA】【BUG】Java 开发中常见问题的具体示例,结合代码片段说明问题场景及原因
java·后端·debug
风也温柔☆21 天前
idea 拉取分支git pull报错 The branch to pull from should be selected
git·intellij-idea·debug·git pull
XYiFfang1 个月前
【Python+requests】解决Python requests中的ProxyError:SSL版本错误问题详解
python·debug·ssl·常见错误·代理配置
青草地溪水旁2 个月前
C++ 登录状态机项目知识笔记
c++·ubuntu·debug·vscode远程调试
快乐肚皮2 个月前
IntelliJ IDEA Debug 模式功能指南
java·ide·intellij-idea·debug