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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> CRC в IAR, не совпадает с программным расчетом
Мария Е
сообщение Jun 18 2013, 10:20
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 18-11-07
Из: Москва
Пользователь №: 32 424



Здравствуйте!
Использую IAR для AVR версии 6.3.3.1990
МК xmega32D4.
Для написания бутлоадера необходимо подсчитывать CRC прошивки. Хочу это сделать средствами линкера.
Прописываю в настройках:
Прикрепленное изображение


Рассчитываю программно в соответствии с документацией на линкер IAR
CODE

unsigned long ChecksumStart = 0x0000;
unsigned long ChecksumEnd = 0x8FFD;
...
unsigned short slow_crc16(unsigned short sum, unsigned char *p,unsigned int len)
{
while (len--)
{
int i;
unsigned char byte = *(p++);
for (i = 0; i < 8; ++i)
{
unsigned long osum = sum;
sum <<= 1;
if (byte & 0x80)
sum |= 1;
if (osum & 0x8000)
sum ^= 0x1021;
byte <<= 1;
}
}
return sum;
}
...
unsigned short calc = 0;
// Run the checksum algorithm
calc = slow_crc16(0, (unsigned char *) ChecksumStart,(ChecksumEnd - ChecksumStart+1));
// Rotate out the answer
unsigned char zeros[2] = {0, 0};
calc = slow_crc16(calc, zeros, 2);
...


Результат как программного расчета, так и линкером отправляю в com порт. Они не совпадают. И программный расчет не постоянен: при передергивании питания значение меняется.

P.S. Видела подобные проблемы и их обсуждения на форуме, но не поняла, есть ли решение

Сообщение отредактировал Мария Е - Jun 18 2013, 11:16
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
Мария Е
сообщение Jun 18 2013, 11:33
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 18-11-07
Из: Москва
Пользователь №: 32 424



Все заработало, когда переделала код в соответствии со статьей http://supp.iar.com/Support/?note=91733&from=note+76314 и примером к ней.
Тему можно закрывать.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 1 2014, 08:14
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Привет всем! Столкнулся с похожей проблемой.

IAR 6.12.1, МК ATxmega64A3U.
Линкер CRC генерит и ложит в конец прошивки, вроде все собирается верно. Вот выдержка из MAP-файла:
Код
SEGMENT              SPACE    START ADDRESS   END ADDRESS     SIZE  TYPE  ALIGN
=======              =====    =============   ===========     ====  ====  =====
INTVEC               CODE          00000000 - 000001FB         1FC   com    1
?FILL1               CODE          000001FC - 000001FF           4   rel    0
NEAR_F               CODE          00000200 - 00000218          19   rel    0
NEAR_F               CODE          00000219 - 00000675         45D   rel    0
SWITCH               CODE          00000676 - 000007DF         16A   rel    1
CODE                 CODE          000007E0 - 0000558B        4DAC   rel    1
<FAR_F> 1            CODE          0000558C - 00005F12         987   rel    0
INITTAB              CODE          00005F13 - 00005F20           E   rel    0
NEAR_ID              CODE          00005F21 - 00006122         202   rel    0
?FILL2               CODE          00006123 - 0000FFFD        9EDB   rel    0
CHECKSUM             CODE          0000FFFE - 0000FFFF           2   rel    0
ABSOLUTE             DATA               00000020                     rel    0
                      DATA               00000034                  
                      DATA               000001C0                  
                      DATA          00001000 - 000011A0         1A1
                      DATA          000011C0 - 00001360         1A1
                      DATA          00001380 - 00001381           2
NEAR_I               DATA          00002000 - 00002201         202   rel    0
NEAR_Z               DATA          00002202 - 00002B81         980   rel    1
RSTACK               DATA          00002B82 - 00002BC1          40   dse    0
CSTACK               DATA          00002BC2 - 00002DC1         200   dse    0


