我有一个程序可以写入某些FPGA内存。当程序使用优化(O1,O2或O3)编译时,它会因总线错误而崩溃。但是,在没有优化的情况下编译程序时没有崩溃。
这是一个崩溃的最小例子:
void set_reg(const uint32_t *data)
{
uint32_t val = data[0];
dvm.write32(dac_map, 0, static_cast<uint32_t>(8192 * cos(val))); // crash
}
当我添加volatile时,不再有崩溃:
void set_reg(const uint32_t *data)
{
volatile uint32_t val = data[0];
dvm.write32(dac_map, 0, static_cast<uint32_t>(8192 * cos(val))); // no crash
}
如果我删除对cos的调用,则没有问题。
这似乎与GCC: program doesn't work with compilation option -O3有关。当我添加标记-ffloat-store
时,程序不会崩溃。
但是,对于更复杂的实际代码,添加标记-ffloat-store
并不能解决问题。
我不了解GCC的优化方式以及如何导致SIGBUS
。如果有人能够解释这一点,它将对调试很有用。
谢谢。
NB:
1)GCC版本为arm-linux-gnueabihf-g++ (Ubuntu/Linaro 5.3.1-14ubuntu2) 5.3.1 20160413
2)函数write32
定义为
void write32(MemMapID id, uint32_t offset, uint32_t value)
{
ASSERT_WRITABLE
*(volatile uintptr_t *) (GetBaseAddr(id) + offset) = value;
}