Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прошу помочь с подсчетом КС программы
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
ПАВ
Прошу помочь с подсчетом КС программы. Прочитал HELP на линкер, приведенный там пример не заработал (хотя узнал массу нового). Вопросы следующие:
1. Как вытащить начало и конец кода программы в функцию подсчета КС?
2. Есть ли возможность заставить линкер рассчитать CRC32 с заданным мною полиномом?
Если можно практические рекомендации. help.gif
zltigo
Цитата(ПАВ @ Feb 20 2007, 21:13) *
Прочитал HELP на линкер, приведенный там пример не заработал (хотя узнал массу нового). Вопросы следующие:
1. Как вытащить начало и конец кода программы в функцию подсчета КС?
2. Есть ли возможность заставить линкер рассчитать CRC32 с заданным мною полиномом?

1. По именам программ и/или сегментов естественно. Собственно проблема не понятна.
2. Естественно да в хелпе подробно описано. Конкретная проблема какая?

И еще это:
http://supp.iar.com/Support/?note=91733&from=note+76314
ПАВ
Уточню задачу. Имеется несколько устройств, с разными AVR (128 и 2560). ПО в этих AVR перекрывается на 20-30%. В том числе совпадает (я надеюсь так сделать) и контроль целостности ПО. Как прицепиться к началу проги я разобрался (конец сегмента прерываний). Непонятно как прицепиться к концу ПО, ведь в каждом устройстве своя программа, свои сегменты и т.д.
zltigo
Цитата(ПАВ @ Feb 21 2007, 23:04) *
Непонятно как прицепиться к концу ПО, ведь в каждом устройстве своя программа, свои сегменты и т.д.

Заводите свой сегмент и линкуете его в конец заодно в нем и собственно контрольную сумму размещаете.


Цитата(ПАВ @ Feb 21 2007, 23:04) *
Как прицепиться к началу проги я разобрался (конец сегмента прерываний).

Вообще-то ROMSTART и ROMEND имеют место быть smile.gif
Код
extern int ROMSTART;
extern int ROMEND;

И все smile.gif
Василий Зыков
Написал процедуру расчета CRC-кода программы и наткнулся на следующую проблему:
обявляю указатель и присваиваю ему первый адрес памяти FLASH:

const unsigned char *Flash_ptr = (const unsigned char *)0x0001; //

далее в программу читаю данные по адресу, на который ссылается указатель, отдаю эти данные процедуре расчета CRC-кода, а указатель инкрементирую (потом) (привожу листинг):

269 do{
270 asm ("wdr");

\ ??FLASH_test_0:
\ 00000002 95A8 wdr

271 data = *Flash_ptr;
272 CRC8_calc(data);

\ 00000004 .... LDI R24, LOW(BitFld)
\ 00000006 .... LDI R25, (BitFld) >> 8
\ 00000008 01FC MOVW R31:R30, R25:R24
\ 0000000A 81A4 LDD R26, Z+4
\ 0000000C 81B5 LDD R27, Z+5
\ 0000000E 910D LD R16, X+
\ 00000010 83A4 STD Z+4, R26
\ 00000012 83B5 STD Z+5, R27
\ 00000014 .... RCALL CRC8_calc
273 }while(++Flash_ptr <= (const unsigned char *)0x1FFE);

Вопрос в следующем: почему компилятор генерит код чтения из ОЗУ (команды LD, LDD) а не из FLASH (командой LPM)? В результате чего не получается посчитать CRC-код программы...
Сергей Борщ
Цитата(Василий Зыков @ Mar 29 2007, 09:47) *
const unsigned char *Flash_ptr = (const unsigned char *)0x0001; //
Вопрос в следующем: почему компилятор генерит код чтения из ОЗУ
Потому что AVR имеет несколько адресных пространств. Указатель на флеш, расположенный в озу объявляется как __flash unsigned char const* Flash_ptr = (__flash unsigned char const*)0x0001; И считать сумму надо наверное с нулевого адреса?
Василий Зыков
Сам задал вопрос - сам и отвечаю smile.gif

Изменил определение указателя на следующее:

const unsigned char __flash *Flash_ptr = (const unsigned char __flash *)0x0000;

и все заработало!

Цитата(Сергей Борщ @ Mar 29 2007, 15:51) *
Потому что AVR имеет несколько адресных пространств. Указатель на флеш, расположенный в озу объявляется как __flash unsigned char const* Flash_ptr = (__flash unsigned char const*)0x0001; И считать сумму надо наверное с нулевого адреса?



