传统单片机开发环境是 Keil IDE,它为开发者提供了一套非常方便的开发环境,我们只需要进行很少的设置就可以完成单片机程序的编写、编译、烧录和调试。但 Keil 也有着过于陈旧、闭源和无法跨平台等缺点,用惯了 CLion、VSCode 等现代编译器很难再习惯 Keil;而且众多的开源软件都是使用开源编译链开发的,如果我们对开源编译链没有了解的话,很难上手众多的开源项目。
众多的原因使我们放弃了 Keil IDE,转向 GNU Arm Embedded Toolchain 配上现代编辑器的方案。但不可否认,自己配置开发环境并编写 Makefile 或者 CMake 并不是一件简单的事情。如果我们使用 HAL 库开发 STM32,我们可以使用 STM32CubeMX 配上 CLion 的方案,在 CubeMX 上进行图形化配置并生成 Makefile 工程,最后利用 CLion 对 CubeMX 的支持,直接进行一键配置和开发(更详细的各种方案的对比可以看我另一篇文章)。但如果使用固件库开发 STM32,现在我还没有找到非常方便的配置方案,所以我写了一个自动化的 Python 脚本
Keil2Makefile
,可以自动读取 Keil 工程的配置来生成 Makefile,随后便可以轻松地抛弃 Keil 进行开发。
Python:运行脚本
GNU Arm Embedded Toolchain
:提供编译器、链接器
MinGW:提供 Make 指令
VSCode:代码编辑器
首先在 Github(
https://github.com/Qrpucp/Keil2Makefile)
或 Gitee(
https://gitee.com/qrpucp/Keil2Makefile)
上下载 Keil2Makefile 脚本,下载完成后将整个文件夹复制至 Keil 工程的根目录。
随后在 VSCode 中打开终端,在该目录下运行命令
cd Keil2Makefile/Source/ && python Keil2Makefile.py
成功运行后可以看到一系列提示,此时在根目录下已经自动生成了 Makefile 文件。
我们回到原来的目录进行编译,运行命令 cd …/… && make。
如果不出问题的话,随着一系列文件的编译,最后我们可以看到成功编译出来的 elf、hex 和 bin 文件。
Config/Config.yml 为用户配置文件,在这个文件中可以进行一系列的配置,默认配置如下:
debug_build
0:debug 模式
1:release 模式
optimization:编译器优化选项
generate_mode
force_regenerate:强制重新生成 Makefile,所有配置均进行更新
auto_detect:若不存在 Makefile,则创建 Makefile;如果已存在 Makefile,则只会进行必要参数的更新
auto_add_file:[ 该功能还未实现 ]
0:不自动添加文件
1:自动添加 C 语言文件
build_dir:输出文件目录
modify_asm
0:不修改汇编语言文件后缀名
1:修改汇编语言文件后缀名
虽然 Keil2Makefile 脚本可以自动化生成 Makefile,但因工程的不同,仍不能保证可以直接成功编译,事实上,脚本不可能完成所有转换工作,下面我将解释无法编译的某些情况和解决方法。
1.汇编文件
最难解决的就是汇编语言文件的问题,Keil 使用的编译器和 GNU 的编译器能够识别的汇编语言格式不一样,甚至连后缀名都不同,Keil 能识别的后缀名是 .asm,而 GNU 编译器能识别的后缀名是.s。我们需要手动替换每一个汇编语言文件,Keil2Makefile 脚本可以预先储存 STM32 的启动文件,实现自动替换的功能,但我们在工程中经常还会用到别的汇编语言文件,比如 UCOS 就包含了很多汇编语言文件,这些文件脚本不可能实现自动替换,只能我们手动去寻找并替换。不过一般大型工程都会为每一种编译器提供对应的汇编语言文件,我们不用担心不支持 GNU 编译器的问题。
2.重复定义
每种编译器都会自带一些变量类型的定义,如果这些定义和原来代码中的定义重复了,则删除掉原代码中的定义即可。
3. C/C++混合编程
如果工程里既有 C 语言代码又有 C++ 代码,那么需要使用 g++ 进行链接,且在 C 语言文件中需要在首尾加上如下的预编译指令。
#ifdef __cplusplus
extern "C" {
#endif
//code
#ifdef __cplusplus
#endif
4. printf 重定向
在 GNU 编译器中,printf函数的重定向方法与 Keil 编译器不同,关于这个问题网络上有大量的解决方法,我就不重复说明了。
5. 编译器关键词
armcc 中的关键词__asm{NOP;}在GNU编译器中需要替换为 NOP,align(8)需要替换为__attribute((aligned(8)))。除此之外还有许多的关键词需要替换,可以编译报错后再进行替换。如果想要工程同时支持 Keil 编译器和 GNU 编译器,则可以使用条件编译指令判断编译器类型来选择使用哪一种关键词。
Keil2Makefile 脚本通过读取 Keil 工程的配置文件来自动生成 Makefile,因为 Keil 的配置文件多种多样,我仅在自己能找到的工程上进行了测试,并不能保证该脚本对所有 Keil 工程都适用,如果使用该脚本报了错,可以私信找我解决。
该脚本目前支持的单片机型号很少,主要是因为每一个型号的单片机都需要一个链接脚本和启动文件,我现在并没有一种规则可以自动生成它们,只是通过CubeMX 生成后预先保存并在需要的时候进行替换,所以如果该脚本不支持你所使用的单片机型号,只需要使用 CubeMX 生成,然后复制到自己的工程中就可以了,也可以找我在脚本中支持该型号。
我会一直跟进并完善该脚本。
原文链接(感谢原作者):https://blog.csdn.net/weixin_45467056/article/details/123564509