【发布时间】:2017-11-05 21:27:18
【问题描述】:
我在 Eclipse 上运行 gcc 时遇到了优化问题。 我有一个程序在 -O0 优化级别下运行良好,但我需要打开其他优化级别,因为我的软件使用了太多闪存空间。 但是当我使用 -O1 优化级别(例如)时,我的代码不再工作,我需要使用 UART 外设管理功能进行如下所述的奇怪修改。
使用 -O0 运行良好的代码
void function(...)
{
// Send char one by one on UART peripheral
UART_put_char(...)
// Wait end of transmission on UART
while(end_of_transmission_flag == flase);
}
void UART_TxCompleteCallback()
{
// Change flag state
end_of_transmission_flag = true;
}
对 -O1 进行修改的代码
void function(...)
{
// Send char one by one on UART peripheral
UART_put_char(...)
// Wait end of transmission on UART
while(end_of_transmission_flag == flase)
{
Dummy = Dummy == 0 ? 1 : 0;
}
}
void UART_TxCompleteCallback()
{
// Change flag state
end_of_transmission_flag = true;
}
我想知道为什么 gcc 强迫我做这种修改,我是否需要改变我对代码设计的“思维方式”。或者有这种行为的解释吗?
感谢您的建议。
【问题讨论】:
-
end_of_transmission_flag是否声明为volatile? -
^ 它也应该被声明为原子的(或者,在 C11 之前,您必须依赖编译器扩展来保证它以原子方式读取和写入)
-
@M.M Atomic 无关紧要,除非这里涉及线程。 Volatile 对于硬件驱动程序来说已经足够了。
-
@ZanLynx 不,不是,至少一般情况下不是。例如,在 AVR 上,任何 16 位分配都是非原子的,需要通过在分配期间禁用中断来保护 ISR 不被“修改到分配的一半”。
标签: c gcc optimization embedded