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

 
 
> Скрипты линкера ld
EugeNNe
сообщение Mar 26 2009, 12:55
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 424
Регистрация: 6-03-06
Из: Н.Новгород
Пользователь №: 14 997



Возникла задача подсчитать CRC прошивки загружаемой во флэш AVR и писать в CRC ну скажем в последнюю ячейку памяти. Считать СRC бинарного файла и потом отдельно загружать в память совсем неудобно. Хотелось бы что бы в WinAVR собрал проект и загрузил. Люди подсказали что такое можно сотворить если написать скрипт для линкера. Сейчас с этим разбираюсь. Но может быть кто то подобное уже делал и есть примерчик. Просто время жмёт, а доки на ld немало надо сказать...

P.S. И хотелось бы полагать что CRC надо посчитать и загрузить куда надо.
А вопрос "зачем это надо?" несущественен....
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 16)
Сергей Борщ
сообщение Mar 26 2009, 15:29
Сообщение #2


Гуру
******

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



Цитата(BigBolt @ Mar 26 2009, 14:55) *
Возникла задача подсчитать CRC прошивки загружаемой во флэш AVR и писать в CRC ну скажем в последнюю ячейку памяти. Считать СRC бинарного файла и потом отдельно загружать в память совсем неудобно. Хотелось бы что бы в WinAVR собрал проект и загрузил. Люди подсказали что такое можно сотворить если написать скрипт для линкера.
Что-то я не припомню, чтобы ld умел считать CRC. Почему неудобно считать и загружать? ld должен зарезервировать место в прошивке. Srecord умеет считать CRC и вставлять ее в указанное место HEX-файла. Вызов SRecord можно добавить в качестве одной из целей в makefile.


--------------------
На любой вопрос даю любой ответ
"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
EugeNNe
сообщение Mar 26 2009, 16:58
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 424
Регистрация: 6-03-06
Из: Н.Новгород
Пользователь №: 14 997



Цитата(Сергей Борщ @ Mar 26 2009, 18:29) *
Что-то я не припомню, чтобы ld умел считать CRC. Почему неудобно считать и загружать? ld должен зарезервировать место в прошивке. Srecord умеет считать CRC и вставлять ее в указанное место HEX-файла. Вызов SRecord можно добавить в качестве одной из целей в makefile.


Вопрос не в том кто будет CRC считать, а в том что бы автоматизировать процесс. Спасибо за ссылочку, будем изучать.... Мне вообще тоже казалось что вроде как подсчёт CRC не задача линкера...

Сообщение отредактировал BigBolt - Mar 26 2009, 17:11
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Mar 26 2009, 18:31
Сообщение #4


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(BigBolt @ Mar 26 2009, 18:58) *
Мне вообще тоже казалось что вроде как подсчёт CRC не задача линкера...

С IARовским линкером спутали.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Mar 26 2009, 22:12
Сообщение #5


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Тоже думал на эту тему. И подумалось что не надо CRC пихать в последнюю ячейку памяти (т.е. в конец адресного пространства ПЗУ), а лучше сразу после программы. Так-как можно сильно снизить надежность устройства в случае большого неиспользованного пространства ПЗУ.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ARV
сообщение Mar 27 2009, 08:45
Сообщение #6


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



может, я недопонимаю чего-то... но как подсчет CRC программного кода повышает надежность ПО? вот мои рассуждения.

1. программа, в которой искажен хотя бы 1 бит в коде не может считаться корректной.
2. результат работы некорректной программы не может быть признан достоверным и не должен никак использоваться.

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

далее - если CRC не совпала... что делать в этом случае? просто "зависнуть"? ведь надеяться, что даже какое-то мигание светодиодом при работе НЕКОРРЕКТНОЙ программы будет исполнено правильно - нельзя... и чем такое "зависание" будет отличаться от зависания полноценного (из-за нарушения ПЗУ)?

не самообман ли это - самоподсчет CRC?


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 27 2009, 09:49
Сообщение #7


Гуру
******

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



