Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Снова о самопрограммировании
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Oless
Хочу сразу сказать, что перекопал уже весь форум и не только этот, прочитал avr106 но проблему устранить так и не смог.
Нужна помощь. Необходимо сделать обновление флеш программ. Для этого пытаюсь разместить код бутлоудера в отведенное ему пространство, но после программирования атмеги128 и последующего считывания код остается в начале прошивки. Как было рекомендовано в avr106, взял стандартный lnkm128s.xcl добавил в него
-D_..X_BOOTSEC_SIZE=2000 /* 4096 words */
-Z(FARCODE)BOOT_SECTION=(_..X_FLASH_END-_..X_BOOTSEC_SIZE-1)-
_..X_FLASH_END



в код программы void ExampleFunction() @ "BOOT_SECTION"{

for(ii=0;ii<100;ii++);// для теста

}


среда иар 2.31 , фьюзы BSIZ=0,BLB0=3,BLB1=3
arttab
как предположение:
задайте в адрес в явном виде, а не выражением -Z(FARCODE)BOOT_SECTION=(_..X_FLASH_END-_..X_BOOTSEC_SIZE-1)-
_..X_FLASH_END
убедитесь что BOOT_SECTION находиться в области определенной как загрузчик фузами.

мне в свое время помогла авр студия - видно что где находится и чего делает.
Oless
Получилось у меня загнать функцию в область бутлоудера, но только main, других финкциях он просто игнорирует, ПОЧЕМУ?
HELP
arttab
значит компилятор не понял Вашего указания где разместить бутовую функцию.
я выкладывал pdf с описанием как у меня получилось самопрограммирование. поищите на форуме.
sergik_vrn
Цитата(Oless @ Feb 4 2009, 12:56) *
Получилось у меня загнать функцию в область бутлоудера, но только main, других финкциях он просто игнорирует, ПОЧЕМУ?
HELP

а зачем Вы вводите новый сегмент? разместите в области загрузчика основные стандартные сегменты программы (CODE, и тд.)
например:

/* Code memory - this line is generated with preprocessor.xls */
-Z(CODE)INTVEC,FAR_F,SWITCH,INITTAB,CODE,NEAR_F=1E000-1FFFF
Oless
Цитата(sergik_vrn @ Feb 4 2009, 13:05) *
а зачем Вы вводите новый сегмент? разместите в области загрузчика основные стандартные сегменты программы (CODE, и тд.)
например:

Может я ошибаюсь, но тогда и весь остальной код попадет в эту область.
Дело в том, что уже есть написаннаяи отлаженная мною программа, которая уже около года используется у клиентов
код ее занимает 30 К, к этой программе надо добавить бутлоудер, что бы можно было обновлять прошивку удаленно,
а не лежать каждый раз с отверткой под станком
Палыч
Цитата(Oless @ Feb 4 2009, 14:13) *
... к этой программе надо добавить бутлоудер
Имхо, в этом - Ваша ошибка. Нужно не добавлять к программе бутлоудер, а сделать его. Т.е., это должны быть две программы: 1) рабочая программа; 2)бутлоудер, который заменяет любую(!) рабочую программу.
Oless
Цитата(Палыч @ Feb 4 2009, 14:08) *
Имхо, в этом - Ваша ошибка. Нужно не добавлять к программе бутлоудер, а сделать его. Т.е., это должны быть две программы: 1) рабочая программа; 2)бутлоудер, который заменяет любую(!) рабочую программу.

Возможно Вы правы, но ведь должно работать и как одна, просто так как Вы предлагаете, придется программировать в два приема, сначала бутлоудер, а потом в сети заказчика заливать прогу, я не уверен, что вложусь в 4к, по сути придется реализовывать весь протокол в будлоудере, а так можно будет взять прошивку из внешней флешь памяти загрузенной основной программой
Палыч
Цитата(Oless @ Feb 4 2009, 15:40) *
... а так можно будет взять прошивку из внешней флешь памяти загрузенной основной программой
Не очень понятно, что же Вы хотите реализовать... Но, если в процессе загрузки будут участвовать куски основной (рабочей) программы, то перезалить её Вы не сможите.
PS Основная программа может подготавливать данные для бутлоудера: считать новую рабочую программу с флэш в некую внутреннюю память устройства (не память МК) и передать управление бутлоудеру, который запишет её в память программ МК. Бутлоудер, в общем случае, может брать данные откуда Вам удобно (UART, USB или что-то ещё). Но, это будет всё равно две программы: основная (рабочая) программа и бутлоудер.

