|
CRC в IAR и определение конечного адреса, Подготовка к написанию BootLoadera |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 20)
|
Sep 22 2007, 10:57
|

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

|
Processing
With the Processing options you can specify details about how the code is generated.
Use Fill unused code memory to fill all gaps between segment parts introduced by the with the value you enter. The lcan introduce gaps either because of alignment restriction, or at the end of ranges given in segment placement options.
Use Generate checksum to checksum all generated raw data bytes. This option can only be used if the Fill unused code memory option has been specified.
Size specifies the number of bytes in the checksum, which can be 1, 2, or 4. One of the following algorithms can be used:
Arithmetic sum Simple arithmetic sum CRC16 , generating polynomial 0x11021 (default) CRC32 CRC32, generating polynomial 0x104C11DB7 Crc polynomial CRC with a generating polynomial of the value you enter You can also specify that the one's complement or two's complement should be used. By default it is the most significant 1, 2, or 4 bytes (MSB) of the result that will be output, in the natural byte order for the processor. Choose LSB from the Bit order drop-down list if you want the least significant bytes to be output.
The CRC checksum is calculated as if the following code was called for each bit in the input, starting with a CRC of 0:
unsigned long crc(int bit, unsigned long oldcrc)
{
unsigned long newcrc = (oldcrc << 1) ^ bit;
if (oldcrc & 0x80000000) newcrc ^= POLY;
return newcrc;
}
POLY is the generating polynomial. The checksum is the result of the final call to this routine. If the complement is specified, the checksum is the one's or two's complement of the result.
The will place the checksum byte(s) at the __checksum label in the CHECKSUM segment. This segment must be placed using the segment placement options like any other segment. [/quote]
--------------------
|
|
|
|
|
Sep 22 2007, 17:40
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(SasaVitebsk @ Sep 22 2007, 20:30)  Так чтобы адреса не указывать, а просто - последним. Порядок линковки в порядке перечисления: Код -Z(CODE)INTVEC=ROMSTART-ROMEND ......
-Z(CONST)INITTAB,DATA_ID,DATA_C=ROMSTART-ROMEND // Segment for CheckSUM -Z(CONST)CHECKSUM=ROMSTART-ROMEND // To end of CODE block //-Z(CONST)CHECKSUM#ROMSTART-ROMEND // To end of ROM block
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Sep 24 2007, 13:12
|
Группа: Новичок
Сообщений: 1
Регистрация: 24-09-07
Из: Симферополь
Пользователь №: 30 787

|
Доброго времени суток. SasaVitebsk, если Вы разобрались с CRC в IAR, то прошу помощи. MEGA32 Строка в .xcl - -J2,crc16,1,=(CODE)0-1(для пробы считаю CRC для первых двух байт прошивки) Значения во FLASH 0x0000=0C, 0x0001=94 На месте CHECKSUM#7FFF - af 79 В .map: Symbol Checksum Memory Start End Initial value ------ -------- ------ ----- --- ------------- __checksum 0x79af CODE 00000000 - 00000001 0x0 Вычисляю: Код void crc16_buf(u08 const __flash *buf,u16 buf_size) { u32 oldcrc = 0; u32 newcrc; u16 bit; u08 byte,count; while(buf_size){ byte = (*buf); count = 7; do{ if(byte & 0x80) bit = 1; else bit = 0; newcrc = (oldcrc << 1) ^ bit; // if(oldcrc & 0x80000000) newcrc ^= 0xA0010000; if(oldcrc & 0x8000) newcrc ^= 0x1021; oldcrc = newcrc; byte <<= 1; }while(count--); buf++; buf_size--; } crc16mb_prev = oldcrc; } Не получается получить такой же результат. Может увидите где ошибаюсь Заранее спасибо. [/quote]
|
|
|
|
|
Sep 26 2007, 13:40
|
Группа: Новичок
Сообщений: 5
Регистрация: 25-09-07
Пользователь №: 30 828

|
Цитата(igorAT @ Sep 24 2007, 17:12)  while(buf_size) { byte = (*buf); ... А что, iar уже прямо так данные из flash берет? Раньше для этого unsigned char __load_program_memory(unsigned char __flash *) использовали. ;-)
|
|
|
|
|
Sep 26 2007, 21:39
|

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

|
Цитата(igorAT @ Sep 24 2007, 16:12)  Код void crc16_buf(u08 const __flash *buf,u16 buf_size) Ой, а что так страшно? Попробуйте что-то вроде такого: Код uint16_t crc = 0; do { crc ^= ((uint16_t)*ptr++) << 8; uint8_t i = 8; do { if (crc & (1<<7)) { crc <<= 1; crc ^= 0x1021; } else crc <<= 1; } while(--i); } while (--buf_size);
crc16mb_prev =crc; }
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 27 2007, 08:51
|
Группа: Новичок
Сообщений: 5
Регистрация: 25-09-07
Пользователь №: 30 828

|
Цитата(Сергей Борщ @ Sep 27 2007, 00:29)  Даже и не сообразил сразу что ответить... Уже года 4 как. Ух, ты! Как я проспал! Всегда использовал свои функции для загрузки. Спасибо! В коде примера Сергея есть: Цитата crc ^= ((uint16_t)*ptr++) << 8; Имхо при сдвиге crc биты должны добавляться по одному, а не байтами. Мои загрузчики считают crc всей памяти секции приложения. В конце секции лежит crc и другие данные записанные моей внешней программой. +Нет разницы чем компилировать приложение и на каком языке написано.
|
|
|
|
|
Sep 27 2007, 09:10
|

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

|
Цитата(vladimir_ad @ Sep 27 2007, 11:51)  Имхо при сдвиге crc биты должны добавляться по одному, а не байтами. Дальше вы видите цикл по восьми битам. Есть две схемы вычисления CRC, которые дают в итоге один и тот же численный результат. Нет разницы - добавлять по одному биту или сразу все. Более подробное объяснение с картинками мне попадалось у Б. Скляра в его "Цифровой связи". Цитата(vladimir_ad @ Sep 27 2007, 11:51)  Мои загрузчики считают crc всей памяти секции приложения. В конце секции лежит crc и другие данные записанные моей внешней программой. +Нет разницы чем компилировать приложение и на каком языке написано. Аналогично.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 27 2007, 10:51
|
Группа: Новичок
Сообщений: 5
Регистрация: 25-09-07
Пользователь №: 30 828

|
Цитата(Сергей Борщ @ Sep 27 2007, 13:10)  Дальше вы видите цикл по восьми битам. .... Вы не поняли. Пример не работает - crc всегда 0. ;-)
|
|
|
|
|
Nov 22 2007, 09:29
|

Местный
  
Группа: Свой
Сообщений: 268
Регистрация: 4-11-05
Пользователь №: 10 470

|
Почему линкер при линковке требует больше места чем ему требуется на самом деле? Смотрю map-файл или готовый бинарник, сгенеренный когда линкеру дается весь флеш и затем задаю это (даже немного большее) значение как ROMEND. Код -DBOOTSIZE=00008000 //-DAPPMAXSIZE=00010000 -DAPPMAXSIZE=0000AB0F -DROMSTART=(00100000+BOOTSIZE) -DROMEND=(00100000+BOOTSIZE+APPMAXSIZE) Тогда линковщик начинает ругаться: Код Error[e16]: Segment DATA_C (size: 0x2e3c align: 0x2) is too long for segment definition. At least 0xc24 more bytes needed. The problem occurred while processing the segment placement command "-Z(CONST)INITTAB,DATA_ID,DATA_C=ROMSTART-ROMEND", where at the moment of placement the available memory ranges were "CODE:1108f6-112b0f" Reserved ranges relevant to this placement: 108000-1083a7 ICODE 1083a8-1108a5 CODE 1108a6-1108bf INITTAB 1108c0-112b0f DATA_ID Если дать ему эти нехватающие 0xC24 байта, то линкуется нормально, но это выделенное пространство заполняет как пустое неиспользованное место. Почему? На всяк случай приложил map и xcl файлы.
Прикрепленные файлы
pack.zip ( 2.65 килобайт )
Кол-во скачиваний: 23
|
|
|
|
|
Nov 22 2007, 11:03
|

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

|
Цитата(Waso @ Nov 22 2007, 11:29)  Почему линкер при линковке требует больше места чем ему требуется на самом деле? Это баг. Примерно догадываюсь, откуда он идет. Судя по адресам речь об ARM. Безусловный переход в ARM может быть сделан одним из двух способов - B label и LDR PC,=label (аналоги RJMP и JMP у AVR). Во втором случае требуется еще одно слово для хранения абсолютного адреса (label) в виде константы. В коде место под константу зарезервировано. При линковке линкер смотрит, может ли он дотянуться до метки командой B label. Если может, вставляет эту команду и удаляет ставшую ненужной константу с адресом label. Предполагаю, что код может просматриваться в несколько проходов, ибо переходы, которые были слишком длинными на первой итерации, после удаления части констант тоже могут заменены на короткие. Таким образом размер кода уменьшается. Видимо подсчет размера кода и выдача сообщения об ошибке происходит перед операцией замены длинных переходов на короткие. Это мое мнение, просто предположение. Увы, обход только один - выделить чуть больше памяти и вручную смотреть, что получившийся код уместился в имеющуюся память. Ой. только сейчас увидел: Цитата(vladimir_ad @ Sep 27 2007, 12:51)  Вы не поняли. Пример не работает - crc всегда 0. Ага, ошибочка: if (crc & (1U<<15))
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 25 2007, 18:43
|

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

|
Цитата(Сергей Борщ @ Nov 22 2007, 13:03)  Видимо подсчет размера кода и выдача сообщения об ошибке происходит перед операцией замены длинных переходов на короткие. Тема получила неожиданное продолжение на другом форуме, там же рецепт обхода проблемы. Еще не проверял.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 27 2007, 11:01
|

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

|
Цитата(Waso @ Nov 27 2007, 11:13)  В иаре менял настройку чтоб вставлял инверсионную сумму. И делал завершающий проход по этому числу. Результат ненулевой. Во-первых надо вставлять не инвертированный, а прямой результат. Во-вторых, если в коде встречаются "дыры", т.е. незаполненные участки, то линкер считает, что там нули, а на самом деле там единицы. Поэтому надо давать опцию заполнять свободное место константой 0xFFFFFFFF. Эту тему zltigo прорабатывал. Я ограничился написанием самописной утилиты, которая считает CRC как мне надо.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|