Цитата(ARV @ Mar 27 2009, 10:45) *
не самообман ли это - самоподсчет CRC?
Нет. Почему вы априори думаете, что будет считаться CRC всей программы? Самое распространенное применение - загрузчики. Загрузчик зашивается один раз и не меняется. Приложение записывается в другую область памяти (а может и в ОЗУ). В процессе обновления приложения может произойти сбой и приложение будет испорчено (или не до конца записано, что то же самое). Загрузчик при этом остается целым и вполне может посчитать 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
ARV
сообщение Mar 27 2009, 10:21
Сообщение #8


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



а, ну в таком контексте - я согласен. я почему-то считал, что считается CRC всей флеши... спасибо.


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Harbour
сообщение Mar 27 2009, 11:38
Сообщение #9


Местами Гуру
*****

Группа: Validating
Сообщений: 1 103
Регистрация: 5-12-04
Пользователь №: 1 323



скрипт-то тут нафиг ненужен - в makefile вставляем генератор CRC после objcopy :

%.bin: %.elf
$(OBJCOPY) -j .data -j .text -j .board -O $(FORMAT) $< $@
@gencrc $@

его задача тупо дописать CRC в конец бинарной паршивки. В проге пишем что-то типа :

....
u32 plen = (u32)((&_etext + (&_edata - &__data_start)) - (unsigned long) AT91C_IFLASH);
u16 *crc = (u16 *)((unsigned long) AT91C_IFLASH + plen);
printf("Bootloader size - %d bytes, crc - 0x%X [ %s ]\r\n", plen, *crc,
(compute_csum((unsigned char *) AT91C_IFLASH, plen) == *crc) ? "valid" : "*** invalid ***");
....

это кусман от арм, но принцип тот же и для AVR. compute_csum - это та-же f() только внутри паршивки
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Mar 27 2009, 14:04
Сообщение #10


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Harbour @ Mar 27 2009, 14:38) *
это кусман от арм, но принцип тот же и для AVR. compute_csum - это та-же f() только внутри паршивки
Спасибо Вам за мысль. Правильно-ли я Вас понимаю, что загрузчик вызывает функцию верификации CRC из области приложения?
Как быть если хочется поместить в сам загрузчик и эту функцию. Т.е. как bootloader узнает размер уже запрограммированной прошивки для верификации CRC только по реально используемой flash?

Может на загрузчик возложить обязанность первоначального расчёта CRC сразу после обновления.
Ведь в этот момент известен размер прошивки.
Если boot контролирует правильность записи каждой отдельной страницы и протокол обмена тоже гарантирует целостность, то на мой взгляд можно...
После окончания обновления записать в последнюю ячейку размер прошивки и рядышком CRC (посчитанное и по байтикам размера прошивки).


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Harbour
сообщение Mar 28 2009, 08:06
Сообщение #11


Местами Гуру
*****

Группа: Validating
Сообщений: 1 103
Регистрация: 5-12-04
Пользователь №: 1 323



Да, правильно. Так ее туды и помещают wink.gif узнает размер он с помощью выше указанной строчки :

...
u32 plen = (u32)((&_etext + (&_edata - &__data_start)) - (unsigned long) AT91C_IFLASH);
...

plen - это и есть размер бинарной прошивки внутри контроллера, сразу за ней следует CRC, которую мы уже дописали из makefile. Можно и на загрузчик возложить - но гембеля много - обычно CRC так просто не запишешь - нужно запоминать/стирать страницу - а если питание в это время пропало ? или выносить CRC в отдельную страницу. И потом непонятно - если CRC не совпадает - это что испортились данные или просто загрузчик ее еще не обновил ?

Мой же принцип очень прост и надежен :

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

Другое дело, что в проекте bootloader работает только в начальный момент, его задача проверить себя, проверить приложение и запустить его. вот CRC самого приложения можно уже вместе с набором параметров класть в отдельную страницу флеша и обновлять после того как юзер залил новую версию приложения через этот самый bootloader.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Mar 28 2009, 10:23
Сообщение #12


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Harbour @ Mar 28 2009, 11:06) *
Мой же принцип очень прост и надежен :

- CRC загрузчика я точно знаю после генерации бинарной прошвики
- исполняемый файл содержит заранее вычисленную на хосте и верную CRC прошивки, добавляется она в конец прошивки, много места не содержит и легко вычисляется, как на хосте (по размеру исходного bin файла) так и в MCU (по метке конца данных)
Можете про метку конца данных подробнее. Уж больно всё это интересноsmile.gif Спасибо за пояснения!


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Harbour
сообщение Mar 30 2009, 06:15
Сообщение #13


