在 STM32 上使用 C++ 指南

发布时间:2020-4-21 17:33    发布者:嵌入式人生17
STM32 上使用 C++ 指南
简介
本文描述了如何使用在搭载了 RT-Thread 系统的 STM32 平台上使用 C++,包括 C++ 的配置和应用等。并给出了在STM32F411 NUCLEO开发板上验证的代码示例。
硬件平台简介
本文基于意法半导体 STM32F411 NUCLEO开发板,给出了 C++ 的具体应用示例代码,由于RT-Thread上层应用API的通用性,因此这些代码不局限于具体的硬件平台,用户可以轻松将它移植到其它平台上。
STM32F411 NUCLEO是意法半导体推出的一款基于ARM Cortex-M4内核的开发板,最高主频为100Mhz,该开发板具有丰富的板载资源,可以充分发挥STM32F411RE 的芯片性能。
STM32F411RE从属于销量名列前茅的STM32F4系列,众所周知,F4STM32主打高性能和数字信号处理的轻奢系列。
奢侈F4作为内核为Cortex-M4 (DSP+FPU)MCU,可选180MHz 主频、2M Flash/384KB RAMChrom-ART加速器、MPI-DSI接口、延伸到125度的工作温度、DFSDM数字滤波器以及各种常见的音频(SAI)、连接(EthernetCameraUSB)、控制(CANUARTI2C)、存储(FMC2/4/8 bits SPISDMMC)外设。
在价格让人轻松、尺寸轻巧”(不到3mm*3mm的封装)、功耗轻微
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml14784\wps19.png
如何在 STM32 上使用 C++
准备工作
1、下载 RT-Thread 源码
2、下载 ENV 工具
3、进入rt-thread\bsp\stm32f411-st-nucleo 目录,检查 BSP rtconfig.py 文件和 SConstruct 文件是否支持 C++ 配置,如下图所示
检查 rtconfig.py 文件中对 C++ 的支持
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml14784\wps20.png
检查 SConstruct 文件中对 C++ 的支持
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml14784\wps21.png
打开 C++ 支持:
打开 Env 工具,在 Env 命令行中输入 menuconfig,进入配置界面,使用 menuconfig 工具(学习如何使用)配置工程。在 menuconfig 配置界面依次选择 RT-Thread Components ---> C++ features ---> Support C++ features,如图所示:
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml14784\wps22.png
编译工程: scons --target=mdk5 1. 生成 mdk5 工程,将示例代码附带的 main.cpp 替换掉 BSP 中的 main.c 并重新加入到工程中,如图所示:
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml14784\wps23.png
编译,下载程序,在终端输入 help 命令可以看到 test_cpp 已经添加成功了。
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml14784\wps24.png
运行 C++ 程序:
在终端输入 test_cpp 运行结果如下图所示。
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml14784\wps25.png
C++ 全局对象构造函数的调用
RT-Thread 中对全局对象构造函数的实现中,以 GNUC 为例,在 rt-thread\components\cplusplus 目录下的 crt_init.c 文件中对 C++ 进行了系统初始化, 在特定的 BSP 目录下,连接脚本文件 link.lds C++ 全局构造函数的代码分配了段,使 C++ 全局对象构造函数链接后能够存放在指定的段中。如下图所示:
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml14784\wps26.png
crt_init.c 文件完成了 C++ 系统的初始化工作
C++ 系统初始化部分:
1RT_WEAK int cplusplus_system_init(void)
2{
3    typedef void(*pfunc)();
4    extern pfunc __ctors_start__[];
5    extern pfunc __ctors_end__[];
6    pfunc *p;
7
8    for (p = __ctors_start__; p < __ctors_end__; p++)
9        (*p)();
10
11    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 = .;
2    ARM.exidx :
3    {
4        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
5        _sidata = .;
6    } > CODE
7    __exidx_end = .;
__exidx_start 分配了 C++ 异常的起始地址, __exidx_end 分配了 C++ 异常的结束地址,当异常产生的时候,就会被分配到指定的段地址中。
这里以一个 C++ 除零异常的抛出和捕获为例:
1   #include
2
3    #define MIN_VALUE                 (1e-4)                          
4    #define IS_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        }
12
13        return x / y;                                 
14    }
15
16    void throw_exceptions(void *args)
17    {
18        try                                            
19        {
20            div_func(6, 3);
21            rt_kprintf("there is no err\n");
22            div_func(4, 0);                                   /* create exception*/
23            rt_kprintf("you can run here?\n");
24        }
25        catch(double)                                         /* catch exception */     
26        {
27            rt_kprintf("error of dividing zero\n");
28        }
29    }
30
31    MSH_CMD_EXPORT(throw_exceptions, throw cpp exceptions);
当除零异常发生的时候 div_func 函数会抛出一个异常,在 throw_exceptions 函数中会去捕获这个异常。
下载代码,并在终端输入 throw_exceptions 运行结果如下图所示。
file:///C:\Users\Administrator.WIN-STED6B9V5UI\AppData\Local\Temp\ksohtml14784\wps27.png
到这一步为止,如何在搭载了 RT-Thread 系统的 STM32 平台上如何使用 C++ 的介绍就结束了。

本文地址:https://www.eechina.com/thread-585676-1-1.html     【打印本页】

本站部分文章为转载或网友发布,目的在于传递和分享信息,并不代表本网赞同其观点和对其真实性负责;文章版权归原作者及原出处所有,如涉及作品内容、版权和其它问题,我们将根据著作权人的要求,第一时间更正或删除。
您需要登录后才可以发表评论 登录 | 立即注册

厂商推荐

关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表