 Этo_Я_oпять (20.12.2003 11:35, просмотров: 2752)
 Эт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,
связанный с кривостью кластеризации переменных. Сейчас поисследую и его.