Спасибо за ответ! Я даже не заметил его. Только когда свой уже ответ самому же себе написал, тогда и заметил. Но все равно спасибо.

не знаю почему, но в таком виде, как Вы говорите, "не работает"...:
__flash unsigned char const* Flash_ptr = (__flash unsigned char const*)0x0001;

причем, я так пробовал, что меня и сбило с толку и заставило сюда написать.
Но стоит только перенести __flash в конец определения типа - начинает работать:
const unsigned char __flash *Flash_ptr = (const unsigned char __flash *)0x0000;

Конечно же, надо считать с нулевого адреса. Там в целях отладки стояла единица.
Faradey
Цитата(Василий Зыков @ Mar 29 2007, 12:14) *
...

не знаю почему, но в таком виде, как Вы говорите, "не работает"...:
__flash unsigned char const* Flash_ptr = (__flash unsigned char const*)0x0001;


__flash unsigned char const* Flash_ptr; // Указатель в flash памяти ОЗУ

unsigned char const __flash * Flash_ptr; // Указатель в ОЗУ на flash память

unsigned char const* Flash_ptr; // Указатель в ОЗУ на память ОЗУ
Василий Зыков
Цитата(Faradey @ Mar 29 2007, 17:12) *
__flash unsigned char const* Flash_ptr; // Указатель в flash памяти ОЗУ

unsigned char const __flash * Flash_ptr; // Указатель в ОЗУ на flash память

unsigned char const* Flash_ptr; // Указатель в ОЗУ на память ОЗУ


Спасибо! Теперь все ясно!
sz36
Цитата(ПАВ @ Feb 22 2007, 01:04) *
Как прицепиться к началу проги я разобрался (конец сегмента прерываний). Непонятно как прицепиться к концу ПО, ведь в каждом устройстве своя программа, свои сегменты и т.д.


Цитата(zltigo @ Feb 22 2007, 01:15) *
Заводите свой сегмент и линкуете его в конец заодно в нем и собственно контрольную сумму размещаете.
Вообще-то ROMSTART и ROMEND имеют место быть smile.gif


А зачем, собс-но, весь этот танец с началом и концом программы, когда IARовский линкер сам умеет КС считать? С ней в run-time и сравнивать. Я, например, в очень многих устройствах этот способ использую для контроля целостности программы. Опять же, начало и конец программы не помогут подсчитать КС на этапе компиляции, тогда какая-то постобработка нужна.
Сергей Борщ
Цитата(sz36 @ Apr 19 2007, 23:05) *
А зачем, собс-но, весь этот танец с началом и концом программы, когда IARовский линкер сам умеет КС считать? С ней в run-time и сравнивать.
Так в run-time же надо ее тоже посчитать, чтобы было что сравнивать. Для этого и нужен. Только зачем считать именно до конца программы, когда можно просчитать до конца памяти? И вот тут уже иаровский линкер лажается. Он считает, что незанятая память содержит нули, а на самом-то деле там 0xFF. Чтобы его результат совпадал с реальным приходится давать команду "заполнить свободное место константой 0xFFFF" и файл прошивки неприлично разбухает. По этой причине я отказался от расчета КС линкером в пользу самописной утилиты, считающей как мне надо и размещающей КС по указанному мной адресу (в конец памяти).
zltigo
Цитата(Сергей Борщ @ Apr 20 2007, 00:31) *
По этой причине я отказался от расчета КС линкером в пользу самописной утилиты, считающей как мне надо и размещающей КС по указанному мной адресу (в конец памяти).

