gpt4 book ai didi

c - 我应该在这个库中使用 volatile 吗(以及在哪里)?

转载 作者:太空宇宙 更新时间:2023-11-04 03:45:12 25 4
gpt4 key购买 nike

我正在使用 Arduino PID library我想在 ISR 中使用它,例如:

ISR(TIMER1_COMPA_vect) {
myPID.compute();
}

但是,我可以看出这是一个的想法,因为 ISR 中使用的变量需要使用 volatile 关键字。好的,所以我这样声明 PID:

PID myPID(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);

然后我用 volatile 声明了 inputoutputsetpoint。但是,该库不接受可变变量。

转换它的第一个想法是在各处添加 volatile。但是我应该添加它吗:

  • 在内部变量之前
  • 在类之前(像上面那样声明它时)还是在头文件中?
  • 在我的库中的变量参数的变量类型?

我该怎么办?

最佳答案

What should I do?

如图所示使用您的代码,不要使用任何 volatile 并开心 :)

volatile 关键字只是向编译器提示一个变量可能会因看不见的路径而改变。如果一个简单的变量只被 ISR 修改,那么将其标记为 volatile 不会有什么坏处。这样的标记可以防止编译器对这样的代码做错误的事情:

volatile int n = 0;

ISR(TIMER1_COMPA_vect) {
n = 1;
}


void loop() {

n = 0;

// At this point the tricky compiler might think
// "n must be zero, why do this comparison?"
// it might also think,
// "hey, I've got the value of n still sitting in a
// register, I don't even have to read it from memory
// The volatile keyword says "stop thinking"

if(n == 1) {
// do something when ISR() occurred just before if()
// a very small window, but it would eventually happen
n = 0;
}

}

对于您的对象,它只是关于 ISR 引入的更改是否会导致该对象的其他用户可能看不到的变量更改。如果 PID 对象通过 compute() 消耗输入和输出的唯一驱动程序,则没有问题。换句话说,compute() 的变化不会影响主循环()

更大的问题应该是一致性,这不是用 volatile 固定的。如果 setpoint 是 32 位整数,则内存中的值不能自动更改。主循环()可能有一条无辜的线

setpoint = setpoint + 20;

但这涉及到从内存中获取值到寄存器中,执行数学运算并写回。在过程中的任何时钟节拍,都可能发生中断。恰好在将 setpoint 的新值存储到内存的过程中,可能会发生中断(最终会发生)。

您可以通过在访问共享对象时禁用主循环 () 中的中断来保护这一点。

nointerrupts()
setpoint = setpoint + 20;
interrupts()

现在您可以确保中断不会在最坏的时刻发生,并在设置点的破坏值上执行 compute()。

关于c - 我应该在这个库中使用 volatile 吗(以及在哪里)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25170821/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com