Местами Гуру
*****

Группа: Validating
Сообщений: 1 103
Регистрация: 5-12-04
Пользователь №: 1 323



Конец данных, обычно это и есть последнее что записывается в прошивку, вот классический пример :

...........
.data : AT (_etext)
{
__data_start = . ;
*(.data)
*(.data.*)
SORT(CONSTRUCTORS)
. = ALIGN(4);
*(.fastrun) /* "RAM-Functions" */ /* added by mthomas */

} > DATA

. = ALIGN(4);

_edata = . ;
PROVIDE (edata = .);
..........................................

Если нет своих или каких либо специальных секций, то содержимое прошивки представляет собой две секции : .text и .data, длины которых известны на этапе линковки и могут быть доступны для вычисления изнутри программы непосредственно по меткам линкера. Это как-бы азы работы с ld - описано по многу раз, как в инете, так и тут на форуме.
В данном случае разбивают проект на crypto bootloader и приложение (app), выделяем 1 страницу флеш для хранения app crc и ее параметров (serial number, version и т.д.), размещаем их в памяти последовательно (bootloader + param page + app):

- шьем бутлодер
- шьем с помощью бутлодера app (в этом месте бутлодер уже знает длину app)
- бутлодер вычисляет app crc и вместе с переданными параметрами записывает все это дело в param page
- при старте бутлодер проверяет себя, проверяет приложение, и если все пучком - стартует его
- если нет - переходит в режим ожидания/программирования с соответствующей индикацией/сообщением
Go to the top of the page
 
+Quote Post
boldgambler
сообщение Dec 17 2009, 14:06
Сообщение #14





Группа: Участник
Сообщений: 6
Регистрация: 26-04-09
Пользователь №: 48 288



а где бы можно посмотреть примеры скрипта линкера для AVR ?
а то для арма почти в каждом проекте и скрипт и startup, а для AVR ни того ни другого не могу встретить в каком нить тестом проекте для gcc.
правда в отличии от арма тут прошивка и так компилится, но видно он откуда-то библиотечные startup и ld по умолчанию берет.
где бы почитать как его составлять этот скрипт?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 17 2009, 14:30
Сообщение #15


Гуру
******

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



Цитата(boldgambler @ Dec 17 2009, 16:06) *
а где бы можно посмотреть примеры скрипта линкера для AVR ?
В WinAVR - C:\WinAVR\avr\lib\ldscripts. В линуксе - аналогичная папка, в которую становятся binutils-avr.

Цитата(boldgambler @ Dec 17 2009, 16:06) *
а то для арма почти в каждом проекте и скрипт и startup, а для AVR ни того ни другого не могу встретить в каком нить тестом проекте для gcc.
правда в отличии от арма тут прошивка и так компилится, но видно он откуда-то библиотечные startup и ld по умолчанию берет.
ARMы слишком разные, и слишком разные конфигурации карт памяти возможны в системах с внешними ОЗУ/ПЗУ. У AVR все внутри, поэтому базовые скрипты вшиты в линкер.
Цитата(boldgambler @ Dec 17 2009, 16:06) *
где бы почитать как его составлять этот скрипт?
В документации на binutils


--------------------
На любой вопрос даю любой ответ
"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
boldgambler
сообщение Dec 17 2009, 15:01
Сообщение #16





Группа: Участник
Сообщений: 6
Регистрация: 26-04-09
Пользователь №: 48 288



спасибо. буду смотреть.
а когда имеет смысл писать свой скрипт? только если создаешь какие то секции где хочешь например меню расположить? ну или например разделить системные и пользовательские данные в памяти?

Сообщение отредактировал boldgambler - Dec 17 2009, 15:04
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 17 2009, 20:36
Сообщение #17


Гуру
******

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



Цитата(boldgambler @ Dec 17 2009, 17:01) *
а когда имеет смысл писать свой скрипт?
Когда вас не устраивает раскладка памяти, предоставляемая стандартным скриптом.


--------------------
На любой вопрос даю любой ответ
"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 Текстовая версия Сейчас: 22nd July 2025 - 11:39
Рейтинг@Mail.ru


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