TaterLi's LazyBlog

自言自语,不喜绕路,科学上网,远离天国.

@TaterLi1周前

02/10
10:32
技术控

编译器优化引起的奇怪BUG

Atollic已经被ST收购了,STM32当然是开放用,以前稍微接触没有深入,现在开始想做点东西,感觉又被编译器聪明坑了.

测试代码:

uint8_t i = 0;

uint8_t SPI_Send(uint8_t byte)
{
    uint8_t tmp = 0;
    LL_SPI_TransmitData8(SPI1, byte);
    while(!LL_SPI_IsActiveFlag_TXE(SPI1));
    while(!LL_SPI_IsActiveFlag_RXNE(SPI1));
    tmp = LL_SPI_ReceiveData8(SPI1);
    return tmp;
}

LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_4);
SPI_Send(i++);
SPI_Send(i++);
SPI_Send(i++);
LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_4);

LL_mDelay(1);

很明显,这是个SPI发送数据的代码.

使用-O3优化.

分析:

拉高后明明是mDelay(1),而且拉高后都在mDelay函数,怎么还发数据,而且发的数据怎么只有2帧,而且数据还不对.

改成O2优化.

结果没什么差距.

用O1优化.感觉好像发了3帧,又好像 不是,数据也不对.

用不优化,数据就对了.

PS:mDelay(1) 貌似是ST库BUG.

不管是O1 O2 O3,后来还测试了Osize,Ofast,均出错.可见是arm-atollic-eabi-gcc有BUG啊.肯定是打开了不靠谱的优化.

Using built-in specs.
COLLECT_GCC=arm-atollic-eabi-gcc.exe
COLLECT_LTO_WRAPPER=c:/program\ files\ (x86)/atollic/truestudio\ for\ stm32\ 9.0.0/armtools/bin/../lib/gcc/arm-atollic-eabi/6.3.1/lto-wrapper.exe
Target: arm-atollic-eabi
Configured with: /home/build/gcc-arm-none-eabi-6-2017-q1-update/src/gcc/configure --build=x86_64-linux-gnu --host=i686-w64-mingw32 --target=arm-atollic-eabi --prefix=/home/build/gcc-arm-none-eabi-6-2017-q1-update/install-mingw --libexecdir=/home/build/gcc-arm-none-eabi-6-2017-q1-update/install-mingw/lib --infodir=/home/build/gcc-arm-none-eabi-6-2017-q1-update/install-mingw/share/doc/gcc-arm-atollic-eabi/info --mandir=/home/build/gcc-arm-none-eabi-6-2017-q1-update/install-mingw/share/doc/gcc-arm-atollic-eabi/man --htmldir=/home/build/gcc-arm-none-eabi-6-2017-q1-update/install-mingw/share/doc/gcc-arm-atollic-eabi/html --pdfdir=/home/build/gcc-arm-none-eabi-6-2017-q1-update/install-mingw/share/doc/gcc-arm-atollic-eabi/pdf --enable-languages=c,c++ --enable-mingw-wildcard --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-headers=yes --with-newlib --with-python-dir=share/gcc-arm-atollic-eabi --with-sysroot=/home/build/gcc-arm-none-eabi-6-2017-q1-update/install-mingw/arm-atollic-eabi --with-libiconv-prefix=/home/build/gcc-arm-none-eabi-6-2017-q1-update/build-mingw/host-libs/usr --with-gmp=/home/build/gcc-arm-none-eabi-6-2017-q1-update/build-mingw/host-libs/usr --with-mpfr=/home/build/gcc-arm-none-eabi-6-2017-q1-update/build-mingw/host-libs/usr --with-mpc=/home/build/gcc-arm-none-eabi-6-2017-q1-update/build-mingw/host-libs/usr --with-isl=/home/build/gcc-arm-none-eabi-6-2017-q1-update/build-mingw/host-libs/usr --with-libelf=/home/build/gcc-arm-none-eabi-6-2017-q1-update/build-mingw/host-libs/usr --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-pkgversion='GNU Tools for ARM Embedded Processors (Build 17.03)' --with-multilib-list=atollicprofile
Thread model: single
gcc version 6.3.1 20170215 (release) [ARM/embedded-6-branch revision 245512] (GNU Tools for ARM Embedded Processors (Build 17.03))

我发现调试过程中,把内核HALT了,依然发SPI,这个难道是优化工具假装HALT了?

HALT时依然有数据.

要不我JLink有问题,要不他有问题.但是我一直在Keil就没问题.而且拔掉仿真器,依然一直发数据,怀疑就是编译出来东西有问题.也有可能是没有充分考虑逻辑,导致慢指令还没执行完,快的指令就来了,马上得执行了.

Keil O3 Compiler 5验证.(Compiler 6依然没错)

编译器优化引起的奇怪BUG