![](/img/trans.png)
[英]How should members of volatile class objects handle pointer and array members?
[英]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 States
、 getState() 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.