Symbol      Checksum  Memory  Start      End       Initial value
------      --------  ------  -----      ---       -------------
__checksum    0x3286   CODE   00000000 - 0000FFFD  0x0000 (#0x0000)

Алгоритм брал и из примеров в документации на линкер, и из атмеловских аппноутов и свой, давно используемый код - результат один - подсчитанная программой CRC не совпадает с той, что посчитал линкер...
Написал приложение по Win, которая считает CRC файла прошивки - подсчитанная приложением CRC сходится!!!
Подозреваю, что проблема в моем коде, но вроде все просто и очевидно. В общем бревна в глазу не вижу...

Привожу код функции:
CODE
crc = 0;

while (len--)
{
unsigned char i;
unsigned char byte = *data++;

for (i = 0; i < 8; ++i)
{
unsigned long osum = crc;
crc <<= 1;
if(byte & 0x80)
crc |= 1;
if (osum & 0x8000)
crc ^= 0x1021;
byte <<= 1;
}
}
return crc;


И листинг:
CODE
237 crc = 0;
\ 00000006 E080 LDI R24, 0
\ 00000008 E090 LDI R25, 0
\ 0000000A 2F04 MOV R16, R20
\ 0000000C 2B05 OR R16, R21
\ 0000000E 2B06 OR R16, R22
\ 00000010 2B07 OR R16, R23
\ 00000012 F0E1 BREQ ??BOARD_CRC16_MakeF_0
\ 00000014 018A MOVW R17:R16, R21:R20
\ 00000016 019B MOVW R19:R18, R23:R22
238
239 while (len--)
240 {
241 unsigned char i;
242 unsigned char byte = *data++;
\ ??BOARD_CRC16_MakeF_1:
\ 00000018 9175 LPM R23, Z+
243
244 for (i = 0; i < 8; ++i)
\ 0000001A E068 LDI R22, 8
\ 0000001C 5001 SUBI R16, 1
\ 0000001E 4010 SBCI R17, 0
\ 00000020 4020 SBCI R18, 0
\ 00000022 4030 SBCI R19, 0
\ 00000024 E241 LDI R20, 33
\ 00000026 E150 LDI R21, 16
245 {
246 unsigned long osum = crc;
\ ??BOARD_CRC16_MakeF_2:
\ 00000028 2E19 MOV R1, R25
247 crc <<= 1;
\ 0000002A 0F88 LSL R24
\ 0000002C 1F99 ROL R25
248 if(byte & 0x80)
\ 0000002E FB77 BST R23, 7
\ 00000030 F40E BRTC ??BOARD_CRC16_MakeF_3
249 crc |= 1;
\ 00000032 6081 ORI R24, 0x01
250 if (osum & 0x8000)
\ ??BOARD_CRC16_MakeF_3:
\ 00000034 FE17 SBRS R1, 7
\ 00000036 C002 RJMP ??BOARD_CRC16_MakeF_4
251 crc ^= 0x1021;
\ 00000038 2784 EOR R24, R20
\ 0000003A 2795 EOR R25, R21
252 byte <<= 1;
\ ??BOARD_CRC16_MakeF_4:
\ 0000003C 0F77 LSL R23
253 }
\ 0000003E 956A DEC R22
\ 00000040 F799 BRNE ??BOARD_CRC16_MakeF_2
254 }
\ 00000042 2F40 MOV R20, R16
\ 00000044 2B41 OR R20, R17
\ 00000046 2B42 OR R20, R18
\ 00000048 2B43 OR R20, R19
\ 0000004A F731 BRNE ??BOARD_CRC16_MakeF_1
255 return crc;
\ ??BOARD_CRC16_MakeF_0:
\ 0000004C 018C MOVW R17:R16, R25:R24
\ 0000004E 2D80 MOV R24, R0
\ 00000050 2D93 MOV R25, R3
\ 00000052 9508 RET


--------------------
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Feb 1 2014, 08:38
Сообщение #4


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

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Код
Алгоритм брал и из примеров в документации на линкер, и из атмеловских аппноутов и свой, давно используемый код - результат один - подсчитанная программой CRC не совпадает с той, что посчитал линкер...
Написал приложение по Win, которая считает CRC файла прошивки - подсчитанная приложением CRC сходится!!!
Подозреваю, что проблема в моем коде, но вроде все просто и очевидно. В общем бревна в глазу не вижу...


Я вот таким кодом пользовался. В конце результат инвертировал чтобы совпадало с тем, что вычисляет линкер.
CODE
/*
Name : CRC-16
Poly : 0x1021 1000000100001 x^12 + x^5 + 1
Init : 0x0000
*/
#define POLY 0x1021 //полином для вычисления crc16 памяти программ

//функция вычисления CRC-16 памяти программ AVR прямым методом
//перед возвратом результат инвертируется
unsigned int crc16_slow(unsigned int *pData, unsigned int size)
{
unsigned int crc16_result = 0; //создаём результат вычисления, начальное значение = 0

while(size--)
{
crc16_result ^= *pData++;

for (unsigned char j = 0; j < 16; j++)
{
crc16_result = crc16_result & 0x8000 ? (crc16_result << 1) ^ POLY : crc16_result << 1;
}
}

return ~crc16_result; //возвращаем инверсное значение
}

Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 1 2014, 08:43
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата
Я вот таким кодом пользовался. В конце результат инвертировал чтобы совпадало с тем, что вычисляет линкер.
Да дело то вроде не в алгоритме, т.к. тот же код на РС подсчитывает CRC верно!


--------------------
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Feb 1 2014, 08:54
Сообщение #6


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

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(prottoss @ Feb 1 2014, 12:43) *
Да дело то вроде не в алгоритме, т.к. тот же код на РС подсчитывает CRC верно!


В линкере корректно расположен сегмент для CRC16?

Код
-Z(CODE)CHECKSUM=(_..X_CRC_FLASH_END-1)-_..X_CRC_FLASH_END //тут располагается сегмент crc16 - 2 последних байта памяти
-J2,crc16,1//=(CODE)1E004-1E00b //а это ключ линкера для вычисления crc16 по области (CODE)0-(_..X_CRC_FLASH_END-2)


Не хочу вводить в заблуждение т.к. проект старый и я уже не помню подробностей, но вроде как результат вычисления crc по приведённому ранее коду совпадал с тем, что вычисляет линкер. Я использовал заполнение неиспользованной памяти 0xff.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 1 2014, 09:06
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Уважаемый mempfis_
Вы похоже не весь мой первый пост прочитали или не поняли меня.
CRC располагается в конце файла прошивки по двум последним адресам - 0xFFFE - 0xFFFF. Я показывал кусок MAP-файла:
Код
CHECKSUM             CODE          0000FFFE - 0000FFFF           2   rel    0

Сама CRC считается для области 0-FFFD включительно:
Код
Symbol      Checksum  Memory  Start      End       Initial value
------      --------  ------  -----      ---       -------------
__checksum    0xab3a   CODE   00000000 - 0000FFFD  0x0000 (#0x0000)

Программа, написанная мной для Windows, открывает файл прошивки считает CRC от 0 до FFFD и сравнивает с тем, что лежит по адресам FFFE - FFFF. Все сходится.
Тем же алгоритмом считаю CRC в программе - не сходится!


--------------------
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 1 2014, 09:17
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(prottoss @ Feb 1 2014, 11:06) *
Программа, написанная мной для Windows, открывает файл прошивки считает CRC от 0 до FFFD
Там есть две интересные области:
Код
?FILL1               CODE          000001FC - 000001FF           4   rel    0
?FILL2               CODE          00006123 - 0000FFFD        9EDB   rel    0

Линкер при расчете думает, что они заполнены нулями. В прошивке этих областей нет и они остаются заполненными 0xFFFF. Вероятно ваша программа тоже знает, что в этих областях единицы. Отсюда и несовпадение. В свое время из-за этого отказался от расчета CRC линкером и считаю ее отдельной утилиткой.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 1 2014, 09:25
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Сергей Борщ @ Feb 1 2014, 15:17) *
Отсюда и несовпадение.
Еще раз говорю - для проверки CRC написал программу на Borland Builder - она считает CRC прошивки - все совпадает!


--------------------
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 1 2014, 10:26
Сообщение #10


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(prottoss @ Feb 1 2014, 11:25) *
Еще раз говорю - для проверки CRC написал программу на Borland Builder - она считает CRC прошивки - все совпадает!

Читайте внимательно - предполагаю, что ваш файл прошивки описывает не всю область 0 - 0xFFFF. В нем есть "дыры", в частности отсутствует информация о содержимом адресов 6123-FFFD. Содержимое этих дыр в кристалле - стертая флеш, т.е. "все единицы". Линкер об этом не знает и считает, что содержимое пустых областей - нули. Поэтому результат вашего расчета не совпадает с результатом линкера. Я так думаю.

Добавлено: все вышесказанное имеет смысл если формат файла прошивки - Intel HEX


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 1 2014, 10:46
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Сергей Борщ @ Feb 1 2014, 16:26) *
Добавлено: все вышесказанное имеет смысл если формат файла прошивки - Intel HEX
Формат файла - bin