Цитата(Oless @ Feb 4 2009, 15:40) *
придется программировать в два приема, сначала бутлоудер, а потом в сети заказчика заливать прогу
Вовсе не обязательно. Располагаюся они в разных частях памяти программ и одним и тем же программатором можно записать их вместе: стирание памяти делается одно на два программирования.
GDI
Человек, видимо имеет ввиду, что он с помощью основной программы тянет откуда то прошивку и сохраняет ее , например , в ат45 на борту. Затем девайс ребутится и бутлоадер забирает код прошивки из ат45 и перешивает девайс. Судя по упоминанию "сети" заказчика, прошивка будет браться через Ethernet и обработка Ethernet-а не влезет в бутлоадер.
Палыч
Цитата(GDI @ Feb 4 2009, 16:18) *
с помощью основной программы тянет откуда то прошивку и сохраняет ее... Затем девайс ребутится и бутлоадер забирает код прошивки из ат45 и перешивает девайс.
Да - ради Бога! Но, зачем скрещивать "ужа и ежа"? Бутлоудер ведь не будет перепрошиваться у заказчика - только рабочая программа, которая в последствии тоже, возможно, будет перезалита тем же способом. Нужно строго разделить подготовку (в рабочей программе) и запись (бутлоудер).
GDI
Это да, бутлоадер отдельно всегда пишется. Как вариант решения, сделать отдельный бут, отдельную прогу, зашить бут, бутом зашить прогу, считать программатором дамп и этим дампом прошивать девайсы при производстве. При внесении изменений, все операции повторить.
Палыч
Цитата(GDI @ Feb 4 2009, 16:47) *
сделать отдельный бут, отдельную прогу, зашить бут, бутом зашить прогу
Если рабочая программа подготавливает данные для загрузчика, то предложенное Вами - проблематично: некому подготавливать...
1) Некоторым программаторам можно сказать: перед прошивкой не делать стирания памяти.
2) Можно "слить" в один два hex-файла...

PS Кстати, если рабочая программа действительно подготавливает данные для загрузчика, то у такой методы заливки есть "ахиллесова пята": в случае повреждения рабочей программы заливка новой программы загрузчиком - невозможна.
Oless
Цитата(GDI @ Feb 4 2009, 15:18) *
Человек, видимо имеет ввиду, что он с помощью основной программы тянет откуда то прошивку и сохраняет ее , например , в ат45 на борту. Затем девайс ребутится и бутлоадер забирает код прошивки из ат45 и перешивает девайс. Судя по упоминанию "сети" заказчика, прошивка будет браться через Ethernet и обработка Ethernet-а не влезет в бутлоадер.

Да, Вы правы, именно так и обстоит дело



Цитата(Палыч @ Feb 4 2009, 15:59) *
Если рабочая программа подготавливает данные для загрузчика, то предложенное Вами - проблематично: некому подготавливать...
1) Некоторым программаторам можно сказать: перед прошивкой не делать стирания памяти.
2) Можно "слить" в один два hex-файла...

PS Кстати, если рабочая программа действительно подготавливает данные для загрузчика, то у такой методы заливки есть "ахиллесова пята": в случае повреждения рабочей программы заливка новой программы загрузчиком - невозможна.



Я таки соглашусь с Вами и буду делать загрузчик отдельным проектом, почему-то мне казалось, что это не обязательно
Думаю, что слить (заменить часть hex ) будет возможным, хотя это и извращение


Спасибо
GDI
А надо всегда держать образ программы во внешней памяти и если основная программа повредилась, загрузчик должен восстановить ее, правда если развивать мысль далее, то и этот образ надо периодически проверять на битость и перезаливать если найдены повреждения. Да и вообще сделать старт девайса с бутлоадера, тогда он может проверять программу в памяти контроллера на сумму, если она не совпадает, то пытаться залить ее с носителя, предварительно проверив файл на носителе на повреждения, а дополнительно к этому еще и обрабатывать условие для перепрошивки, что влечет за собой необходимость хранить 2 версии программы, текущую и новую, но это не проблема.
Prime
Я делал так:
Отдельно заливал бутлодер, настраивал контроллер так, чтобы он всегда с него грузился. Дальше возможно два варианта - либо по состоянию какой нибудь ноги контроллера определять, хочет ли пользователь, чтобы работал загрузчик, или же выходить в основную программу. Другой вариант - ожидание внешней команды (например, мой загрузчик работал по USART, и в течении 100 мс ждал команды, а затем уходил в основную программу, если команду не получил). В данных вариантах даже если загрузчик не сможет полностью обновить прошивку из за сбоев, всегда будет работать первым бутлодер (если конечно он сам не повредиться, за этим лучше следить либо в нём самом, либо защитить его лок-битами)
IJAR
Цитата(Oless @ Feb 4 2009, 17:27) *
Да, Вы правы, именно так и обстоит дело






Я таки соглашусь с Вами и буду делать загрузчик отдельным проектом, почему-то мне казалось, что это не обязательно
Думаю, что слить (заменить часть hex ) будет возможным, хотя это и извращение


Спасибо


Вариантов решения Вашей задачи достаточно много: приведу 1.
Лучше делать 2 проекта:
1. BootLoader
2. USER proram

