繁体   English   中英

部分可变变量?

[英]Partially volatile variable?

假设我有一个带有主循环和1毫秒中断的微控制器(如果您不知道那是什么,那只是一个中断主循环执行的任务,而它却在执行某事.....并且它是1毫秒中断,因为它每毫秒发生一次)。

我有一个变量,用于在主循环和毫秒中断之间进行通信:

volatile status_t Status;

现在,我在主循环中有一段代码可以更新Status变量,从而对其进行大量转换:

cli();    // This temporarily turns off interrupts, so we don't 
          // modify the variable unsafely
Status.UpdateStuff();
Status.UpdateOtherStuff();
//etc.

sei();    // Turn interrupts back on

问题在于,每个对Status函数调用都会重写Status ......编译器无法在本地内存中缓存Status的值。

解决此问题的一种可能方法是:

cli();
status_t* localStatus = (status_t*)&Status;
localStatus->UpdateStuff();
localStatus->UpdateOtherStuff();
//etc.

Status = *localStatus;
sei();

真正的问题是这样的:

这是否会做我希望做的事,还是有更好的方法来解决不断刷新变量的问题,而不是让优化器缓存变量?

您的第二个版本可能仍会多次写入微控制器,因为编译器可能没有意识到它可以跨方法调用缓存值(可能只有在方法是内联的情况下才可以确定此值)。 所以我建议制作一个显式的本地副本,而不仅仅是一个本地指针。

cli();
status_t localStatus = Status;
localStatus.UpdateStuff();
localStatus.UpdateOtherStuff();
...
Status = localStatus;
sei();

一个使处理器在禁用中断的情况下运行的时间最小化的示例。 仅当nextStatus没有其他副作用时,此方法才有效。 如果这样做,则必须在成功提交状态后记录并执行这些操作。

cli();
do {
  auto lastStatus = Status;
  sei ();

  auto nextStatus = lastStatus;
  nextStatus.UpdateStuff();
  nextStatus.UpdateOtherStuff();
  ...

  cli ();
} while (lastStatus != Status);
Status = nextStatus;
sei();

暂无
暂无

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

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