liuqian 发表于 2014-7-12 14:44:23

吐个槽,PIC编译器优化出问题,妈的,浪费两天

程序如下,目的,把Flash当eep用

puts("Before:");
ReadSettings();
printSettings(&Settings);

puts("Buffer:");
stmp.StableTime=i+1;
stmp.Tolerance=i+2;
stmp.Threshold1=i+3;
stmp.Hysteresis1=i+4;
stmp.Threshold2=i+5;
stmp.Hysteresis2=i+6;
printSettings(&stmp);

puts("Erase: ");
EraseRow(USER_SPACE);
ReadSettings();
printSettings(&Settings);

puts("After: ");
WriteRow(&stmp,USER_SPACE);
ReadSettings();
printSettings(&Settings);
i++;

XC8 1.32 破解pro版,取消speed优化(相当于空间优化)
结果如下:
Before:08 10 c8 00 0a e8 03 64 .    816   200101000 100
Buffer:01 02 03 00 04 05 00 06 .    1   2   3   4   5   6
Erase: 08 10 c8 00 0a e8 03 64 .    816   200101000 100
After: 08 10 c8 00 0a e8 03 64 .    816   200101000 100

Before:08 10 c8 00 0a e8 03 64 .    816   200101000 100
Buffer:02 03 04 00 05 06 00 07 .    2   3   4   5   6   7
Erase: 08 10 c8 00 0a e8 03 64 .    816   200101000 100
After: 08 10 c8 00 0a e8 03 64 .    816   200101000 100

Before:08 10 c8 00 0a e8 03 64 .    816   200101000 100
Buffer:03 04 05 00 06 07 00 08 .    3   4   5   6   7   8
Erase: 08 10 c8 00 0a e8 03 64 .    816   200101000 100
After: 08 10 c8 00 0a e8 03 64 .    816   200101000 100

写不进去,擦除无效

改为speed优化

Before:08 10 c8 00 0a e8 03 64 .    816   200101000 100
Buffer:01 02 03 00 04 05 00 06 .    1   2   3   4   5   6
Erase: ff ff ff ff ff ff ff ff .255 255 65535 255 65535 255
After: 01 02 03 00 04 05 00 06 .    1   2   3   4   5   6

Before:01 02 03 00 04 05 00 06 .    1   2   3   4   5   6
Buffer:02 03 04 00 05 06 00 07 .    2   3   4   5   6   7
Erase: ff ff ff ff ff ff ff ff .255 255 65535 255 65535 255
After: 02 03 04 00 05 06 00 07 .    2   3   4   5   6   7

Before:02 03 04 00 05 06 00 07 .    2   3   4   5   6   7
Buffer:03 04 05 00 06 07 00 08 .    3   4   5   6   7   8
Erase: ff ff ff ff ff ff ff ff .255 255 65535 255 65535 255
After: 03 04 05 00 06 07 00 08 .    3   4   5   6   7   8
可以写入

测试发现,在space优化下,只要在EraseRow(USER_SPACE);
后面调用WriteRow(&stmp,USER_SPACE);,擦除就不行
即使我把WriteRow改到另外一个子程序中,或改变运行流程(比如擦除后作标记,过100ms后回来再写新数据),都是擦除不行

无意间想起来,底层的写入部分,在free版调试是OK,就还原回去,发现正常了。因为free默认是speed优化,所以OK。于是改回pro,用speed优化,也OK。

然后另一个麻烦来了,空间已经95%了,程序稍微加些功能就装不下。想从串口出个调试信息都麻烦,真TM蛋疼。

aozima 发表于 2014-7-12 14:53:32

1. 先检查自己的程序是否有些地方没注意,经不起优化。
2. 看编译后的汇编,找出错误点。
3. 另可以对单独的文件设置单独的优化参数。或在源代码内控制编译器针对不同的片段使用不同的优化参数。

gliet_su 发表于 2014-7-12 20:55:30

编译器优化不会有问题,那是因为你不了解优化器。

liuqian 发表于 2014-7-12 22:45:27

本帖最后由 liuqian 于 2014-7-12 22:48 编辑

是程序就会有bug,包括编译器,看最终的汇编代码就知道了
gcc的编译器依然在升级
以前用cvavr时发现过好几处编译器的错误,在本坛发过

90999 发表于 2014-7-13 00:27:55

gliet_su 发表于 2014-7-12 20:55
编译器优化不会有问题,那是因为你不了解优化器。

这不好说,优化器难以了解。

fengsir 发表于 2014-9-19 17:03:26

看看LIST文件。。。

liuyonguo 发表于 2014-9-19 18:06:18

编译器优化有问题?

abutter 发表于 2014-9-19 20:30:28

一般不要去直接怀疑编译器,而是分析一下结果为什么变成这样,同时看看编译器有没有 bug 修复。

是软件都会有错,编译器也有错,这是肯定的是,只是编译器的质量水平一般是比较高的,因为一般都偏保守,而且有相应的测试用例。

mowin 发表于 2014-9-19 20:47:57

钓丝我表示自己的程序也经不起优化,优化就死。但是水平低查不到源头,请问各位,除了看汇编,还有什么有用经验。谢谢,因为汇编太大了,看得头晕

abutter 发表于 2014-9-19 21:54:13

mowin 发表于 2014-9-19 20:47
钓丝我表示自己的程序也经不起优化,优化就死。但是水平低查不到源头,请问各位,除了看汇编,还有什么有用 ...

我觉得应该先从写代码规范和习惯开始。

一个 MCU 系统即使不复杂,也可以划分成很多的模块。我自己开发的时候总是先从单一模块开始,例如 GPIO 电灯,CAN/I2C,然后再用诸多的控制逻辑集成。这样的好处是,方便硬件调试和工程测试,然后就是出现问题在回归到单一功能。
页: [1]
查看完整版本: 吐个槽,PIC编译器优化出问题,妈的,浪费两天