marus-ka 0 1 октября, 2014 Опубликовано 1 октября, 2014 · Жалоба Всем привет! И снова у меня проблемы с crc. Теперь с IAR ARM. Пыталась двумя способами: через меню линкера и через файл линкера. Через меню: не сходится с программным расчетом. Что пробовала: разные алгоритмы: CRC16, CRC32 и разные настройки (Reverse, initial value и т.д.) Код для программного расчета брала из EWARM IAR C/C++ Development Guide Что непонятно: как указывать диапазон адресов из которых вычисляется CRC? (есть подозрение, что это несовпадение связано именно с несовпадением диапазонов данных, которые считаются) Совпадает ли он с диапазоном для Fill unused code memory? А если нет, то как его настроить, чтобы вычислялся только по коду, а не по пустому месту? Через файл icf: постоянно возникает ошибка Error[Lc003]: expected "check", "define", "do", "export", "if", "include", "initialize", "keep", "place", or a placement label, D:\IAR_projects\ARM\concentrator_RE013_M0+\samd20g16_flash.icf 78 В icf файле определяю блок CHECKSUM, и пишу следующее из EWARM IAR C/C++ Development Guide ielftool --fill=0xdd; 0x00000000 – 0x00010000; --checksum=__checksum:2,crc16;0x00000000 – 0x00010000 concentrator_RE013_M0+.out.temp concentrator_RE013_M0+.out. Пробовала просто fill, та же ошибка. Гуглила, не помогло((( Что я делаю не так? :crying: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 2 октября, 2014 Опубликовано 2 октября, 2014 · Жалоба А какой у Вас IAR (версия)? В разных версиях немного разные настройки. У меня в проектах на IAR6.50 так (и см. скриншоты): Для IAR5.50 первый скриншот будет немного другим (всё остальное - так же). Соответствущий расчёт CRC: //Расчёт CRC32 полином == 0xEDB88320L u32 CRC32(void const *buf, int len, u32 crc) { static const u32 t[] = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x00000000, 0x1DB71064, 0x3B6E20C8, 0x26D930AC, 0x76DC4190, 0x6B6B51F4, 0x4DB26158, 0x5005713C, 0xEDB88320, 0xF00F9344, 0xD6D6A3E8, 0xCB61B38C, 0x9B64C2B0, 0x86D3D2D4, 0xA00AE278, 0xBDBDF21C}; u8 const *p = (u8 const *)buf; while (--len >= 0) { u32 c = crc ^ *p++; crc = t[c & 15] ^ t[(c >> 4 & 15) + 16] ^ crc >> 8; } return crc; } static u32 crch; //Программная эмуляция аппаратного вычислителя CRC u32 HCRC32(void const *data, int len) { return ~(crch = CRC32(data, len, crch)); } void InitPrgCRC() { crch = 0; } В LPC177x/8x возможно задействовать аппаратный вычислитель CRC. У меня в проектах он используется, но здесь я его вырезал, оставил только ту часть дефайна, которая для случая отсутствия аппаратного вычислителя. Вызов (в начале main()): ... //проверка, что весь образ ПО во FLASH защищён CRC в IAR if ((u8 *)&__codetail[ncell(__codetail)] - (u8 *)__vector_table > __checksum_end + 1 - __checksum_begin + 32 + 4) trap(TRAP_PRG_IMAGE); InitPrgCRC(); u32 const seed = ~0; HCRC32(&seed, sizeof(seed)); if (HCRC32(__checksum_begin, __checksum_end - __checksum_begin + 1) != __checksum) trap(TRAP_PRG_IMAGE); ... Участок .icf, описывающий флешь (защищённую CRC): ... define block IMAGE_HEAD with fixed order {section .intvec, section .checksum, section .codehead, section .intvecTail, section .icc_signature}; place in FLASH_region {ro, first block IMAGE_HEAD, last section .codetail}; ... В хидерах определено: extern "C" vct const __vector_table[]; extern "C" u8 const __checksum_begin[]; extern "C" u8 const __checksum_end[]; extern "C" u32 const __checksum; extern "C" u32 const __codetail[1]; В asm-файле: ... PUBLIC __codetail EXTERN __checksum_begin, __checksum_end SECTION .codetail:CONST:NOROOT(2) __codetail DC32 __checksum_begin DC32 __checksum_end DC32 FIRMWARE_TARGET PUBLIC __codehead SECTION .codehead:CONST:NOROOT(2) __codehead DC32 __codetail DC32 0 ... CRC покрывает весь образ прошивки во флеш, за исключением первых векторов таблицы прерываний. Для них IAR считает контрольную сумму и с этим у меня возникли конфликты. Так что первые вектора я исключил из расчёта CRC. Как видите - образ прошивки начинается с адреса 0x1000 (первой идёт секция с векторами прерываний). Конечный адрес заполнения (первый скриншот) задаёте так, чтобы он покрывал весь образ прошивки с запасом (программа будет расти). Все дырки заполняются кодом заполнения. Вот как-то так примерно ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
marus-ka 0 3 октября, 2014 Опубликовано 3 октября, 2014 · Жалоба Спасибо за ответ! Мне в нем еще разбираться и разбираться))) У меня IAR 7.20 и контроллер SAM D20. А у меня вот такие настройки: 0x4000 это адрес начала application section. Если делать заполнение с 0 до 0x4000, а в bootloader считать CRC от массива с таким же заполнением и длиной, то все сходится. Как только добавляю хоть одну страницу кода, не сходится. Если считать только одну страницу кода, тоже не сходится. Если считать страницу кода после таблицы векторов прерываний, не сходится. И еще вопрос от блондинки, никак не могу понять что значит aligment 4 для CRC16. Понимаю, что глупый вопрос, но вот так) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 3 октября, 2014 Опубликовано 3 октября, 2014 · Жалоба 0x4000 это адрес начала application section. Если делать заполнение с 0 до 0x4000, Что значит "делать заполнение"? Start address и End address - это начальный и конечный адреса области, для которой рассчитывается CRC. А Fill pattern нужно ставить равным содержимому стёртой флеши. Обычно это FF или 00. И еще вопрос от блондинки, никак не могу понять что значит aligment 4 для CRC16 То же самое, что и для чего-либо другого: величина выравнивания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
marus-ka 0 3 октября, 2014 Опубликовано 3 октября, 2014 (изменено) · Жалоба Что значит "делать заполнение"? Start address и End address - это начальный и конечный адреса области, для которой рассчитывается CRC. А Fill pattern нужно ставить равным содержимому стёртой флеши. Обычно это FF или 00. Для меня это не очевидно. Поля Start address и End address доступны для записи в них значений даже если расчет CRC не производится. Поэтому более логично, что это именно диапазон для Fill pattern. И путем экспериментов выяснила, что диапазон расчета CRC совпадает. Только вот сама crc не сходится. Да и так уж обязательно, что это должно быть значение стертой flash? Я в документации на IAR этого не нашла. Насколько я помню там пишут, что это может быть любое число. То же самое, что и для чего-либо другого: величина выравнивания. Мне понятнее не стало, так как я меняю это значение адрес crc не меняется. Или что должно меняться в зависимости от выравнивания? Просто это мой первый опыт работы с 32х разрядными МК, а в 8 разрядных как-то не приходилось с этим сталкиваться. Изменено 3 октября, 2014 пользователем Мария Е Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 3 октября, 2014 Опубликовано 3 октября, 2014 · Жалоба Для меня это не очевидно. Поля Start address и End address доступны для записи в них значений даже если расчет CRC не производится. Поэтому более логично, что это именно диапазон для Fill pattern. Ну и что? Ясен пень, что когда стоит галка "считать CRC", то CRC для этого диапазона и считается. Мы же говорим об этом случае - Вам-же нужно именно CRC посчитать, а не только дырки заполнить? А без заполнения дырок, IAR естественно не даёт CRC считать. Да и так уж обязательно, что это должно быть значение стертой flash? Я в документации на IAR этого не нашла. Насколько я помню там пишут, что это может быть любое число. Это логично. Логично, чтобы, если в данном диапазоне нет никаких данных, то оставить там то, что есть (т.е. - содержимой чистой flash), а не перетирать лишний раз. Мне понятнее не стало, так как я меняю это значение адрес crc не меняется. Или что должно меняться в зависимости от выравнивания? Вы совета о чём спрашивали? Как посчитать CRC образа прошивки, не так-ли? У меня он считается. Во многих проектах уже. И я для себя этот вопрос давно закрыл. Я Вам подробно описал как. А насчёт экспериментов - увольте, сами ;) PS: Если же Вас интересует именно CRC, а не эксперименты, то очевидным шагом будет - попытаться сначала повторить как сделано у меня. И причём не только эти установки линкёра (не надо на них зацикливаться), а всё (я же не зря сюда выложил столько вырезок - все они важны). Параллельно читая мануал на компилятор.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
marus-ka 0 6 октября, 2014 Опубликовано 6 октября, 2014 · Жалоба Спасибо за уделенное время. Контроллер у меня другой алгоритм расчета Crc тоже. Поэтому предоставленные вами примеры мне не сильно помогли, к сожалению. Я, естественно, перед тем, как писать на форум, попробовала все возможные настройки линкера и прочитала документацию на компилятор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 6 октября, 2014 Опубликовано 6 октября, 2014 · Жалоба Контроллер у меня другой алгоритм расчета Crc тоже. Поэтому предоставленные вами примеры мне не сильно помогли, к сожалению. Я, естественно, перед тем, как писать на форум, попробовала все возможные настройки линкера и прочитала документацию на компилятор. А причём тут контроллер?? IAR считает CRC вне зависимости от МК. И я Вам привёл код процедуры программного расчёта CRC (без участия аппаратного вычислителя CRC) тоже для того чтобы можно было на любом CPU выполнять. Про алгоритм тоже не понятно - почему Вы не можете изменить свой алгоритм? Впрочем - дело Ваше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
marus-ka 0 7 октября, 2014 Опубликовано 7 октября, 2014 · Жалоба У меня изначально была концепция проверять crc в бутлоадере, поэтому такой подход как у вас, если я его правильно понимаю, мне не подходит. Пока от своей концепции я не хочу отказываться, но, возможно, придется. Я изначально хотела не скопировать чей-то пример, а разобраться, именно поэтому задавала и задаю вопросы. Если вы не считаете нужным и правильным отвечать, зачем тогда продолжать разговор? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 7 октября, 2014 Опубликовано 7 октября, 2014 · Жалоба У меня изначально была концепция проверять crc в бутлоадере, поэтому такой подход как у вас, если я его правильно понимаю, мне не подходит. Пока от своей концепции я не хочу отказываться, но, возможно, придется. Чем-же мой подход этому мешает? ;) По секрету Вам скажу, что защищённый таким образом образ (масло-масляное ;) прошивки у нас проверяется клиентским ПО (на ПК, после чтения из файла и перед посылкой прошивки устройству), самим ПО (при своём старте себя, и самоконтроль CRC новой принятой прошивки) и ещё и бутлоадером (перед переписыванием новой прошивки из внешней флешь во флешь CPU). Если вы не считаете нужным и правильным отвечать, зачем тогда продолжать разговор? Разве??? Я же Вам подробно всё расписал. Ещё в первом посте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
marus-ka 0 14 октября, 2014 Опубликовано 14 октября, 2014 · Жалоба Сама не люблю темы без окончательного ответа, поэтому решила отписаться. Изначально было непонятно, какие настройки линкера стоит ставить для совпадения программного и линкерного расчетов, правильно ли считается программно, по какому диапазону считается CRC (совпадает ли он с диапазоном заполнения), есть ли какие-то отличия в алгоритме подсчета CRC для первых байт (или таблицы векторов прерываний) и для остальной части кода, почему для заполненных диапазонов CRC программное и линкерное совпадало. Были прочитаны форумы, википедии и документация на линкер. В итоге мне помогло тупое перебирание способов подсчета CRC (разных галочек в меню линкера) и порядка байт при подсчете. Смогла проверить с помощью он-лайн калькулятора CRC программный способ подсчета CRC. Программно все было правильно. А с помощью калькулятора все гипотезы удавалось проверять быстрее, чем прогоняя код. Для проверки для простоты брала первые 2 или 4 байта ( в разных экспериментах) с первой страницы кода. Было выяснено, что IAR при подсчете CRC два соседних байта меняет местами. Причем, если убрать галку с пункта reverse byte order within word (что должно бы помочь от смены мест байт), получается еще какой-то вариант расчета, который не совпадает ни с одним из тех, что представлены в калькуляторе. При подсчете CRC области памяти заполненной одинаковыми байтами линкерный и программный способы совпадали именно из-за одинаковости байт. Они менялись местами, но так как одинаковые, на результат расчета это не влияло. Еще были сомнения, что CRC считается как-то особенно для первых байт или таблицы векторов прерываний. Это не подтвердилось - проверила с помощью подсчета CRC по алгоритму прямой суммы. Таким образом, для обеспечения совпадения программного и линкерного расчета перед программным расчетом меняю соседние байты местами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 14 октября, 2014 Опубликовано 14 октября, 2014 · Жалоба Таким образом, для обеспечения совпадения программного и линкерного расчета перед программным расчетом меняю соседние байты местами. А я не меняю Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться