文章目录
- NXP - 用MDK建立基于arm-none-eabi工具链的工程框架
- 概述
- 笔记
- 实验环境
- MDK4的版本
- 从小白开始模拟如何"用MDK建立基于arm-none-eabi工具链的工程框架"
- OS
- 安装arm-none-eabi工具链
- 插上实验板
- 新建工程
- 将工具链切到自己指定的arm-gcc
- 调整分散加载文件
- 试试单步调试
- 验证是否由于分散加载文件定义引起的问题
- 备注 - RDDI-DAP Error
- END
NXP - 用MDK建立基于arm-none-eabi工具链的工程框架
概述
想单步调试Smoothieware固件工程,要是用Smoothieware工程提供的办法,就得用MRI + GDB去调试。效率太低了,不想这么搞。
经过权衡和实验(gcc4-mbed 去掉MRI, mbed Studio, LPCXPress, MCU Xpresso, eclipseCPP, MDK)后,准备使用MDK(MDK4和MDK5都可)来建立一个基于arm-none-eabi器具链的工程框架,然后将Smoothieware移植过来。这样就能舒服高效的单步调试。
现在关于工程本身如何建立已经知道了,还有些其他的问题,后续再研究。已经知道问题在哪里了。
先记录一下,如何用MDK建立基于arm-none-eabi工具链的工程框架。
小白,从头到尾来建立工程。如果遇到错误,再去改对应的编译选项。就是由于实验前期遇到一些编译错误问题,这里就模拟我还
最后让程序编译凭借,0错误,0警告。然后再将遇到的不能单步调试的障碍原因抛出,后续再解决。
笔记
“用MDK建立基于arm-none-eabi器具链的工程框架”这个问题是没有完整文档的,但是MDK提供了从默认ARMCLANG程序链切到arm-gcc工具链的UI选项,说明这一定是一个烂大街的问题,不难。
基于搜索引擎是找不到该问题的解决方法的。
找了10多个工程后,终于看到大神如何在MDK中用arm-gcc程序链干活的了 就是后来去github观摩大神们的作品, 看谁用了MDK工程,并且利用了arm-none-eabi工具链. 继而将工程迁出到本地,看看MDK参数部署,再自己建立工程,出现错误后,再比对大神们的正常工程,这就可以得出正确的结论了。如果一个大神的工程没有涉及到该知识点,那就再找一个大神的工程看,我大概
其实,搜索资料也是需要经验的。"有事问百度"只适合小白程度的入门级同学,能用百度搜到的东西都是烂大街的入门级的知识点。
再细节一些的知识点,只要知道如何搜索资料,再加上自己实验,都是不难的。就怕找不到资料(连一个有效线索都没有)。
实验环境
MDK4和MDK5都是可以的。
源于本次要单步调试LPC1768/1769的Smoothieware的工程,MDK4本身就包含LPC17xx的MCU的库。那就先用MDK4来实验。
知道了正确流程后,用MDK5也是一样的,选项差别不大,只是UI选项表明的稍有不同。
现在就模拟一个小白来做实验(将遇到的障碍和解决途径记录下来).
MDK4的版本
MDK4最终的版本是MDK474, ARM官方文档推荐用MDK460.
掌握方法后,用哪个版本都行。源于只要将参数设置对了,用哪个MDK版本都可以。
我就用MDK460来实验。
从小白开始模拟如何"用MDK建立基于arm-none-eabi工具链的工程框架"
OS
win10
安装arm-none-eabi工具链
用当前官方最新版的14.3.rel1
官方提供有安装版的,也有解压版的。
我这里选用的是官方编译好的解压版本。
安装/释放到自己的本地目录 D:\my-arm-gnu-toolchain\arm-gnu-toolchain
插上实验板
实验板只要是LPC1768/1769的MCU就行。
这里我采用OM11043(mbed-NXP-LPC1768)的官方板子,将板子用USB线连上编写机,编写机可能识别板子的CMSIS-DAP设备。
新建工程
手工建立工程目录 D:\my_tmp\uv4\case2


MCU选为LPC1768
MDK根据版本不同,可能会主动给予MCU编程相关的系统实现, 也可以不选择MDK献出的文件, 因为移植开源工程,东西都是全的,不应该MDK来提供。
这里为了演示报错场景,选择是.
将设备链切到自己指定的arm-gcc
MDK默认的工具链是ARMCLANG.

一旦切换了工具链,编译的参数都变了,要求重新核对参数。
尝试先模拟小白,先编译一下工程
这些报错,是说MDK默认提供的这个启动.s的语法是不对的。
因为默认提供的启动.s, 只适合于ARMCLANG的工具链。
此时,要将工程中的不合适的.s删除,添加arm-gcc版本的.s.
现在从Smoothieware工程,将.ld和.s拷贝过来。
对于ARMCLANG设备链,用的分散加载文件是.sct; 对于arm-gcc工具链,用的分散加载文件是.ld或者.lds. 语法是不一样的。


配备分散加载文件


尝试编译工程
现在出了一个很奇怪的报错,是说gcc编译时的参数’-W1’不对。
-Wl参数是个链接时的参数,现在还没到链接阶段呢,报错好奇怪。
且这个参数无法通过UI选项去掉,一直存在。
后来通过比对github大神的工程,知道了,原来要勾选"产生map文件"才行。
默认的Listing是没有map文件的,需要勾选"产生map材料"
Listing产生的这些辅助文件,对于查看编译的过程, 对于优化程序是有帮助的,就全勾上。
再尝试编译,没有’-W1’报错了。
现在看到,有个SystemInit()没实现。去看.s
用户要实现的一个函数,用来初始化硬件。正常的SystemInit函数要完成初始化时钟,gpio这些外设。就是从.s看,这
为了简单,就添加一个空函数。这个空函数要添加在自己的构建中。自己的实现可以是.c, 也能够是.cpp.
Smoothieware工程是一个C和C++混编的工程,这里我们就用.cpp.
在工程目录下,手工新建my_main.cpp, 添加空函数SystemInit(), 如下:
现在提示_start函数没定义,是在Reset_Handler中用到的。看看.s
在x86/x64的win工具中,还要做C运行时库的初始化,然后由_start函数调用main函数,才进入应用层的实现。就是_start函数,如果
对于固件工程,Reset_Handler就相当于_start函数,SystemInit就相当于做了C运行时库的初始化,_start函数就相当于main函数。就是但
看了大神的固件工程搭建,验证了这个判断。
这时,可以将_start改为main, 然后构建自己的main就行。
个合适的选择。就是但是考虑到不能改系统达成,因此在自己的my_main.cpp中,实现_start函数
现在应用就编译过了。
试试单步调试
验证是否由于分散加载记录定义引起的困难
先看一下好的.sct生成的map, 再看一下.ld生成的map.
在比较.sct内容和.ld的内容,排除语法上的区别,看看定义的内存访问地址和访问权限是否一致。
大概率是.ld材料引起的问题。
因为Smoothieware的原始工程,并不是一个从头跑到尾的正常工程。而是由bootloader程序升级的程序。
程序入口地址, Reset例程的地址,中断函数表的地址和正常的固件工程是不一样的。
该实验还在进行中,后续笔记中会记录。
备注 - RDDI-DAP Error
假如调试器硬件或者配备有挑战(包括但是不限于, 没连接调试器,调试器没上电,SWD引脚接触不好, SWD时钟选的太高了),会在单步调试链接时,看到"RDDI-DAP Error"的提示。
假设本来是SWD方式联机的调试器(e.g. 板载的LPC-LINK), 却选成了JTAG连接方式,在参数选项对话框中就能看到"RDDI-DAP Error"的提示。
