Привет всем! Столкнулся с похожей проблемой.
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