Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Self-programming из application
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
_Артём_
День добрый.

Такой вопрос: есть ли возможность перепрограммировать программную память в ходе работы программы.
Программу предполагается расположить по адресам от 0 и подпрограммы самопрограммирования в области бута.
При необходимости перешить программу будут вызываться соответствующие подпрограммы (page erase, page write и тп).
Будет ли такое работать?
SAWushka
Конечно будет, бут для того и нужен. Другой вопрос, что нужно как то следить за тем чтобы контекст не потерялся... если для вас это важно. И есть еще одни момент, опасный для вашего случая. Если в область бута вы попадаете только из основной программы.... и в момент перезаписи произошел сбой/ пропало питание и т.д. это может плохо кончится. А так, да из области бута вы сможете постранично перепрашивать флэш.
_Артём_
Цитата(SAWushka @ Nov 2 2012, 19:51) *
Другой вопрос, что нужно как то следить за тем чтобы контекст не потерялся... если для вас это важно.

Что вы называете контекстом?

Цитата(SAWushka @ Nov 2 2012, 19:51) *
И есть еще одни момент, опасный для вашего случая. Если в область бута вы попадаете только из основной программы.... и в момент перезаписи произошел сбой/ пропало питание и т.д. это может плохо кончится.

Попадаю также по старту.
Если программа сама себя переписывает, тогда опасно.

Цитата(SAWushka @ Nov 2 2012, 19:51) *
А так, да из области бута вы сможете постранично перепрашивать флэш.

Хорошо если так.
SAWushka
Цитата(_Артём_ @ Nov 3 2012, 01:08) *
Что вы называете контекстом?

Контекстом я называю регистры и переменные в оперативной памяти. Функции бута будут их использовать, и могут испортить, вам нужно позаботится о их сохранности, если планируете продолжать работу после перезаписи флэш. Если вы можете себе позволить сбросить процессор после перезаписи - так проще. Пройдете инициализацию заново и вперед.
_Pasha
Еще железобетонный вариант - заложиться под внешний еепром, основной программой писать туда, бутом делать своп флеш/еепром, он кстати в этом случае самый маленький.
Если что-то не так, откат обеспечен.
_Артём_
Цитата(SAWushka @ Nov 2 2012, 20:27) *
Контекстом я называю регистры и переменные в оперативной памяти. Функции бута будут их использовать, и могут испортить, вам нужно позаботится о их сохранности, если планируете продолжать работу после перезаписи флэш.

Нужное количество push-pop должны помочь...

Цитата(SAWushka @ Nov 2 2012, 20:27) *
Если вы можете себе позволить сбросить процессор после перезаписи - так проще. Пройдете инициализацию заново и вперед.

Думаю сбрасывать незачем.

Цитата(_Pasha @ Nov 2 2012, 20:41) *
Еще железобетонный вариант - заложиться под внешний еепром, основной программой писать туда, бутом делать своп флеш/еепром, он кстати в этом случае самый маленький.

внешняя еепром не предполагается.

Цитата(_Pasha @ Nov 2 2012, 20:41) *
Если что-то не так, откат обеспечен.

Стадию процесса надо ещё сохранять как-то.
_Pasha
Цитата(_Артём_ @ Nov 2 2012, 22:46) *
внешняя еепром не предполагается.

Мне нравится поругаемый многими подход, когда в области бута содержится нетленный протокол, например с модбас с вызовом специальной функции. Этот протокол используется совместно и аппликухой и загрузчиком, через системные вызовы - например, таблица функций в последних адресах флеша.
Если сюда заглянет Сергей Борщ, он непременно раскритикует это, интересно послушать его подход.

Цитата
Стадию процесса надо ещё сохранять как-то.

Это даже не обсуждается - и так понятно.
_Артём_
Такой момент ещё не ясен: позволяет ли система команд АВР получить possition independent код.
То есть можно ли расположить функции отвечающие за self-programming на странице номер N, скопировать этот код на страницу с заданным номером и вызывать функции записи с нового адреса?

Делал ли кто-нибудь такое?
Xenia
Цитата(_Артём_ @ Nov 3 2012, 23:55) *
Такой момент ещё не ясен: позволяет ли система команд АВР получить possition independent код.
То есть можно ли расположить функции отвечающие за self-programming на странице номер N, скопировать этот код на страницу с заданным номером и вызывать функции записи с нового адреса?


Расположить код, отвечающий за self-programming, можно на любой странице, только проблема вся в том, что этот код работает только из области бута. Причина этого в том, сами команды, стирающие и записывающие страницы флэша, способны работать только, будучи расположенными в boot-области. Граница, за которой начинается boot-область, в каких-то пределах передвигается (например, посредством установки соответствующих фузов), тем не менее, эти команды способны работать только из boot-области. Поэтому все равно фунцию-загрузчик придется размещать в boot-области.

Наибольшая здесь проблема с таблицей прерываний, содержащией адреса, куда перескакивает управление, когда возникает соотвествующее прерывание. Замена прошивки меняет эти адреса вместе с таблицей прерываний. Однако "лабильность" таблицы прерываний зачастую не дает возможности загрузчику пользоваться прерываниями в процессе загруза, а эта возможность была бы желательна для связи загрузчика с "внешним миром". Ведь должен же он откуда-то принимать ту прошивку, которую загружает? Ясно, что в boot-области эта вся прошивка не поместится, а ОЗУ/SRAM у AVR-ок по объему заведомо меньше флеша, и потому тоже не может разместить в себе загружаемую прошивку целиком. Вот и получается, что загрузчик/прошивальщик вынужден будет вести внешний обмен, чтобы откуда-то извне читать эту прошивку по частям. Причем, любой сбой во время чтения способен сделать МК неработоспосбным, т.к. старая прошивка уже начала затираться новой (на младших страницах флеша), а для старших страниц информация еще не пришла.

Такая проблема не возникнет, если прошивка слишком коротка. Но на практике флеш забивается обычно под завязку. Вот и приходится, хочешь-не хочешь, а совмещать прошивку со чтением из порта. Если это UART, то без прерываний еще можно обойтись, тупо торча в ожидании очередного байта. Но вот относительно USB я даже не представляю себе, как тут можно обойтись без прерываний. А прерываниями, выходит, пользоваться нельзя, т.к. их таблицу затерли новой, код для которой еще до конца не загружен.

Выход из этого положения можно поискать на путях создания второй таблицы прерываняи в области бута. Есть даже средства (аппаратные и программные) переключаться с одной таблицы на другую вместе с точкой запуска. Вот только реализовать этот механизм мне лично не удалось. Так и не смогла переключиться с нижней таблицы прерываний на верхнюю. Видимо не хватило усердия в этом разобраться.

И, наконец, самая сложная, на мой взгляд, проблема - как загрузчик перепишет сам себя, если сам он занимает больше, чем одну страницу? По идее тут необходим ... второй загрузчик sm.gif, который бы затер первый, а тот запустившись следом, затер бы второй. Но даже от постановки такой задачи становится нестерпимо смешно, не говоря уже о практической реализации. sm.gif
_Артём_
Цитата(Xenia @ Nov 4 2012, 00:44) *
Поэтому все равно фунцию-загрузчик придется размещать в boot-области.

Достаточно расположить в бут-области функцию перезаписи страницы. На это требуется байтов 100-200.

Цитата(Xenia @ Nov 4 2012, 00:44) *
Но вот относительно USB я даже не представляю себе, как тут можно обойтись без прерываний.


Хорошо, что мне usb не надо...

Цитата(Xenia @ Nov 4 2012, 00:44) *
Выход из этого положения можно поискать на путях создания второй таблицы прерываняи в области бута. Есть даже средства (аппаратные и программные) переключаться с одной таблицы на другую вместе с точкой запуска.

Не, вторую таблицу в одной области не создать.
Разве что переключаться с помощью MCUCR.IVSEL, но это что-то особенного...

Цитата(Xenia @ Nov 4 2012, 00:44) *
Вот только реализовать этот механизм мне лично не удалось. Так и не смогла переключиться с нижней таблицы прерываний на верхнюю. Видимо не хватило усердия в этом разобраться.

Скорее не нужно было, там вроде несложно.

Цитата(Xenia @ Nov 4 2012, 00:44) *
И, наконец, самая сложная, на мой взгляд, проблема - как загрузчик перепишет сам себя, если сам он занимает больше, чем одну страницу? По идее тут необходим ... второй загрузчик sm.gif,

Второй - это мысль: в буте - только функции самопрограммирования в двух экземплярах (на всякий случай), а сам загрузчик - где нибудь в конце application section.
Цитата(Xenia @ Nov 4 2012, 00:44) *
который бы затер первый, а тот запустившись следом, затер бы второй. Но даже от постановки такой задачи становится нестерпимо смешно, не говоря уже о практической реализации. sm.gif

Да уж, и вовсе не смешно...
_Pasha
Цитата(Xenia @ Nov 4 2012, 02:44) *
Выход из этого положения можно поискать на путях создания второй таблицы прерываняи в области бута. Есть даже средства (аппаратные и программные) переключаться с одной таблицы на другую вместе с точкой запуска. Вот только реализовать этот механизм мне лично не удалось. Так и не смогла переключиться с нижней таблицы прерываний на верхнюю. Видимо не хватило усердия в этом разобраться.

Можно патчить нижнюю IVT, заменяя векторы, которые "хотим" от бута на NOP - сам бут проверяет и делает замену. При этом возникают вопросы:
1. Как разрулить CRC, т.е. тут считаем по оригиналу, а тут местный контроль - чисто для таблицы.
2. Как совместно использовать данные, инкапсулированные в бут - опять же, системные вызовы либо таблица адресов, например, очередь, используемая в прерываниях uart, - и всё это в последних адресах флеша. Потом, линкером надо шаманить, чтобы по абсолютным адресам в ОЗУ зарезервировать... некомфортно. Хотя, можно свести всё к одному хэндлу - указателю на структуру, используемую в прерываниях. Два байта делов-то. И хранить в самых "ненужных" регистрах из r2..14. Видимо, так даже лучше.

С лок-битами, конечно, не всё красиво, потому что может быть надо разрешить читать аппликухе из бут-области.
---
Для меня самая неподъёмная задача была - как сделать на меге48 - там SPM есть, а области загрузки нету. Получилось частное решение с изуродованным стартапом. Глупости.

В общем, при использовании протокола уровня модбаса и сложнее все-таки лучше внешняя память...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.