Проблем написать утилиту - никаких. Только зачем? Диапазоны подсчета задаются, место расположения контрольной суммы задается, алгоритмов (даже без задания произвольных полиномов) изядное количество. Ну а считать всю память не всегда допустимо - у меня там еще несколько отдельно записываемых FPGA заливок лежат практически всегда.
Сергей Борщ
Цитата(zltigo @ Apr 19 2007, 23:55) *
Проблем написать утилиту - никаких. Только зачем? Диапазоны подсчета задаются, место расположения контрольной суммы задается, алгоритмов (даже без задания произвольных полиномов) изядное количество.
Еще раз: Если в этом диапазоне будут пустоты, то линкер считает, что там 0. А программа в реал-тайме находит там 0xFF. Сумма не совпадает. Чтобы этого избежать, надо указать линкеру заполнить свободное место константой, а это не всегда приемлемо.
Цитата(zltigo @ Apr 19 2007, 23:55) *
Ну а считать всю память не всегда допустимо
Это уже частности. Важно, что считается определенный диапазон, адреса которого фиксированы независимо от размера прошивки. Ибо подсчет (у меня) делает загрузчик, а он понятия не имеет о реальном размере прошивки, он только знает какая область под нее выделена.
lamerok
Цитата(Сергей Борщ @ Apr 20 2007, 16:24) *
Еще раз: Если в этом диапазоне будут пустоты, то линкер считает, что там 0. А программа в реал-тайме находит там 0xFF. Сумма не совпадает. Чтобы этого избежать, надо указать линкеру заполнить свободное место константой, а это не всегда приемлемо.Это уже частности. Важно, что считается определенный диапазон, адреса которого фиксированы независимо от размера прошивки. Ибо подсчет (у меня) делает загрузчик, а он понятия не имеет о реальном размере прошивки, он только знает какая область под нее выделена.

Именно поэтому делаем в *.xcl вот так

Код
// fill empty code space with 0x00
-H00
// generate a 2-byte crc16 checksum
-J2,crc16
Сергей Борщ
Цитата(lamerok @ May 17 2007, 09:48) *
Именно поэтому делаем в *.xcl вот так
А что, от заполнения свободного места прошивки нулями вместо 0xFFFF ее размер сильно сохранится?
Цитата
Чтобы его результат совпадал с реальным приходится давать команду "заполнить свободное место константой 0xFFFF" и файл прошивки неприлично разбухает.
zltigo
Цитата(Сергей Борщ @ May 17 2007, 10:20) *
А что, от заполнения свободного места прошивки нулями вместо 0xFFFF ее размер сильно сохранится?

Сергей! Я наконец, кажется понял твою "проблему". Линкер при указании опции -H генерит прошвку размером с выделеный ему ROM если не задавать опцию -h. Какие причины не пользоваться:
Код
-Hhexvalue       Specify filler byte(s)
-hranges         Specify fill ranges

Нету проблемы!
Сергей Борщ
Цитата(zltigo @ May 17 2007, 10:50) *
Сергей! Я наконец, кажется понял твою "проблему". Линкер при указании опции -H генерит прошвку размером с выделеный ему ROM если не задавать опцию -h.
Так мне и надо просчитать КС размером с почти весь ROM, хотя прошивка в этой версии может занимать всего несколько десятков процентов от этого размера. Если бы линкер знал, что в "пустых" ячейках лежит 0xFFFF, результаты у нас бы совпадали. Но он считает что там нули, а в реальном кристалле непрошитые области заняты единицами. Да это собственно и не проблема, а просто особенность линкера smile.gif
lamerok
Цитата(Сергей Борщ @ May 17 2007, 06:20) *
А что, от заполнения свободного места прошивки нулями вместо 0xFFFF ее размер сильно сохранится?

Чвободное место заполняю нулями для
1. Как вы и сказали, чтобы и ИАР и я 0 принимали за 0....
2. Косвенная проверка что вся флеш не битая....

Ну и контрольная сумма проверяется постоянно в Идле задаче, поэтому, время при загрузке не отнимает... т.е. проверяется вся память FLASH все время во время работы устройства..
Runner
Сегодня с удивлением обнаружил, что талантливый линкер IAR AVR 5.11b считает чек-сумму и для flash'и и для EEPROM'а. Поэтому, если на стадии линковки ЕЕПРОМина чем-то забита, а в аппликейшене вы станете счтиать чек-сумму только для flash-и, то полученная чексумма не будет совпадать с посчитанной ИАРом. wink.gif Они бы еще РАМ туда приплюсовали...
zltigo
Цитата(Runner @ Sep 19 2009, 19:09) *
Сегодня с удивлением обнаружил....

Лучше-бы Вы с удивлением "обнаружили" в комплекте IAR документацию на линкер, ну почитали, конечно, как можно управлять им, в том числе, и в части подсчета контрольных сумм.
-Jsize,algo[,flag[,symb[,seg[,align[,[m][#]initial]]]]][=ranges[;ranges…]]
Обратите внимание на возможность указания любого набора ranges
Кстати, линкер не только для "AVR".
Runner
Цитата(zltigo @ Sep 19 2009, 19:41) *
Лучше-бы Вы с удивлением "обнаружили" в комплекте IAR документацию на линкер...

Шпасибо! biggrin.gif a14.gif
Кому интересно - дока "xlink.ENU.pdf"
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.