如何在搭载了RT-Thread系统的STM32平台上使用C++?

640?wx_fmt=jpeg

简介

本文描述了如何使用在搭载了 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的封装)、功耗“轻微”。

如何在搭载了RT-Thread系统的STM32平台上使用C++?_第1张图片

如何在 STM32 上使用 C++


准备工作


1、下载 RT-Thread 源码

2、下载 ENV 工具

3、进入rt-thread\bsp\stm32f411-st-nucleo 目录,检查 BSP rtconfig.py 文件和 SConstruct 文件是否支持 C++ 配置,如下图所示

检查 rtconfig.py 文件中对 C++ 的支持

如何在搭载了RT-Thread系统的STM32平台上使用C++?_第2张图片

检查 SConstruct 文件中对 C++ 的支持

如何在搭载了RT-Thread系统的STM32平台上使用C++?_第3张图片

打开 C++ 支持:

打开 Env 工具,在 Env 命令行中输入 menuconfig,进入配置界面,使用 menuconfig 工具(学习如何使用)配置工程。在 menuconfig 配置界面依次选择 RT-Thread Components ---> C++ features ---> Support C++ features,如图所示:


如何在搭载了RT-Thread系统的STM32平台上使用C++?_第4张图片

编译工程: scons --target=mdk5 1. 生成 mdk5 工程,将示例代码附带的 main.cpp 替换掉 BSP 中的 main.c 并重新加入到工程中,如图所示:

如何在搭载了RT-Thread系统的STM32平台上使用C++?_第5张图片

编译,下载程序,在终端输入 help 命令可以看到 test_cpp 已经添加成功了。


如何在搭载了RT-Thread系统的STM32平台上使用C++?_第6张图片

运行 C++ 程序:

在终端输入 test_cpp 运行结果如下图所示。

如何在搭载了RT-Thread系统的STM32平台上使用C++?_第7张图片

C++ 全局对象构造函数的调用


RT-Thread 中对全局对象构造函数的实现中,以 GNUC 为例,在 rt-thread\components\cplusplus 目录下的 crt_init.c 文件中对 C++ 进行了系统初始化, 在特定的 BSP 目录下,连接脚本文件 link.lds 为 C++ 全局构造函数的代码分配了段,使 C++ 全局对象构造函数链接后能够存放在指定的段中。如下图所示:

如何在搭载了RT-Thread系统的STM32平台上使用C++?_第8张图片

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)();1011    return 0;12}13INIT_COMPONENT_EXPORT(cplusplus_system_init);RT_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__ = .);
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    } > CODE7    __exidx_end = .;
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        }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\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    }3031    MSH_CMD_EXPORT(throw_exceptions, throw cpp exceptions);#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(63);
21            rt_kprintf("there is no err\n");
22            div_func(40);                                   /* 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 运行结果如下图所示。

如何在搭载了RT-Thread系统的STM32平台上使用C++?_第9张图片

到这一步为止,如何在搭载了 RT-Thread 系统的 STM32 平台上如何使用 C++ 的介绍就结束了。

参考资料


1、ENV 用户手册

https://www.rt-thread.org/document/site/programming-manual/env/env/


2、STM32F411-ST-NUCLEO BSP 源码

https://github.com/RT-Thread/rt-thread/tree/master/bsp/stm32/stm32f411-st-nucleo

(请将以上链接复制至外部浏览器打开)

640?

1.一个华为人19年的工作体会:一颗电容会造成数亿损失

2.图灵奖得主大卫·帕特森宣布依托清华-伯克利深圳学院建设RISC-V国际开源实验室

3.MCU AI开发者福音:OPEN AI LAB发布Tengine-Lite预览版与关键词识别算法“小智”

4.万年不变的Top3终于变了,6月编程语言排行榜

5.没拿到钱,我把客户的项目开源了!

6.从“谈芯”走向“用芯” ,RISC-V未来前景光明?

640?wx_fmt=gif

免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。

你可能感兴趣的:(如何在搭载了RT-Thread系统的STM32平台上使用C++?)