Этo_Я_oпять (20.12.2003 11:35, просмотров: 2752)
Вот он! Один из багов оптимизатора IAR EWAVR 3.10A Вот кусочек кода:
unsigned char CSpi::XchByte (unsigned char txb, unsigned char* prxb)
{
.......... skip .................
unsigned char tb=SPSR;
SPDR = txb;
while (bit_is_clear(SPSR,SPIF));
tb=SPDR;
if (prxb) *prxb=tb;
.......... skip .................
}
А вот полученные листинги.
Этот кусок кода, оптимизация Speed-medium, все флажки установлены
227 unsigned char tb=SPSR;
\ 00000020 B11E IN R17,0x0E
228 SPDR = txb;
\ 00000022 B84F OUT 0x0F,R4
230 while (bit_is_clear(SPSR,SPIF)); \ ??XchByte_3:
\ 00000024 9B77 SBIS 0x0E,0x07
\ 00000026 CFFE RJMP ??XchByte_3
232 tb=SPDR;
\ 00000028 B11F IN R17,0x0F
233 if (prxb) *prxb=tb;
\ 0000002A 2F28 MOV R18,R24
\ 0000002C 2B29 OR R18,R25
\ 0000002E F011 BREQ ??XchByte_4
\ 00000030 01FC MOVW R31 : R30,R25 : R24
\ 00000032 8310 ST Z,R17
Тот же кусок кода, но оптимизация Speed-high, все флажки установлены
227 BYTE tb=SPSR;
\ 00000020 B11E IN R17,0x0E
228 SPDR = txb;
\ 00000022 B84F OUT 0x0F,R4
230 while (bit_is_clear(SPSR,SPIF)); \ ??XchByte_3:
\ 00000024 9B77 SBIS 0x0E,0x07
\ 00000026 CFFE RJMP ??XchByte_3
232 tb=SPDR;
\ 00000028 B11F IN R17,0x0F
233 if (prxb) *prxb=tb;
\ 0000002A 2F28 MOV R18,R24
\ 0000002C 2B29 OR R18,R25
\ 0000002E F011 BREQ ??XchByte_4
\ 00000030 01FC MOVW R31 : R30,R25 : R24
\ 00000032 8240 ST Z,R4
Как видно, оба куска почти идентичны. Первый выполняется корректно:
считанное из SPDR в R17 значение сохраняется по указателю. А вот второй-
с глючком. Считал-то он в R17, а сохранил вместо него R4!
R4 использовался для передачи параметра txb и был записан в SPDR.
Но компилятор почему-то посчитал во втором случае, что SPDR не мог
измениться (хотя зачем-то прочитал его значение в R17!) и сохранил
по указателю txb вместо принятого байта.
Вот вам и IAR... Так облажались!
Вывод: оптимизацию Speed-High нельзя использовать при работе с SFR регистрами.
Есть подозрение еще на один баг при оптимизации Speed-high,
связанный с кривостью кластеризации переменных. Сейчас поисследую и его.