6Ф3П 0 10 декабря, 2011 Опубликовано 10 декабря, 2011 · Жалоба Здравствуйте. Буду признателен если спасёте от инвалидности по мозгу. Среда WinAVR. Вычисляю CRC32 как описано тут http://ru.wikipedia.org/wiki/Crc#CRC-32 // =================================================== unsigned long CRC32Table[256] = {0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, итд} int main(void) { unsigned char a[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; int len = 9; volatile long crc = 0xFFFFFFFF; while (len--) { crc = (crc >> 8) ^ (CRC32Table[(crc ^ a[9 - len]) & 0xFF]); } crc = crc ^ 0xFFFFFFFF; В результате CRC == 0xE1042295 (Эмуляция в AVR студии) Теперь то же самое на Delphi // ==================================================== procedure TForm1.Button1Click(Sender: TObject); const tbl: array [0..255] of integer = ($00000000, $77073096, $EE0E612C, $990951BA, ...); arr: array [0..8] of byte = (1,2,3,4,5,6,7,8,9); var crc, len: integer; begin len := 9; crc := $FFFFFFFF; while len > 0 do begin crc := (crc shr 8) xor tbl[(crc xor arr[9 - len]) and $FF]; Dec(len); end; crc := crc xor $FFFFFFFF; label1.Caption := inttostr(crc); end; Здесь CRC = $40EFAB9E; Кто виноват, а главное, что делать. Забыл сказать - с вероятностью 99,9(9) правильный результат в Delphi т. к. этот алгоритм был использован в старых проектах. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 10 декабря, 2011 Опубликовано 10 декабря, 2011 · Жалоба Кто виноват, а главное, что делать. Нулевой байт в C-варианте игнорируется, т.к. len на первом проходе уже равна 8. Плюс считается один байт за границами массива a[]. Исправить можно многими способами. Самый простой и корявый - заменить 9 на 8. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Konst_777 0 10 декабря, 2011 Опубликовано 10 декабря, 2011 · Жалоба Разберитесь, когда выполняется декремент len в программе на C и когда в программе на Delphi B) Пока отвечал, Вам уже ответил уважаемый aaarrr. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
6Ф3П 0 10 декабря, 2011 Опубликовано 10 декабря, 2011 · Жалоба Спасибо. Косячок подправил но всё равно что то не то for (int i = 0; i < 9; i++) { crc = (crc >> 8) ^ (CRC32Table[(crc ^ a[i]) & 0xFF]); } crc = crc ^ 0xFFFFFFFF; Теперь CRC = 0x15E95EF1 p.s. Если глупости спрашиваю прошу прощения, я с С не очень, а WinAVR второй день юзаю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 10 декабря, 2011 Опубликовано 10 декабря, 2011 · Жалоба Еще crc должен быть unsigned, иначе >> даст расширение знака. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
6Ф3П 0 10 декабря, 2011 Опубликовано 10 декабря, 2011 (изменено) · Жалоба В ТОЧКУ!!!!! volatile unsigned long crc = 0xFFFFFFFF; aaarrr большое спасибо!!! Теперь CRC как положено 0x40EFAB9E; Изменено 10 декабря, 2011 пользователем 6Ф3П Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 10 декабря, 2011 Опубликовано 10 декабря, 2011 · Жалоба В ТОЧКУ!!!!! Ну и последний штрих: volatile ему быть совсем не обязательно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
6Ф3П 0 11 декабря, 2011 Опубликовано 11 декабря, 2011 · Жалоба По поводу volatile совершенно согласен. Проблема в том что я в студии не могу посмотреть знач. переменной. Объясните пожалуйста в чём дело. // ================================================================ long CalculateCRC32Block(unsigned char* buf, unsigned int len) { unsigned long crc = 0xFFFFFFFF; while (len--) { crc = (crc >> 8) ^ pgm_read_dword(&(CRC32Table[(crc ^ *buf++) & 0xFF])); } return crc ^ 0xFFFFFFFF; } Если так // ================================================================ int main(void) { unsigned char a[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; volatile unsigned long crc = CalculateCRC32Block(a, 9); то значение переменной crc в студии не видно Так тоже не видно // ================================================================ int main(void) { unsigned char a[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; unsigned long crc = 0; crc = CalculateCRC32Block(a, 9); И только так я могу его посмотреть // ================================================================ int main(void) { unsigned char a[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; volatile unsigned long crc = 0; crc = CalculateCRC32Block(a, 9); Может лучше использовать какую-нибудь другую программу для отладки? Или руки кривые? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 11 декабря, 2011 Опубликовано 11 декабря, 2011 · Жалоба .... Может лучше использовать какую-нибудь другую программу для отладки? Или руки кривые? Не надо =) Всё просто. Скорее всего компилятор разместил переменную crc в регистре. А если переменная в регистре зачастую GNU отладчик её значение получить не может. volatile заставляет компилятор не оптимизировать обращение к crc и как следствие размещает её в доступной отладчику ram. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
6Ф3П 0 11 декабря, 2011 Опубликовано 11 декабря, 2011 · Жалоба Спасибо, понял. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
WHILE 0 11 декабря, 2011 Опубликовано 11 декабря, 2011 · Жалоба Не надо =) Всё просто. Скорее всего компилятор разместил переменную crc в регистре. А если переменная в регистре зачастую GNU отладчик её значение получить не может. volatile заставляет компилятор не оптимизировать обращение к crc и как следствие размещает её в доступной отладчику ram. Ну а map-файл или как он там в GCC называется глянуть можно и ручками посмотреть содержимое нужного регистра? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 10 14 декабря, 2011 Опубликовано 14 декабря, 2011 · Жалоба ps Кто виноват, а главное, что делать. Забыл сказать - с вероятностью 99,9(9) правильный результат в Delphi т. к. этот алгоритм был использован в старых проектах. когда сомневаешься - какой алгоритм считает правильно, а какой нет, см он-лайн калькулятор црц http://www.lammertbies.nl/comm/info/crc-calculation.html строка "01 02 03 04 05 06 07 08 09" и тип данных hex. результат: CRC-32 0x40EFAB9E Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться