|
|
  |
AVR+ARM бутлоадер |
|
|
|
Jun 26 2009, 20:54
|
Участник

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

|
Суть проблемы такова. Есть палта: АРМ7, а именно SAM7X от атмела и атмега16, соединены они по SPI. SAM7 через порт юарт DBG соединен с кампом. В общем нужно сделать следующее. По юарту передаются две прошивки, для арма и для авр. Обе они попадают на АРМ. Нужно что бы он перепрошил авр-ку и перепрошился сам. Подскажите как это нужно реализовать? Поделитесь любыми мыслями, возможно ссылками которые мне помогут разобраться. Если есть примеры готовые, поделитесь, буду благодарен. В общем любые советы и толчки в нужную сторону. Заранее благодарен.
|
|
|
|
|
Jun 26 2009, 21:20
|
Участник

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

|
Ознакомился... все рекомендуюсь "019. Safe and Secure Firmware Upgrade forAT91SAM Microcontrollers" можете расписать как его использовать, два дня кручу-верчу и никак не пойму как оно должно работать... обьясните пожалуйста.
|
|
|
|
|
Jun 26 2009, 21:51
|
Участник

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

|
Я прочитал и даже на русский для потомков собираюсь перевести, но вот что-то на практике не получаеться осуществить. Я надеялся вы обьясните какие есть подводные камни, может я как-то не с той стороны подхожу к вопросу... если не тяжело обьясните как поднять вот тот код...
|
|
|
|
|
Jul 22 2009, 17:49
|
Участник

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

|
Наконец-то добрались руки до написания бутлоадера по AT91SAM7. В общем я сейчас опишу алгоритм как я это собираюсь сделать, а вы если можно ответьте правильно ли я размышляю и если есть ошибки укажите на них. Итак ограничения для firmware. В настройках линкера должно быть указано следующее: Код -DBOOTSIZE=8000
-Z(CONST)INTRAMSTART_REMAP=00000000 -Z(CONST)INTRAMEND_REMAP=0000FFFF -Z(CONST)INTRAMSTART=00200000
-DROMSTART=(00100000+BOOTSIZE) -DROMEND=0013FFFF
-DINTVECSIZE=100 -DRAMSTART=(00000000+INTVECSIZE) -DRAMEND=0000FFFF
-Z(CODE)INTVEC=ROMSTART-(ROMSTART+INTVECSIZE) Итак. Загрузчик размещается во флеши по адресу 0. Пользовательская программа по адресу 0х8000. Загрузчик хочу зделать и через USART и через USB. Но пока не в этом суть. Загрузчик либо проверяет уже существующую прошивку и если она корректна то стартует с неё, или же если пришла из вне команда о перепрошивке начинает перепрошивать пользовательскую программу. Загрузка будет производиться постранично. Так как не может одновпременно производиться и запись и чтение с флеша функция записи должна быть с идентификатором __ramfunc. У меня вопрос встречный. Что делать с обработчиком прерывания, можно ли ему назначить идентификатор __ramfunc? Или же прерывания необходимо останавливать на время выполнения записи в флеш? Итак по адресу 0х8000 записана новая пользовательская программа. Далее производиться копирование векторов прерывания пользовательской программы в ОЗУ с адреса 0х8000 флеша в адрес 0 в ОЗУ. И далее производиться команда remap (теперь по нулевым адресам зеркалируеться ОЗУ и пользовательская программа может выполнять свои обработчики исключительных ситуаций). Ну и естественно нулевой вектор сброса необходимо оставить старый, что бы при сбросе мы попадали в бутлоадер. Укажите на существующие неточности и ошибки в том алгоритме что я привел. В общем любые ваши коментарии. Завтра уже планирую закодировать все выше написаное.
|
|
|
|
|
Jul 22 2009, 18:02
|

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

|
Цитата(piz2383 @ Jul 22 2009, 20:49)  Загрузчик размещается во флеши по адресу 0. .... Далее производиться копирование векторов прерывания пользовательской программы в ОЗУ с адреса 0х8000 флеша в адрес 0 в ОЗУ. Нестыковка. Как вы скопируете в адрес 0, если там лежит флеш из которой исполняется загрузчик? Вектора должны лежать по адресу 0. До ремапа туда отражена флеш и вектора загрузчика, после ремапа туда отражено ОЗУ и скопированные вами в ОЗУ (на адрес 0x200000) вектора приложения. Загрузчик должен располагаться и выполняться из адресов флеш (0x100000). Иначе в тот момент, когда вы сделаете ремап - на место исполняемого кода загрузчика ляжет ОЗУ и тут-то все и упадет. Приложение тоже должно работать из адресов флеш, ибо по нулевым адресам после ремапа будет ОЗУ.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 22 2009, 22:49
|
Участник

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

|
Т.е. единственное что нужно добавить это что бы загрузчик размещался с адресов 0x100000, а пользовательская программа с адреса 0x108000 и во время копирования нужно копировать с адреса 0x100000 в адрес 0x200000. Правильно я понимаю Вас?
Кстати в обработчик бутлоадера мы можем попасть как после включения так и после программного сброса. Если после включения питания то remap не вызывался, а если после программного сброса то выполнялась команда ремап. Как-то программно можно это определить?
|
|
|
|
|
Jul 22 2009, 23:13
|

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

|
Цитата(piz2383 @ Jul 23 2009, 01:49)  Т.е. единственное что нужно добавить это что бы загрузчик размещался с адресов 0x100000, а пользовательская программа с адреса 0x108000 и во время копирования нужно копировать с адреса 0x100000 в адрес 0x200000. Правильно я понимаю Вас? Да. И несколько иначе описать сами вектора в файле линкера. Поищите по форуму по ключевому слову INTVEC, я буквально на прошлой неделе пример приводил. Но если программный сброс был собакой или битом в контроллере сброса, то ремап автоматически переключится на флеш в процессе сброса. Я, для определения откуда попали в загрузчик, использую один из битов направления порта. При включении питания он настроен на ввод. Приложение его настраивает на вывод. Цитата(piz2383 @ Jul 23 2009, 01:49)  Кстати в обработчик бутлоадера мы можем попасть как после включения так и после программного сброса. Если после включения питания то remap не вызывался, а если после программного сброса то выполнялась команда ремап. Как-то программно можно это определить? У SAM7 довольно хитро: берете любой адрес в ОЗУ (например, адрес автоматической переменной на стеке), находите соответствующий ему адрес в области ремапа и сравниваете содержимое по этому адресу. Если не совпало - в нулевые адреса отражена флеш. Если совпало - изменяете переменную и смотрите, изменилось ли так же содержимое ячейки в области ремапа. Если изменилось - отражено ОЗУ.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 23 2009, 06:08
|
Участник

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

|
Цитата(Terminator @ Jul 23 2009, 04:45)  Чтобы не возится с __ramfunc я тупо заливаю весь загрузчик в ОЗУ, благо памяти в контроллере много. Ну а все-таки обозвать обработчик прерываний с помощью идентификатора __ramfunc можно? Цитата(Terminator @ Jul 23 2009, 04:45)  А как вы собираетесь защитится от аварий при перепрошивке? Например заливаем новую прошивку и тут пропадает питание. Что будет делать загрузчик? Запустит недописанную программу? Я планирую во-первых сперва залочить область бутлоадера. Далее с программы на компьютере передаеться сперва размер прошивки и её контрольная сумма затем только прошивка. Заливаю прошивку, записываю в последние адресса флеша значания размера и контрольной суммы. Теперь беру и банально проверяю, совпало перехожу, не совпало сообщаю при этом программу на компьютере. При влючении питания аналогично, сперва проверяю потом прыгаю. Все правильно я собираюсь делать? Цитата(Сергей Борщ) Поищите по форуму по ключевому слову INTVEC, я буквально на прошлой неделе пример приводил. Я нашел это тему в общем мне нужно настройки линкера настроить примерно таким образом: Код -DBOOTSIZE=8000
-Z(CONST)INTRAMSTART_REMAP=00000000 -Z(CONST)INTRAMEND_REMAP=0000FFFF -Z(CONST)INTRAMSTART=00200000
-DROMSTART=(00100000+BOOTSIZE) -DROMEND=0013FFFF
-DINTVECSIZE=100 -DRAMSTART=(00200000+INTVECSIZE) -DRAMEND=0020FFFF
// Intvec always linked to 0x00-0x3F -Z(CODE)INTVEC=00000000-0000003F
// ROM -Z(CODE)INTVEC_I=ROMSTART-ROMEND -QINTVEC=INTVEC_I // place INTVEC image into INTVEC_I. -Z(CODE)ICODE,CODE,DIFUNCT,SWITAB=ROMSTART-ROMEND -Z(CONST)INITTAB,DATA_ID,DATA_C,CODE_ID=ROMSTART-ROMEND Правильно я разобрался?
Сообщение отредактировал piz2383 - Jul 23 2009, 06:10
|
|
|
|
|
Jul 23 2009, 06:18
|

читатель даташитов
   
Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999

|
Цитата(piz2383 @ Jul 23 2009, 09:08)  Ну а все-таки обозвать обработчик прерываний с помощью идентификатора __ramfunc можно? Можно. Цитата Я планирую во-первых сперва залочить область бутлоадера. Далее с программы на компьютере передаеться сперва размер прошивки и её контрольная сумма затем только прошивка. Заливаю прошивку, записываю в последние адресса флеша значания размера и контрольной суммы. Теперь беру и банально проверяю, совпало перехожу, не совпало сообщаю при этом программу на компьютере. При влючении питания аналогично, сперва проверяю потом прыгаю. Все правильно я собираюсь делать? Все правильно. Только учтите, если предусмотрена возможность обновления прошивки не только интерактивно с компьютера, то должны быть механизмы сигнализации о не успешной перепрошивке, или откат на предыдущую версию.
|
|
|
|
|
Jul 23 2009, 06:46
|

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

|
Цитата(piz2383 @ Jul 23 2009, 09:08)  Я нашел это тему в общем мне нужно настройки линкера настроить примерно таким образом: ... Правильно я разобрался? Да. Размер INTVECSIZE можно ограничить 64 байтами. Для приложения файл будет аналогичен.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|