繁体   English   中英

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

[英]Use volatile class members for interrupt handling

让我们假设它是一些ARM控制器的嵌入式开发。 假设我们有一些变量,它可以从中断或“​​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 ......那么volatile就像 C++ 类的瘟疫一样,并且必须使周围的一切都挥发掉。 volatile enum class StatesgetState() volatile等。这对我来说不太好(我错了吗?)

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

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

如果您的程序中只需要 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;

我相信如果类对象本身是volatile你只需要volatile限定方法。 但是,如果您只是将相关成员变量设置为volatile ,我认为您不会有任何问题。 我已经成功地完成了这个(即它编译/运行) 类似于你想要实现的目标......例如:

class SomeSubsystem
{
public:
    ...
    void onMainThread(void); // no volatile qualification necessary
    void onInterrupt(void);  // "
private:
    States volatile mState;  // only make the relevant member variables volatile
}

SomeSubsystem aSubsystem;    // don't make the object volatile
...
aSubsystem.onMainThread();
aSubsystem.onInterrupt();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM