在 MCU 上运行高级 C++ 软件

本文探讨了在MCU上运行C++软件的挑战,特别是关于全局构造函数和析构函数、new/delete操作符、RTTI和异常处理的限制。文章通过Embox RTOS展示了如何克服这些限制,支持可重新启动的C++应用程序,以及如何处理多线程功能。Embox通过提供不同级别的C++支持选项,包括对libstdc++的兼容层,使得在MCU上运行复杂的C++项目如OpenCV成为可能。
摘要由CSDN通过智能技术生成

使用 C++ 开发用户应用程序有很多优势,因此该语言在包括基于 MCU 的系统中变得越来越流行也就不足为奇了。“mbed”项目完全专注于这种语言。许多 RTOS 提供 C++ 兼容层,但与“大”系统(具有 MMU)相比,大多数 RTOS 都有一些限制。在本文中,我们将研究 C++ 的内部结构并找出造成这些限制的原因。

MCU 上的 C++ 有两个主要限制:重新启动应用程序和标准 C++ 库的多线程功能。

本文中的大多数示例都将在Embox RTOS上进行考虑。该 RTOS 允许在 MCU 上运行像OpenCV这样复杂的 C++ 项目。该项目需要标准 C++ 库中的线程支持。此外,与 MCU 上的其他 RTOS 不同,Embox 允许重新启动 C++ 应用程序。我们将使用带有外部 SDRAM 的 STM32F769i 板来演示 OpenCV,因为该框架需要数百 KB 的 RAM。但是,几千字节的 RAM 足以运行简单的 C++ 应用程序。

基本语法

C++ 语言的语法由编译器实现。这些功能包含在名为“libsupc++”的语言支持库中。在应用程序运行时必须处理一些部分。例如,需要处理全局构造函数和析构函数。

全局构造函数和析构函数

让我们看看任何 C++ 应用程序如何与全局构造函数和析构函数一起工作。所有全局 C++ 对象都是在程序调用 main() 之前创建的。为此有一些特殊的部分:“.init_array”、“.init”、“.preinit_array”、“.ctors”。这些是指向函数的指针数组,必须从头到尾遍历,调用数组的相应元素。

Embox 中调用全局对象构造函数的代码如下:

void cxx_invoke_constructors(void) {
   extern const char _ctors_start, _ctors_end;
   typedef void (*ctor_func_t)(void);
   ctor_func_t *func = (ctor_func_t *) &_ctors_start;
   ...
   for (; func != (ctor_func_t *) &_ctors_end; func++) {
       (*func)();
   }
}

让我们看看 C++ 应用程序的终止是如何工作的,即调用全局对象的析构函数。有两种方法。

首先,编译器中最常用的是使用来自 C++ 应用程序二进制接口 (ABI) 的 __cxa_atexit()。这是 POSIX atexit() 的类似物。也就是说,您可以注册将在程序终止期间调用的特殊处理程序。当在应用程序开始时调用全局构造函数时,如上所述,还有编译器生成的代码,用于使用 __cxa_atexit() 注册析构函数处理程序。

第二种方法是将指向析构函数的指针存储在特殊部分“.fini_array”和“.fini”中。如果指定了“-fno-use-cxa-atexit”标志,GCC 编译器将使用这种方式。在这种情况下,在应用程序终止期间,必须以相反的顺序(从高地址到低地址)调用析构函数。这种方法不太常见,但在微控制器中很有用。因为,在这种情况下,可以找出编译时需要多少个处理程序。

Embox 中调用全局对象析构函数的代码如下:

int __cxa_atexit(void (*f)(void *), void *objptr, void *dso) {
   如果(atexit_func_count >= TABLE_SIZE){
       printf("__cxa_atexit: 静态销毁表溢出。\n");
       返回-1;
   }
   atexit_funcs[
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值