首页 > 解决方案 > 带有参数的嵌入式系统上的最小 C++ 回调

问题描述

我正在嵌入式系统上用 C++ 开发。由于资源限制,我不允许std::function用于我的回调。

我想从软件的上层注册一个回调,并在一个非常低级的驱动程序中执行它。问题是这个回调还需要将参数作为数组传递,我想避免使用全局变量。

低级驱动程序:

using callback = void (*)(uint32_t data[2]);

// extern C because it is executed inside an c style interrupt, don't ask
extern "C" {
static callback global_cb = nullptr;

void ExecuteCallback(uint32_t data[2]) {
    if (global_cb != nullptr) {
        global_cb(data);
    }
}

void Interrupt() {
 // Error occured
    uint32_t logData[2] = { 0, 1}; // Dummy data for stackoverflow
    ExecuteCallback(logData);
} 
}

void low_level_driver::RegisterCallback(callback cb) {
    global_cb = cb;
}


应用层如下所示:

#include "low_level_driver.h"

ResetHandler::ResetHandler() {
    low_level_driver.RegisterCallback(MyCallback);
}

void ResetHandler::MyCallback(uint32_t logData[2]) {
  // log the Data
}

目前我无法以任何可能的方式注册我的回调。我知道我的回调是错误的,或者我尝试在应用程序层中注册它的方式是错误的。需要帮忙。

编辑:不管这个设计有多糟糕。我正在寻找以下内容:基本上只是一种带有参数的回调方法。

标签: c++functioncallbackembedded

解决方案


有 std::function 的替代方法,既不键入擦除也不分配。

我个人最喜欢的是IncludeOS委托实现。它在函数签名之后有两个额外的模板参数,允许自定义回调大小和一些可选的优化,基于它是纯的(基本上是一个自由函数)、可简单复制或两者都不是。这些附加参数的缺点是,如果您使用许多不同的变体,它可能会使您的代码膨胀。

另一种选择可能是 MBed 所做的。他们有一个名为CThunk的类,它甚至在其描述中声明其目的是将回调重定向到非静态成员函数。我还没有使用它,而且 API 看起来不那么现代和花哨,但它可能符合您的需求。


推荐阅读