--------------------
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 1 2014, 10:53
Сообщение #12


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Значит вы и линкер считаете по разным алгоримам. Или используете разное начальное значение CRC. Или он размещает байты результата в обратном порядке.

Простите, невнимательно прочитал предыдущие сообщения - то есть результат вашей win-программы совпадает с линкером но не совпадает с результатом расчета в прошивке... Тогда что мешет в вин-программе выводить промежуточные значения в процессе вычисления и сравнить с теми же значениями при пошаговой отладке вашей прошивки в симуляторе? Или прогнать оба алгоритма на одинаковом массиве из, скажем, 5 байт? Если результат совпадет - выводить результат после обсчета каждого килобайта прошивки и методом последовательного приближения найти участок, на котором прошивка спотыкается.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 1 2014, 10:58
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Сергей Борщ @ Feb 1 2014, 16:53) *
Значит вы и линкер считаете по разным алгоримам. Или используете разное начальное значение CRC. Или он размещает байты результата в обратном порядке.
Ну почему же по разным? Пока оставим код в МК в покое. Вернемся к Билдеру. Я компилирую прошивку в BIN-формате и заливаю с верификацией. Все замечательно прошивается и верифицируется. Затем я запускаю программу - она считает CRC прошивки и проверяет с тем, что положил линкер в два последних адреса- все сходится.


--------------------
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 1 2014, 14:52
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Сергей Борщ @ Feb 1 2014, 15:17) *
Отсюда и несовпадение. В свое время из-за этого отказался от расчета CRC линкером и считаю ее отдельной утилиткой.
Ну, допустим, я откажусь от того, чтобы линкер сам считал CRC - я могу сделать такую утилиту сам - она и сейчас уже работает. Что изменится??? И утилита и линкер считают CRC одинаково. Я опять в печали - прога в МК считает почему то по другому... sad.gif

PS: Убрал из программы все лишнее. Результат не меняется sad.gifsad.gifsad.gif


--------------------
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 1 2014, 18:31
Сообщение #15


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Неужели сложно прогнать этот кусок прошивки (расчет CRC) в симуляторе? На этой же прошивке.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


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


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