реклама на сайте
подробности

 
 
 
Closed TopicStart new topic
> Подсчет CRC32, Периодически неверно считается CRC32
KSN
сообщение Feb 26 2010, 11:33
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 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.
/* ... продолжение программы...*/

}
Причина редактирования: Оформление исходного текста
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Feb 26 2010, 14:02
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Судя по вашему рассказу, проблема в неверной обработке прерываний. Все ли правильно установлено в обработчике прерываний?
Go to the top of the page
 
+Quote Post
KSN
сообщение Feb 27 2010, 05:33
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
редактор
сообщение Feb 27 2010, 09:45
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



Не спец по AVR поэтому общие мысли
1. Бутлоадер и приложение один проект или два разных??
Если разные то прерывание и подсчет CRC должны быть описаны в одном проекте. иначе линкер может смешать области данных двыух проектов.
2. По описанию Адрес 0xA2 содержит указатель на CRC, а при вызове функции параметр как длина участка кода
addr = slow_crc32(addr,(Uint8 __flash *)0, ((Uint16)pchecksum)&0x013FF);
3. Второй вызов функции. Что из себя представляет переменная zero? может быть в этом проблема
addr = slow_crc32(addr,(Uint8 __flash *)&zero,4);
Поскольку два вызова функции, я бы попробовал после каждой из них посмотреть результат, какой вызов вносит ошибку.


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
SysRq
сообщение Feb 27 2010, 17:52
Сообщение #5


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Быть может, дело вовсе не в crc, а в чем-то еще?
К примеру, эта самая Tictime - 16 бит, а МК - 8-битный. Если не запретить прерывания таймера на момент считывания Tictime для операции, к примеру, сравнения (if(Tictime == 1000)), возможна беда...
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Feb 27 2010, 23:53
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 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. Аж глаз режет.
Go to the top of the page
 
+Quote Post

Closed TopicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 13th July 2025 - 21:27
Рейтинг@Mail.ru


Страница сгенерированна за 0.01393 секунд с 7
ELECTRONIX ©2004-2016