【问题标题】:Why is this variable not being set?为什么没有设置这个变量?
【发布时间】:2014-08-26 00:27:40
【问题描述】:

我正在编写一段代码,该代码根据时间数据计算一些值。它在微控制器 (TI MSP430) 上运行

我遇到了不寻常的行为,因为变量似乎永远不会被赋值。

unsigned int angle = 0;
unsigned long int average_period;
void main(void){
    ...
    while (1){
        ....
        angle = ((2359325536UL)/average_period);
        ...
        }
    }

在这段代码中,我有一个全局变量 angle(它需要是全局变量,因为它在中断中被访问)并且它在我的程序的主循环中重复计算和设置。

但是它的值永远不会改变,如果我将角度设置为其他任意值,它会保持该值,所以它不像计算输出零。

如果我使角度不稳定,它可以正常工作,尽管我的代码大小从(3kB 到 7.5kB)翻了一番。什么会导致这种情况,如果不使用 volatile 关键字可以避免这种情况。

注意:我对 volatile 关键字不是很熟悉,除了它可以用来防止未使用的变量被优化。

【问题讨论】:

  • 不应将角度定义为unsigned long
  • 结果值将在 0-36000 左右的范围内,并且在其他地方使用无符号整数。我的理解是这些可以隐式转换。
  • 这正是 volatile 的用途。没有它,循环可以被优化掉
  • average_period 是如何设置的?
  • 为什么可以优化掉,在循环中还有其他类似的值计算,并且在代码中的其他中断中使用了角度。

标签: c microcontroller long-integer volatile


【解决方案1】:

通常volatile 用于表示变量可以在正常控制流之外更改,例如在 ISR 中。但听起来你只是在 ISR 中阅读angle,而不是设置它。

所以我的猜测是angle 永远不会在while (1) 循环之外使用,并且优化器假设它的值无关紧要,所以它会跳过分配。 volatile 告诉它它不能做出任何这样的假设。

为避免 volatile,请尝试在循环外使用 angle,或将其传递给另一个文件中定义的函数,以便编译器认为计算值很重要。

【讨论】:

  • 或者只使用几个#pragma 语句来关闭围绕“角度”值设置的优化。
  • “如果你想避免使用锤子,你可以用砖头或木头敲钉子。”
  • volatile 是适合这项工作的错误工具。 OP 需要向编译器发出信号,表明主循环中设置的 angle 的值在其他地方使用,并且无法优化。 volatile 没有这么说,它说angle 可以以编译器意想不到的方式改变。正如 OP 所说,这会强制生成防御性代码和 2X 代码。每次访问都将获得额外的“加载”指令,甚至是同一 ISR 中的背靠背行。如果此代码仅在后台循环中设置 var 并在 ISR 中读取,则完全不需要这些额外的负载,并且可能会损害时序。
猜你喜欢
  • 2011-09-15
  • 1970-01-01
  • 2016-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多