欢迎光临散文网 会员登陆 & 注册

在arm-gcc的环境下使用C/C++混合编程开发stm32

2022-12-07 02:25 作者:奥大梨呀  | 我要投稿

    有的时候在用C进行一些面向对象的编程时,总需要考虑很多事情。尽管C也可以做面向对象编程,Linux内核就是这么做的。只是对于我们自己开发而言相对较麻烦,需要考虑很多事情,自己建立对象模型,再用函数指针实现对象的方法等,太过于繁琐。在需要实现面向对象编程时,C++会是一个不错的选择。

由于某些原因,我开发stm32程序的平台已经从MDK5转到了arm-gcc + vscode +openocd的组合模式。MDK5是支持C/C++混合编程的,而且设置方法非常简单,网络上教程一堆。

那么对于arm-gcc如何配置呢,下文细说。

首先需要使用stm32CubeMX生成一个基于Makefile的工程,生成后的工程目录如下:

 

工程目录

ST的库虽然都是.c文件,但是都做了C/C++混合编程的处理,我们只需要修改Makefile即可。

①增加C++文件列表

效仿Makefile里C文件和汇编ASM文件列表的写法,添加C++的文件列表,往后所有.cpp文件都往此处添加。


②添加arm-g++编译器

使用arm-g++用来编译.cpp文件


③添加CPP全局宏定义

还是效仿C全局宏定义的写法,虽然可以直接使用C的,但是还是规范些好,万一以后要添加呢。


④添加CPP编译选项

还是一样,效仿C的写法,不过,在CPPFLAGS后再添加2个选项

-fno-rtti -fno-exceptions

-fno-rtt 表示不使用RTTI,即运行时类型识别,这意味着代码中不能使用typeid和dynamic_cast,但这可以使编译后的固件文件减小。

-fno-exceptions 表示不捕获程序异常,此选项也可以减小编译后的固件文件大小。

⑤添加关联信息

这一项是编译时生成关联信息,对链接有影响,还是直接拷贝C的实现。


⑥添加CPP文件列表

这里是利用makefile的语法从一堆源文件名生成对应的.o文件名,并且设置了.c .cpp .s文件的搜索路径。

⑦添加.cpp文件的编译规则

从上面的.c文件编译规则复制下来,将其改成CPP规则即可。

@和echo是我手动添加的,用于精简编译输出信息,与本文内容无关。


    完成以上步骤后,Makefile就修改完成了,下面写一个Led.cpp测试一下

 

这里只放.h文件,c文件都是一些方法的实现,避免篇幅太长就不放了。

再看看main.cpp:

 

    如果需要直接在原工程的main.c中编写C++程序,则需要将main.c修改为main.cpp。

这里我就修改了。

注意,我们在编写头文件的时候,最好加上extern “C”,用宏__cplusplus限制。因为C文件调用某个写在CPP的函数是会报错的,因为C++支持重载而C不支持。因此需要把一些可能会在C文件调用的函数的声明用extern “C”{}限制,否则在链接那一步会报错在C文件里调用的这个函数找不到。

在上面main.cpp中,SysTick_Callback()是我在定义的一个弱函数,他会在SysTick中断中被调用,这里就是因为在main.cpp中实现,原本的弱函数不会被替换,因此需要加上extern”C”{}限制才行。

    另外,全局对象的构造函数是在程序还未进入main函数就执行了的,如果构造函数里有与硬件相关的代码就可能出错。所以尽量避免使用构造函数,除非你使用newdelete或者只使用局部变量。上面代码里可以看出我对于全局对象是使用静态方法Create进行初始化的。

编译顺利通过

编译通过

最终程序烧录到stm32上也能正常运行,LED正常闪烁,这里我就不放效果图了。

最后附上我自己的Makefile完整版供参考


在arm-gcc的环境下使用C/C++混合编程开发stm32的评论 (共 条)

分享到微博请遵守国家法律