Доброго времени суток. Есть такая задача - дистанционно перешивать девайс. Девайс сделан на атмеге и из внешних интерфейсов имеет только езернет через мост на визнете. Идея состоит в том ,что в основной программе мы получаем прошивку и шьем ее в определенную часть флеша. Потом даем сброс контроллеру, он перегружается в boot, видит какой нибудь флаг перепрошивки (например определенную последовательность байт по определенному адресу) и переливает полученную дистанционно новую прошивку по нулевому уже адресу. Естественно для таких целей запас флеша на контроллере берется в 2 раза больший максимально возможной прошивки (с учетом бутлоадера). Вопросы - 1. Были ли уже где нибудь решения похожих задач чтоб не изобретать велосипед? 2. Если нет и рыть самому -подскажите следующее - прописано что шить сам себя проц может только функциями, расположенными в секции загрузчика. Но в моему случае необходимо шить и из загрузчика и из основной программы. Так как это две разные собственно прошивки - как я могу обратиться из основной программы к функции записи флеша, скомпилированной для загрузчика? Или как решить такого плана задачу по другому?
если шить напрямую нельзя - попробуй другую память (eeprom или ОЗУ, возможно внешнее) или загрузчик учить по ЛАНу работать.
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Аппнотов начитался вдоволь, и в принципе вся инфа почуть-чуть уже начала складываться на нужные полочки в голове, но перед тем как взяться за карандаш и нарисовать первый эскиз колеса к будущему велосипеду и задал вопрос тут - возможно уже кто-то на просторах уже задавался такими вопросами.
Все встреченные мною интернетовские буты умеют общаться по встроенным в проц протоколам - uart, spi, в более сложных usb и при этом бут получает прошиву в онлайн. Засунуть обработку внешнего эзернета в бут нереально по размеру. Потому возник такой вариант. Когда прошива получается в основном теле, а потом бут ее переливает куда надо. Понятно что буду писать свой бут. Пока для себя не уяснил как из основного тела обратиться к заранее прописанным в буте процедурам записи во флеш, ибо они по требованиям атмеловцев обязаны быть там.
Update:
Правда за это время наткнулся на вариант (закину сюда может еще кого заинтересует):
Цитата:
1. Смотрю адрес нужной функции в IAR map файле: flash_page_write CODE 0001F72E
2. Создаю в основной программе указатель: void (*flash_page_write)(unsigned short) = (void (*)(unsigned short))0x1F72E; При этом IAR выдаёт предупреждение. Warning[Pe1053]: conversion from integer to smaller pointer
3. Записываю в кристалл boot, затем с его помощью загружаю и запускаю приложение. 4. Пытаюсь записать страницу памяти. Затем всё зависает. Вероятно не происходит возврата из вызванной функции. ...... Проверьте адресацию в map-файле. Вполне вероятно, что она байтовая и тогда Вы вызываете функцию по случайному адресу вместо (0x1F72E>>1); ...... Вам нужно такой оператор. void (*flash_page_write)(unsigned short) = (void (*)(unsigned short))0xFB97; // (0x1F72E>>1);
Флеш адресуется пословно, но в мепе указан побайтовый, который в 2-раза больший. ...... >> в мепе указан побайтовый Таки Бинго, работает!
можно обойтись без map-файла. т.к. по сбросу обычно получает управление бут, который затем переводит стрелки на основную программу, достаточно в обоих программах (бута и главной) прописать по фиксированному адресу в ОЗУ указатель на таблицу интерфейсных функций, и на этом все. бут начинает работу с того, что пишет в эти ячейки адрес таблицы с адресами своих интерфейсных функций, а главая программа, когда получает управление, пользуется этим адресом.
анализировать map-файл всякий раз после пересборки бута не потребуется.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Согласен идея хорошая, хотя и бут , в отличие от основной прошивы (надеюсь) менять не придется. Тем более не реально его поменять дистанционно , только программатором на столе. Адреса будут константой после отладки и заливки бута.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Идея состоит в том ,что в основной программе мы получаем прошивку и шьем ее в определенную часть флеша.
Внешнего флеша? Потому что насколько помню, только из загрузчика можно прошивать флеш, а из основной программы не получится. То что вы хотите поддерживается в МК других производителей, но не в мегах.
Нет, идея вот в чем - допустим я знаю что у меня прошивка будет не более 20кб. Я беру камень с заведомо большим флешем - допустим Atmega644 с 64к на борту. Моя родная прошива сидит в нижних 20к. Когда я хочу обновить - я передаю ей через езернет новую прошивку. Обработка эзернета итак уже есть в основной прошивке. Камень ее получает и шьет в следующие 20к просто как поток данных, вызывая процедуры записи в флеш, находящиеся уже в составе предварительно зашитого бутлоадера. Потом выставляю флаг что имеем новую прошиву и ресечусь. Естественно фьюзы выставлены так , что при старте сразу запускается бут, если нет флага - просто передает управление основной программе. при наличии флага просто запускается копирование прошивки с верхних 20к в положенные нижние и по окончании опять ресет. Собственно так поступают абсолютное все бутлоадеры, разница только в том , как я писал выше, что прошивку они получают онлайн через какой нибудь интерфейс и сразу шьют. В моем случае прошивка УЖЕ имеется на борту в виде данных - надо ее только перекинуть на положенные адреса. Весь сыр бор тут и был - как обратиться к этим процедурам чтения/записи флеша, которые находятся в секции загрузчика. Выше был предложен вариант решения. Даже два. Ну и вопрос - может кто то это уже реализовывал, не думаю я что это супер революционная идея.
Я как то задумывался над проблемой нехватки места в бутлоадере, но времени как то стало крайне мало и я забросил, но была у меня мысля(если я неправ уважаемые знатоки, поправьте ход моих мыслей): контроллер мега шьётся постранично, т.е. я сам решаю какие страницы я хочу переписать и где, в этом вроде ограничений нет кроме одного нельзя прошить ботлодыря поскольку в этот момент он "работает". С другой стороны, если нет команды на обновление прошивки бут перенаправляет контроллер на выполнение основной программы. Смысл заключается в чём: к примеру берём контроллер мега16, допустим основная прошивка будет укладываться с лихой в первые 8 Кбайт а вот размер бута ну не как не укладывается в 1 Кбайт , то почему бы функции бута не разместить после 8 Кбайт основной программы. При старте бута сразу перенаправить на данную функцию, а при прошивке переписывать только те страницы в которых находятся в первых 8Кбайтах?
Ну по логике, как я понимаю, никто не мешает так делать. Если из основной области программы ты не будешь писать самое себя. И это уже можно называть не бутлодырем, а просто каким нибудь "стартапом", который будет выполнять например какие то функции до основной программы, а не просто работать перепрошивальщиком. А можно сделать 2 разные прошивки для одного и того же контроллера и переключаться между ними по какому то флагу в том же еепроме. Полет фантазии никто не ограничивает.
можно обойтись без map-файла. т.к. по сбросу обычно получает управление бут, который затем переводит стрелки на основную программу, достаточно в обоих программах (бута и главной) прописать по фиксированному адресу в ОЗУ указатель на таблицу интерфейсных функций, и на этом все. бут начинает работу с того, что пишет в эти ячейки адрес таблицы с адресами своих интерфейсных функций, а главая программа, когда получает управление, пользуется этим адресом.
А подскажите пожалуйста тогда как в авр-студии правильно это проделать? То есть имея наши функции uint16_t writeFlashPage(uint16_t waddr, pagebuf_t size), uint16_t readFlashPage(uint16_t waddr, pagebuf_t size) - какой конструкцией взять их адрес и записать/забрать в переменную в ОЗУ по определенному адресу?
А подскажите пожалуйста тогда как в авр-студии правильно это проделать? То есть имея наши функции uint16_t writeFlashPage(uint16_t waddr, pagebuf_t size), uint16_t readFlashPage(uint16_t waddr, pagebuf_t size) - какой конструкцией взять их адрес и записать/забрать в переменную в ОЗУ по определенному адресу?
Код:
typedef uint16_t (*function)(uint16_t, pagebuf_t); // объявили тип "указатель на функцию" static const __flash function interface[2] = {writeFlashPage, readFlashPage}; // массив с адресами наших функций во flash
uint16_t result = interface[0](0, 64); // вызвали первую функцию result = interface[1](0, 64); // вызвали вторую
имя функции - это указатель на ее адрес.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Засунуть обработку внешнего эзернета в бут нереально по размеру.
Делал для LPC2368/2378 на основе NXP-шного примера из аппнота по этой теме - не только езернет, но и примитивный ip с ARP,ICMP,DHCP,UDP уместился в 0x2000 байт. Принимает данные по UDP, шьёт вызовами встроенных IAP функций. При старте проверяет на наличие программы в первом блоке флеша за своим хвостом - и, либо передаёт управление этой программе, либо ждёт команд от внешней загружающей программы. Шьёт от последнего блока к первому - понятно почему.
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
typedef uint16_t (*flashfunc_t)(uint16_t, uint8_t*, pagebuf_t); // объявили тип "указатель на функцию" //Сохраним адреса функций работы с флеш памятью по фиксированному адресу //секция flashfunc описана в настройках линкера (-Wl,--section-start=.flashfunc=0xFFF0) const flashfunc_t flashfunc[2] __attribute__ ((section (".flashfunc"))) = {writeFlashPage, readFlashPage}; // массив с адресами наших функций во flash
Main:
Код:
typedef uint16_t (*flashfunc_t)(uint16_t, uint8_t*, uint16_t); // объявили тип "указатель на функцию" flashfunc_t flashwr, flashrd;
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 37
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения