|
|
  |
Подсчет CRC32, Периодически неверно считается CRC32 |
|
|
|
Feb 26 2010, 11:33
|
Местный
  
Группа: Свой
Сообщений: 404
Регистрация: 3-12-04
Из: Новосибирск
Пользователь №: 1 304

|
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. /* ... продолжение программы...*/
}
Причина редактирования: Оформление исходного текста
|
|
|
|
|
Feb 27 2010, 05:33
|
Местный
  
Группа: Свой
Сообщений: 404
Регистрация: 3-12-04
Из: Новосибирск
Пользователь №: 1 304

|
Возможно, что и с прерыванием не порядок. Глянул листинг - особого криминала не увидел. Код \ 00000000 93FA ST -Y, R31 \ 00000002 93EA ST -Y, R30 \ 00000004 932A ST -Y, R18 \ 00000006 931A ST -Y, R17 \ 00000008 930A ST -Y, R16 \ 0000000A B72F IN R18, 0x3F \ 0000000C E6E0 LDI R30, 96 \ 0000000E E0F0 LDI R31, 0 \ 00000010 .... RCALL ?Subroutine25 \ ??CrossCallReturnLabel_101: \ 00000012 5F0F SUBI R16, 255 \ 00000014 4F1F SBCI R17, 255 \ 00000016 .... RCALL ?Subroutine22 \ ??CrossCallReturnLabel_84: \ 00000018 BF2F OUT 0x3F, R18 \ 0000001A 9109 LD R16, Y+ \ 0000001C 9119 LD R17, Y+ \ 0000001E 9129 LD R18, Y+ \ 00000020 91E9 LD R30, Y+ \ 00000022 91F9 LD R31, Y+ \ 00000024 9518 RETI \ 00000026 REQUIRE Tictime
\ In segment CODE, align 2, keep-with-next \ ?Subroutine22: \ 00000000 8300 ST Z, R16 \ 00000002 8311 STD Z+1, R17 \ 00000004 9508 RET
\ In segment CODE, align 2, keep-with-next \ ?Subroutine25: \ 00000000 8100 LD R16, Z \ 00000002 8111 LDD R17, Z+1 \ 00000004 9508 RET
|
|
|
|
|
Feb 27 2010, 23:53
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Цитата(SysRq @ Feb 27 2010, 20:52)  Быть может, дело вовсе не в crc, а в чем-то еще? К примеру, эта самая Tictime - 16 бит, а МК - 8-битный. Если не запретить прерывания таймера на момент считывания Tictime для операции, к примеру, сравнения (if(Tictime == 1000)), возможна беда... Автор пишет, что прерывание всего одно - от Timer2. Посему никто не мешает процессору грузить новые данные в 16-разрядную переменную. То есть никакой беды нет. И еще, пора бы уже поправить имя переменной Tictime -> Ticktime. Аж глаз режет.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|