【问题标题】:avr-gcc compiler optimized out a global variable [closed]avr-gcc 编译器优化了一个全局变量
【发布时间】:2017-01-11 16:24:56
【问题描述】:

这里,

我的源代码

OCR0A=30;
uint16_t start=TCNT1;
uint16_t w;
for(uint8_t i=0;i<6;i++){
  pwm=pgm_read_byte(&forward[i]);     // mark here
  // delay
  do{
    w=TCNT1;
  } while(w-start>300);
}
OCR0A=127;

编译它,查看asm,我发现我的代码的业务被改变了。它变成了像下面这样的其他东西

OCR0A=30;
uint16_t start=TCNT1;
uint16_t w;
for(uint8_t i=0;i<6;i++){
  // delay
  do{
    w=TCNT1;
  } while(w-start>300);
}
pwm=pgm_read_byte(&forward[5]);      // mark here
OCR0A=127;

注意“在此处标记”行。 在我的原始代码中。 pwm 应该被定时器溢出中断使用。第二个代码并不是真正由编译器生成的。我写它只是为了方便描述

有什么建议吗? 谢谢

【问题讨论】:

  • 恕我直言,GCC 会选择将您的读取推送到 for 循环之外,这非常奇怪。可能想发布更多您的代码,以便我们对此做出正确判断。我知道 AVR-GCC 可以做一些时髦的事情,但并非完全没有理由,但如果我们了解更多上下文,这个小例子可能会变得更容易理解。
  • 我发布的显示问题的代码不是真实的。我只是编的。为什么编译器会产生不同的东西?不会工作。
  • 也许您误读了程序集?除非您将汇编与验证结论所需的任何其他内容一起显示,否则没有人可以验证。
  • 如果您可以发布更多的程序集,我们可以更轻松地揭穿这一点。 (如果您不想用汇编代码完全阻塞问题,您可以使用 pastebin 或其他东西(我不确定代码发布替代方案)。
  • 编译器认为for 语句对于变量pwm 是无用的。刚刚分配了最终值forward[5]

标签: c volatile avr-gcc


【解决方案1】:

问题在于编译器无法知道您打算在不同线程的不同位置使用pwm。由于您不在循环中使用该值,因此编译器只需将该值设置为它将写入变量的最后一个值(其他值无论如何都会被覆盖)。

您需要使用内存栅栏来解决这个问题(因此编译器和 CPU)不会重新排序对内存的写入。

编辑:查看this 答案表明将volatile 添加到pwm 应该足以确保所有写入都发生。

【讨论】:

    猜你喜欢
    • 2018-11-09
    • 2017-09-20
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多