misyachniy 0 15 июня, 2014 Опубликовано 15 июня, 2014 · Жалоба Есть уже готовый проект. Теперь к нему нужно прикрутить возможность обновления ПО в приложении. Предполагается 2(4) метода получения ПО в EEPROM 1) По USB в штатном/аварийном режиме. 2) По FTP через GPRS в штатном/аварийном режиме. В найденых мною примерах bootloader пишется и компилируется отдельно. Программа пишется отдельно и компилируется по разному, для отладки и для загрузки через бутлоадер. Прием данных в EEPROM возможен как при обновлени так при при отказе соновной прошивки, следовательно нецелесообразно в бутлоадере и а основной программе дублировать функции для работы USB, GPRS, EEPROM. Bootloader и основную пограмму можно положиь в разных секциях flash и компилировать один проект. Затем с двоичного файла отрезать нужный кусок. В сети не нашел подобных вариантов. Очевидно что есть скрытые (или очевидные :-) недостатки такого метода. Какие именно недостатки? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 15 июня, 2014 Опубликовано 15 июня, 2014 · Жалоба Компилировать как один проект нельзя - как же вы потом отрежете? Там ведь возможны перекрёстные ссылки. Например: функция a() используется и в основной программе и в загрузчике. Естественно, что компилятор не будет (и не сможет) делать две её копии. По-любому надо два разных проекта, которые и собирать по-отдельности. И линковать в разные области flash. А уж готовые бинарники можно и склеить при желании. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Axel 1 15 июня, 2014 Опубликовано 15 июня, 2014 · Жалоба Какие именно недостатки? "Категорический" недостаток - невозможность апгрейда совместно используемых фрагментов. Остальное - просто дополнительные хлопоты по их размещению и интерфейсу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 15 июня, 2014 Опубликовано 15 июня, 2014 · Жалоба дополнительные хлопоты :) Ну если так можно назвать переписывание стандартного си-стартапа, чтобы разделить функции main(), а также сегменты инициализации глобальных и static переменных. Это кроме всего прочего. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
A. Fig Lee 0 15 июня, 2014 Опубликовано 15 июня, 2014 · Жалоба Что такое "бутлоадер EEPROM"? Просто менять EEPROM бутлоадер не нужен. Или речь о флаш идет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Axel 1 15 июня, 2014 Опубликовано 15 июня, 2014 · Жалоба дополнительные хлопоты :) Это кроме всего прочего. Конечно, Вы правы. Но все-таки это из разряда "Если нельзя, но очень хочется - то можно...". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
A. Fig Lee 0 15 июня, 2014 Опубликовано 15 июня, 2014 · Жалоба "Категорический" недостаток - невозможность апгрейда совместно используемых фрагментов. Остальное - просто дополнительные хлопоты по их размещению и интерфейсу. Не только совместно используемых, основную программу тоже с оглядкой надо будет апгрейдить. Бутлоадер всегда должен быть полностью отдельным. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 15 июня, 2014 Опубликовано 15 июня, 2014 (изменено) · Жалоба Проблема в том, что если вы откомпилируете с разными уровнями оптимизации кода или перейдете на новую версию компилятора, то точки входа в модули в бутлодере сползут и появится несовместимость версий и прочие беды. Если конечно функции привязать к конкретным адресам, то будет полегче, но все равно это будет неудобно. Отдельно делать банально легче технически. А хранить куски кода в бутлодере - правильно ли идеологически? - вы же как раз хотите обновлять код, а как это делать если все массивные части у вас будут залочены... Бутлодер должен быть лаконичным, максимально надежным куском кода, который поднимет девайс из любого убитого состояния, который обновлять не будет нужно никогда. Например должно быть так: основная прошивка должна загрузить код по FTP в промежуточную память (конечно если она есть), а бутлодер уже из этой памяти взять код, проверить на целостность и уже потом прошить. Изменено 15 июня, 2014 пользователем kan35 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 15 июня, 2014 Опубликовано 15 июня, 2014 · Жалоба и не надо писать одинаковые функции обновления прошивки из основной программы и из бутлоадера. Все можно свести к задаче обновления из бутлоадера. Достаточно сделать режим загрузки бутлоадера. 1. по флагу в памяти или горячей перезагрузки с флагом в РАМе 2. по специальной команде в начале загрузки (зажатая кнопка, или команда по порту и т.д.) 3. по отсутствию валидной прошивки (контрольная сумма, код безопасности и так далее. любой из 3 сработавших вариантов переводит схему в режим обновления прошивки, если все проскочили то штатная загрузка. Такую схему вы никогда не превратите в кирпич. А также поддержка перезаписи памяти программы надо поддержать всего в одном месте в загрузчике, основной прошивки не надо даже давать возможность это делать. Загрузчик примитивен, без инициативы, а значит может применяться во всех ваших прочих устройствах, не зависимо от того что они делают. Мы уже такой загрузчик не глядя в приборы втыкаем... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
A. Fig Lee 0 16 июня, 2014 Опубликовано 16 июня, 2014 · Жалоба Бутлодер должен быть лаконичным, максимально надежным куском кода, который поднимет девайс из любого убитого состояния, который обновлять не будет нужно никогда. Например должно быть так: основная прошивка должна загрузить код по FTP в промежуточную память (конечно если она есть), а бутлодер уже из этой памяти взять код, проверить на целостность и уже потом прошить. Угу. А потом эта загруженная программа откажется работать. И прощай фтп Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Axel 1 16 июня, 2014 Опубликовано 16 июня, 2014 · Жалоба Угу. А потом эта загруженная программа откажется работать. И прощай фтп Вполне вероятная перспектива. В реальности технология "Семь раз отмерь..." не всегда реализуема и перекладывание части функций загрузчика на основную программу (что, собственно, и предусматривает концепция "лаконичности") - прямой путь к неприятностям. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 16 июня, 2014 Опубликовано 16 июня, 2014 · Жалоба Имеет право на жизнь и такой вариант, какой вы описали. Но он слишком хлопотный. Например в ПЛК сименс можно заменить даже отдельные процедуры. Причём прямо на лету. Правда при этом хранятся не только копии программ, но и копии данных. Требуется полное совпадение данных. Они определённым образом обезличены, по отношению к другим модулям. Ну и так далее ... ;) Короче, если не готовы продумать все эти детали и подробности, то значительно проще, использовать независимый бут и независимое приложение. Пусть там что-то и будет дублироваться. В конечном итоге, работа бута состоит только в загрузке приложения. И он может быть даже неэфективным. Может годами не модифицироваться. Необходимо чтобы он просто выполнял свою функцию. А вот приложение, может непрерывно совершенствоваться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
misyachniy 0 19 июня, 2014 Опубликовано 19 июня, 2014 · Жалоба Взял пример AN2557 переделал прием данных по UART в чтение из EEPROM. Увеличил размер под bootloader в проекте bootloader-а #define ApplicationAddress 0x8004000 И подкорректировал stm32f10x_flash_offset.icf define symbol __ICFEDIT_region_ROM_start__ = 0x08004000; Скомпилировал пример и загрузил в EEPROM. bootloader корректно стирает Program memory, пишет в нее программу но не запускает приложение. Не проходит проверка: // Test if user code is programmed starting from address "ApplicationAddress" if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000) { /* Jump to user application */ JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4); Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) ApplicationAddress); Jump_To_Application(); } По ApplicationAddress у меня храняться байты 00 04 00 20 Что переводиться в unsigned int как 0x20000400 После наложения маски 0x20000000 условие должно выполняться и запускаться программа, но отладчик пропускает выполнеие и вываливается на конец программы while (1) {} Почему7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 60 19 июня, 2014 Опубликовано 19 июня, 2014 · Жалоба Чудес не бывает - смотрите отладчиком. Делал бутлодер и с поддержкой GPRS и полностью автономный. Загрузка только измененными кусками и полностью. Всё работает так как и задумано. Никаких проблем с процессором не возникало ни разу. Просто надо продумать всё заранее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kolobok0 0 21 июня, 2014 Опубликовано 21 июня, 2014 · Жалоба ...В конечном итоге, работа бута состоит только в загрузке приложения..... сделал просче - бут обеспечивает только старт рабочей версии. Всё остальное (каналы прихода прошивки, её обработка и т.д..) делает сама прошивка. Т.к. во флеше хранится более чем одна рабочая копия, то откатиться на устойчивую версию в любой момент времени - труда не составляет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться