本文描述了如何使用在搭载了 RT-Thread 系统的 STM32 平台上使用 C++,包括 C++的配置和应用等,并给出了在STM32F411 NUCLEO开发板上验证的代码示例。
硬件平台简介
本文基于意法半导体STM32F411 NUCLEO开发板,给出了 C++的具体应用示例代码,由于RT-Thread上层应用API的通用性,因此这些代码不局限于具体的硬件平台,用户可以轻松将它移植到其它平台上。
STM32F411 NUCLEO是意法半导体推出的一款基于ARM Cortex-M4内核的开发板,最高主频为100Mhz,该开发板具有丰富的板载资源,可以充分发挥STM32F411RE 的芯片性能。
STM32F411RE从属于销量名列前茅的STM32F4系列,众所周知,F4是STM32主打高性能和数字信号处理的“轻奢”系列。
“奢侈”在F4作为内核为Cortex-M4 (DSP+FPU)的MCU,可选180MHz 主频、2M Flash/384KB RAM、Chrom-ART加速器、MPI-DSI接口、延伸到125度的工作温度、DFSDM数字滤波器以及各种常见的音频(SAI)、连接(Ethernet、Camera、USB)、控制(CAN、UART、I2C)、存储(FMC、2/4/8 bits SPI、SDMMC)外设。
“轻”在价格让人“轻松”、尺寸“轻巧”(不到3mm*3mm的封装)、功耗“轻微”。
如何在STM32上使用C++
准备工作
1、下载RT-Thread 源码
2、下载ENV 工具
3、进入rt-threadspstm32f411-st-nucleo目录,检查 BSPrtconfig.py文件和SConstruct文件是否支持C++配置,如下图所示
检查rtconfig.py文件中对C++的支持
检查SConstruct文件中对C++的支持
打开C++支持:
打开Env工具,在Env命令行中输入menuconfig,进入配置界面,使用menuconfig工具(学习如何使用)配置工程。在menuconfig配置界面依次选择RT-Thread Components ---> C++ features ---> Support C++ features,如图所示:
编译工程:scons --target=mdk51. 生成mdk5工程,将示例代码附带的main.cpp替换掉BSP中的main.c并重新加入到工程中,如图所示:
编译,下载程序,在终端输入help命令可以看到test_cpp已经添加成功了。
运行C++程序:
在终端输入test_cpp运行结果如下图所示。
C++ 全局对象构造函数的调用
RT-Thread中对全局对象构造函数的实现中,以GNUC为例,在rt-threadcomponentscplusplus目录下的crt_init.c文件中对C++进行了系统初始化, 在特定的BSP目录下,连接脚本文件link.lds为C++全局构造函数的代码分配了段,使C++全局对象构造函数链接后能够存放在指定的段中。如下图所示:
crt_init.c文件完成了C++系统的初始化工作
C++系统初始化部分:
1RT_WEAKintcplusplus_system_init(void) 2{ 3typedefvoid(*pfunc)(); 4externpfunc__ctors_start__[]; 5externpfunc__ctors_end__[]; 6pfunc*p; 7 8for(p=__ctors_start__;p< __ctors_end__; p++) 9 (*p)();1011 return 0;12}13INIT_COMPONENT_EXPORT(cplusplus_system_init);
在cplusplus_system_init函数中,将全局对象的构造函数依次链接到了链接脚本文件中为其分配的段中,并且调用了RT-Thread组件自动初始化的宏INIT_COMPONENT_EXPORT,所以在链接的时候,C++全局对象构造函数所产生的目标文件就被链接到了__ctors_start__和__ctors_end__组成的段中。
链接脚本中为C++全局构造函数分配的段部分:
1PROVIDE(__ctors_start__=.);2KEEP(*(SORT(.init_array.*)))3KEEP(*(.init_array))4PROVIDE(__ctors_end__=.);
__ctors_start__分配了C++全局构造函数段的起始地址,__ctors_end__分配了C++全局构造函数段的结束地址,所以全局构造函数在系统初始化的时候,就会被链接到这里分配的段地址中。
RT-Thread C++ 异常说明
同样,在链接脚本文件link.lds中,也为C++异常分配了段地址:
1__exidx_start=.;2ARM.exidx:3{4*(.ARM.exidx*.gnu.linkonce.armexidx.*)5_sidata=.;6}>CODE7__exidx_end=.;
__exidx_start分配了C++异常的起始地址,__exidx_end分配了C++异常的结束地址,当异常产生的时候,就会被分配到指定的段地址中。
这里以一个C++除零异常的抛出和捕获为例:
1#include2 3#defineMIN_VALUE(1e-4) 4#defineIS_DOUBLE_ZERO(d)(abs(d)< MIN_VALUE) 5 6 double div_func(double x, double y) 7 { 8 if (IS_DOUBLE_ZERO(y)) 9 {10 throw y; /* throw exception */11 }1213 return x / y; 14 }1516 void throw_exceptions(void *args)17 {18 try 19 {20 div_func(6, 3);21 rt_kprintf("there is no err ");22 div_func(4, 0); /* create exception*/23 rt_kprintf("you can run here? ");24 }25 catch(double) /* catch exception */ 26 {27 rt_kprintf("error of dividing zero ");28 }29 }3031 MSH_CMD_EXPORT(throw_exceptions, throw cpp exceptions);
当除零异常发生的时候div_func函数会抛出一个异常,在throw_exceptions函数中会去捕获这个异常。
下载代码,并在终端输入throw_exceptions运行结果如下图所示。
到这一步为止,如何在搭载了RT-Thread系统的STM32平台上如何使用C++的介绍就结束了。
-
STM32
+关注
关注
2268文章
10881浏览量
355254 -
C++
+关注
关注
22文章
2106浏览量
73558
原文标题:如何在搭载了RT-Thread系统的STM32平台上使用C++?
文章出处:【微信号:mcuworld,微信公众号:嵌入式资讯精选】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论