c++ - 使用 volatile 类成员进行中断处理

标签 c++ embedded interrupt

让我们假设它是一些ARM Controller 的嵌入式开发。假设我们有一些变量,它可以从中断或“​​mainThread”分配 - (它是“主循环”还是 RTOS 线程)。在C世界volatile在这种情况下应该使用关键字,代码可能如下所示:

/* Some subsystem .C file */
static volatile uint8_t state;

void on_main_thread(void) {
    state = 1;     /* Changing state in this context */
}

void on_interrupt(void) {
    state = 0;     /* Changing state from interrupt */
}

uint8_t get_state(void) {
    return state;  /* Getting the state in whatever context */
}
volatile在这种情况下,关键字是必不可少的。现在我们公司把一些代码改写成C++,同样的子系统例子是这样的(我这里用enum来强调这个问题)
class SomeSubsystem
{
public:
    enum class States
    {
        Off,
        Idle,
        Up,
        Down,
    };


    States getState() const { return mState; }

    void onMainThread(void) {
           mState = States::Idle;     // Changing state in this context
    }

    // Somehow this function is called from the interrupt
    void onInterrupt(void) {
           mState = States::Up;     // Changing state from interrupt
    }
private:
    States mState;   // <-- Here! Volatile? 
//...
};

现在 States mState应该是可变的,因为它在不同的上下文之间共享。但如果将其设置为 volatile... 那么 volatile就像 C++ 类的瘟疫一样,你必须 volatile 周围的一切。赞 volatile enum class States , getState() volatile等等,这对我来说不好看(我错了吗?)

所以。在 C++ 中处理这种情况的正确方法是什么?

附言我会尝试将“这种情况”定义为:“可能使用来自不同上下文(如中断和正常代码执行)的类成员”

最佳答案

如果您的程序中只需要 SomeSubsystem 的单个实例(我假设根据您发布的 c 代码进行假设),这可能会起作用。

如果您需要多个实例,那么也许您可以将 mState 修改为 States 数组或一些类似的结构。

class SomeSubsystem
{
public:
    enum class States
    {
        Off,
        Idle,
        Up,
        Down,
    };


    States getState() const { return mState; }

    void onMainThread(void) {
           mState = States::Idle;     // Changing state in this context
    }

    // Somehow this function is called from the interrupt
    void onInterrupt(void) {
           mState = States::Up;     // Changing state from interrupt
    }
// Make mState public in order to access it from the rest of your code
// Otherwise, keep it private and create static set/get functions
public:
    static volatile States mState;   // <-- Here! Volatile? 
//...
};

然后在某处定义 mState(例如在 SomeSubsystem.cpp 中)
volatile SomeSubsystem::States SomeSubsystem::mState = SomeSubsystem::States::Off;

现在您可以像这样从代码中的任何位置访问 mState
SomeSubsystem::mState = SomeSubsystem::States::Off;

关于c++ - 使用 volatile 类成员进行中断处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38610847/

相关文章:

C++/MFC 错误访问控件的变量

c++ - int 参数和 int& 参数的双参数

c++ - 我怎么知道有多少客户端连接到我的服务器与 Qt

c - 同一地址的不同指针类型

c - 为什么sem_wait不会在中断时解除阻塞(并返回-1)?

c++ - Mac OS X 目标的体面交叉编译器

c++ - 幻方,我无法用它来对行、列和对角线求和

在开关盒中类型转换成更大的类型

c - 如何从 i2c io 扩展器 linux 请求 GPIO 中断(失败并显示 -EINVAL)

c - 使用 Arduino Uno 生成正弦波的代码是否有效/合理?