Boot естественно размещаете в секции Boot, USER с адреса 0x0000. В секции векторов прерывания ставие
jmp на соответствующие адреса секции USER, кроме USART-a (он исп-ся для закачки програамы USER)
Старт на BootrLoader - он настраивает USART и разрешает прерывания от него, инициализирует свои
переменные (min 16-20 ячеек RAM ими придется пожертвовать в USER а если USER уже написан, то поскать в нем). После инициализации BootLoader отдается USER-у на адрес 0x0000. При замене программы USER -
дергаете USART - преравание от него попадут BootLoader-у и он обработав его на всякие ошибко и
пароли вернется не к USER-у а в свой main и тогда весь RAM будет в его распоряжении. Дальнейшее -
дело техники и Вашей фантазии.
defunct
Цитата(IJAR @ Feb 5 2009, 23:05) *
jmp на соответствующие адреса секции USER, кроме USART-a (он исп-ся для закачки програамы USER)

Как-то закручено и неестественно получается.
Почему бы просто не выставить фуз BOOTRST, а вектора переключать в BOOT секцию с помощью бита IVSEL. Получатся два абсолютно независимых проекта.
Из BOOT'а в основную программу переходить - jmp 0x0, наоборот (из USER в BOOT) - по WDT сбросу.
Сигналить из основной программы бутлоадеру о наличии обновленной прошивки через оговоренную ячейку EEPROM.
IJAR
Цитата(defunct @ Feb 6 2009, 01:39) *
Как-то закручено и неестественно получается.
Почему бы просто не выставить фуз BOOTRST, а вектора переключать в BOOT секцию с помощью бита IVSEL. Получатся два абсолютно независимых проекта.
Из BOOT'а в основную программу переходить - jmp 0x0, наоборот (из USER в BOOT) - по WDT сбросу.
Сигналить из основной программы бутлоадеру о наличии обновленной прошивки через оговоренную ячейку EEPROM.


>Как-то закручено и неестественно получается....
>фуз BOOTRST
Вот те раз - закручено, а по-моему так прще простого.
Я же написал: Старт кристалла на BootLoader - это и подразумевает установку BOOTRST.
А вот где держать вектора: здесь понятно 2 варианта в USER секции или Boot секциии,
если нет иасходников на USER а только hex файл прошивки, тогда ес-но в Boot, если же есть исходники,
то можно и в USER (выгадываем на каждом вызове прерывания время на лишний jmp).
В конце концов USER инициализируется после BootLoader - он решит где их размещать.
Но не делать же 2 вариана Boot - так получится один унмверсальный. Преимущество моего способа
в том, что USER не обязан знать о существовании BootLoader-a кроме выделения для него нескольких
адресов RAM (это можно делать в файле конфига линкера), кроме того не требуется лишних pin-ов
на кристалле для определения "куда стартовать"

>Из BOOT'а в основную программу переходить - jmp 0x0, наоборот (из USER в BOOT) - по WDT сбросу.


Можно и так, если конечно USER сам знает когда делать обновление, хотя можно обойтись и jmp на старт Boot
Если же все идет от оператора то переход из USER в BOOT см. мой порст выше - по рывку за USART!!!

>Сигналить из основной программы бутлоадеру о наличии обновленной прошивки через оговоренную ячейку EEPROM.
А вот это ради Бога - я же написал "тут дело техники и Вашей фантазии"
defunct
Цитата(IJAR @ Feb 6 2009, 10:59) *
Преимущество моего способа в том, что USER не обязан знать о существовании BootLoader-a кроме выделения для него нескольких
адресов RAM (это можно делать в файле конфига линкера), кроме того не требуется лишних pin-ов

Ваш способ имеет право на жизнь. Но - выделить несколько адресов RAM, держать "в уме" что один из векторов "обслуживается" другим проектом - это есть зависимость одного проекта от другого... На мой взгляд проекты BOOT/USER надо строить полностью независимо друг от друга.
Насчет пинов, лишних пинов BOOT'у не нужно, а когда понадобится нечто вроде HW write-protection'a или HW реквеста обновить прошивку можно пользовать пины с ISP разъема, например MISO/MOSI.

BOOT по минимуму должен уметь:
a. Прошивать.
b. Проверять то, что прошил.
c. запускать то, что прошил.

USER:
По минимуму должен работать одинаково как с прошитым BOOT'ом, так и без него.
Dog Pawlowa
Цитата(defunct @ Feb 6 2009, 15:34) *
BOOT по минимуму должен уметь:
a. Прошивать.
b. Проверять то, что прошил.
c. запускать то, что прошил.

Я бы добавил :
0. Проверять имеющееся приложение перед тем, как на него перейти.
defunct
Цитата(Dog Pawlowa @ Feb 6 2009, 14:48) *
Я бы добавил :
0. Проверять имеющееся приложение перед тем, как на него перейти.

Это комбинация пунктов "b" и "c" smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.