Цитата(_Артём_ @ Nov 3 2012, 23:55)

Такой момент ещё не ясен: позволяет ли система команд АВР получить possition independent код.
То есть можно ли расположить функции отвечающие за self-programming на странице номер N, скопировать этот код на страницу с заданным номером и вызывать функции записи с нового адреса?
Расположить код, отвечающий за self-programming, можно на любой странице, только проблема вся в том, что этот код работает только из области бута. Причина этого в том, сами команды, стирающие и записывающие страницы флэша, способны работать только, будучи расположенными в boot-области. Граница, за которой начинается boot-область, в каких-то пределах передвигается (например, посредством установки соответствующих фузов), тем не менее, эти команды способны работать только из boot-области. Поэтому все равно фунцию-загрузчик придется размещать в boot-области.
Наибольшая здесь проблема с таблицей прерываний, содержащией адреса, куда перескакивает управление, когда возникает соотвествующее прерывание. Замена прошивки меняет эти адреса вместе с таблицей прерываний. Однако "лабильность" таблицы прерываний зачастую не дает возможности загрузчику пользоваться прерываниями в процессе загруза, а эта возможность была бы желательна для связи загрузчика с "внешним миром". Ведь должен же он откуда-то принимать ту прошивку, которую загружает? Ясно, что в boot-области эта вся прошивка не поместится, а ОЗУ/SRAM у AVR-ок по объему заведомо меньше флеша, и потому тоже не может разместить в себе загружаемую прошивку целиком. Вот и получается, что загрузчик/прошивальщик вынужден будет вести внешний обмен, чтобы откуда-то извне читать эту прошивку по частям. Причем, любой сбой во время чтения способен сделать МК неработоспосбным, т.к. старая прошивка уже начала затираться новой (на младших страницах флеша), а для старших страниц информация еще не пришла.
Такая проблема не возникнет, если прошивка слишком коротка. Но на практике флеш забивается обычно под завязку. Вот и приходится, хочешь-не хочешь, а совмещать прошивку со чтением из порта. Если это UART, то без прерываний еще можно обойтись, тупо торча в ожидании очередного байта. Но вот относительно USB я даже не представляю себе, как тут можно обойтись без прерываний. А прерываниями, выходит, пользоваться нельзя, т.к. их таблицу затерли новой, код для которой еще до конца не загружен.
Выход из этого положения можно поискать на путях создания второй таблицы прерываняи в области бута. Есть даже средства (аппаратные и программные) переключаться с одной таблицы на другую вместе с точкой запуска. Вот только реализовать этот механизм мне лично не удалось. Так и не смогла переключиться с нижней таблицы прерываний на верхнюю. Видимо не хватило усердия в этом разобраться.
И, наконец, самая сложная, на мой взгляд, проблема - как загрузчик перепишет сам себя, если сам он занимает больше, чем одну страницу? По идее тут необходим ... второй загрузчик

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