嵌入式C:AVR; header 中的变量无法在 main 中求值
Embedded C: AVR; variable in header cannot be evaluated in main
感谢您抽出时间阅读。
我遇到的问题
我有:
main.h
声明:
uint8_t u_newVar
我也有
foo.h
写着:
extern uint8_t u_newVar
应用程序处于 main.c 的无限 while 循环中,直到发生 ISR。
在foo.c中表示ISR调用了foo.c内的一个函数。
在那个函数中(foo_function() 如果你愿意):0x01 被写入 u_newVar.
最后,从中断返回并回到无限 while 后,有一个 "if" 语句:
while(1){
if(u_newVar == 0x01){
uartTX_sendArray(st_uartRX_MessageContents->u_command, (sizeof st_uartRX_MessageContents->u_command));
uartTX_sendButtonPressData(st_uartRX_MessageContents->u32_value);
u_newVar = 0x00;
}
}
但是,应用程序永远不会进入 if。如果这个 "if" 块在 foo.c 中,在
之后,它将起作用
u_newVar = 0x01;
行。
我试过的东西
我查看了编译后的程序集,发现的东西让我有些困惑。
如果我查看 main 中的 "if",这就是我所看到的:
所以它从地址加载值:SRAM 的 0x011D,我可以确认是 0x01。
然后"CPI"将R24直接与0x01进行比较,显然应该可以。
然后"BREQ",如果相等则分支,并将程序计数器递增两次到下面的uart函数。也有道理。
然而这部分很奇怪。否则,使用"RJMP" 跳转到当前所在的指令。除非我弄错了,否则这会永远锁在这里?
所以,还记得我提到过在写入 u_newVar 之后将 if 块放入 foo.c 吗?是的,这不太有趣:
"if"本来应该在"u_newVar = 0x01"之后,但是编译器太聪明了,怎么优化。这就是为什么它总是在那里工作的原因。
您忘记告诉编译器变量可能被异步修改。例如在 ISR 中。
volatile uint8_t u_newVar;
您看到的是汇编程序的输出,而不是链接代码。
链接器在重定位 table 中包含代码中该偏移量的信息(指令的数据字节和实际目标偏移量是什么)。在链接过程中(或对于某些环境)在加载处理期间)这些数据字节将被更新以包含正确的值
感谢您抽出时间阅读。
我遇到的问题
我有:
main.h
声明:
uint8_t u_newVar
我也有
foo.h
写着:
extern uint8_t u_newVar
应用程序处于 main.c 的无限 while 循环中,直到发生 ISR。
在foo.c中表示ISR调用了foo.c内的一个函数。
在那个函数中(foo_function() 如果你愿意):0x01 被写入 u_newVar.
最后,从中断返回并回到无限 while 后,有一个 "if" 语句:
while(1){
if(u_newVar == 0x01){
uartTX_sendArray(st_uartRX_MessageContents->u_command, (sizeof st_uartRX_MessageContents->u_command));
uartTX_sendButtonPressData(st_uartRX_MessageContents->u32_value);
u_newVar = 0x00;
}
}
但是,应用程序永远不会进入 if。如果这个 "if" 块在 foo.c 中,在
之后,它将起作用u_newVar = 0x01;
行。
我试过的东西
我查看了编译后的程序集,发现的东西让我有些困惑。
如果我查看 main 中的 "if",这就是我所看到的:
所以它从地址加载值:SRAM 的 0x011D,我可以确认是 0x01。
然后"CPI"将R24直接与0x01进行比较,显然应该可以。
然后"BREQ",如果相等则分支,并将程序计数器递增两次到下面的uart函数。也有道理。
然而这部分很奇怪。否则,使用"RJMP" 跳转到当前所在的指令。除非我弄错了,否则这会永远锁在这里?
所以,还记得我提到过在写入 u_newVar 之后将 if 块放入 foo.c 吗?是的,这不太有趣:
"if"本来应该在"u_newVar = 0x01"之后,但是编译器太聪明了,怎么优化。这就是为什么它总是在那里工作的原因。
您忘记告诉编译器变量可能被异步修改。例如在 ISR 中。
volatile uint8_t u_newVar;
您看到的是汇编程序的输出,而不是链接代码。
链接器在重定位 table 中包含代码中该偏移量的信息(指令的数据字节和实际目标偏移量是什么)。在链接过程中(或对于某些环境)在加载处理期间)这些数据字节将被更新以包含正确的值