IAR AVR 5.20, Atmega8. Bootloader располагается с адреса 0х1800, используетя одно прерывание от таймера 2. Область памяти с 0x1400-0x17FF является общей для Bootloader & Application (здесь расположены общие функции). По адресу 0x00A2 находится указатель на память, где хранится значение CRC32 (считается IARом). Проблема заключается в следующем: делаю несколько посылок команды "посчитать CRC32" и получаю иногда неправильный результат. Если на момент подсчета CRC32 запретить прерывания, то CRC32 считается нормально. Не могу понять в чем дело? Гляньте часть кода, что не так? Проект компилировался и под IAR AVR 4.30 - результат такой же, значит дело не в компиляторе.
CODE
Uint32 __flash *pchecksum;
#pragma location=0x60
__no_init volatile unsigned int Tictime;
Uint32 slow_crc32(Uint32 sum, Uint8 __flash *p, Uint16 len)
{
while (len--)
{
Uint8 i;
unsigned char byte = *p++;
for (i = 0; i < 8; ++i)
{
unsigned long osum = sum;
sum <<= 1;
if (byte & 0x80)
sum |= 1 ;
if (osum & 0x80000000)
sum ^= POLY;
byte <<= 1;
}
}
return sum;
}
#pragma vector=TIMER2_COMP_vect
__interrupt void TIMER2_COMP_isr(void)
{ Tictime++; }
__C_task void main(void)
{
__no_init Uint32 addr;
GICR = (1<<IVCE); // Таблицу векторов в область загрузчика
GICR = (1<<IVSEL);
__enable_interrupt();
/* ....Здесь идет кое-какой код.... В частности обмен по SPI.
Во время обмена по SPI прерывания запрещаются....*/
// Прилетела команда по SPI посчитать CRC32.
pchecksum = (Uint32 __flash *)(*((Uint16 __flash *)(0x00A2)));
addr = 0;
addr = slow_crc32(addr,(Uint8 __flash *)0, ((Uint16)pchecksum)&0x013FF);
addr = slow_crc32(addr,(Uint8 __flash *)&zero,4);
// далее addr посылаю по SPI.
/* ... продолжение программы...*/
}
Причина редактирования: Оформление исходного текста