sz36 0 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба Hi, All! 1) Есть ли какой-нибудь способ перезаписать свой загрузчик в System Memory (которая с 1FF0 0000), или она в принципе readonly? 2) Если нет, то как тогда принято делать обновление прошивки своего девайса через сеть? У меня есть внешняя SPI Flash, допустим новая версия прошивки уже загружена из интернета в нее и проверена, каковы дальнейшие действия? Я могу скопировать свой загрузчик в RAM и запустить, чтобы он переписал новую прошивку из внешней SPI Flash во внутренюю Flash кристалла. Но не нравится мне этот способ тем, что если в процессе произойдет какой-либо сбой (электричество, etc), устройство превращается в тыкву. Существует ли иной, более безопасный способ? 3) Есть мысль поместить загрузчик в последний сектор Flash и переписывать прошивку, исполняя оттуда. Тогда, как я понимаю, таблица векторов прерываний не будет корректной, но, наверное, можно переписать прошивку с полингом, запретив глобально все прерывания на это время. Получится ли так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба 2 minutes ago, sz36 said: Существует ли иной, более безопасный способ? Да, есть. Воспользуйтесь поиском. Тема загрузчиков поднималась на форуме не один раз. Это я вам не потому, что лень что-то говорить, а потому что в темах собран богатый опыт. Которым нужно воспользоваться! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба 30 minutes ago, sz36 said: 1) Есть ли какой-нибудь способ перезаписать свой загрузчик в System Memory? Нет, и это правильно! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба 49 минут назад, sz36 сказал: 1) Есть ли какой-нибудь способ перезаписать свой загрузчик в System Memory (которая с 1FF0 0000), или она в принципе readonly? Есть. Обратиться к производителю чипов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба Стать производителем чипов Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlanDrakes 1 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба 1. Нет. Память именно для этого и Read-only. Писать в неё физически невозможно. Позозреваю масочное ПЗУ на данном месте. 2. Да. Есть варианты, в зависимости от собственно, загрузчика. 3. Можете сделать наоборот. Располагать загрузчик в первых секторах и исполнять прошивку именно с него (не трогая конфигурационные биты). Естественно, собирать прошивку нужно с соответствующим адресом начала памяти. Практически все контроллеры ARM умеют переносить таблицу векторов в RAM. Многие - даже в произвольное место. Ищите информацию о регистре SCB->VTOR - как раз указатель на смещение таблицы векторов прерываний. На тех кристаллах, что я пробовал лично, он 32-битный и покрывает ВЕСЬ диапазон доступных адресов. Могу предложить подобный алгоритм работы: 1. Контроллер получает новую прошивку и записывает её во Flash память. Делает в определённом месте соответствующую пометку "Нужно обновиться!". 2. Контроллер перезапускается. Стартует загрузчик. 3. Загрузчик настраивает периферию, прерывания, всё что нужно, проверяет внешнуюю память на наличие прошивки. При необходимости стирает адреса, в которые будет записана новая прошивка. В случае сбоя питания - перезагружается и начинает с начала - стирает и перезаписывает снова. 4. Загрузчик проверяет целостность прошивки, сверяет её с содержимым внешней памяти, снимает метку "Нужно обновиться" и передаёт управление на вектор сброса основной прошивки. 5. Основная прошивка копирует таблицу векторов прерываний в RAM, настраивает адрес этой самой таблицы, и работает будто ничего и не происходило. ЗЫ: Рекомендую таки оставить лазейку для дополнительного сброса в виде WatchDog'а. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба 57 минут назад, AlanDrakes сказал: Ищите информацию о регистре SCB->VTOR Или о битах MEMMAP и процедуре перемещения отражения памяти(remap), если придется работать с ядром Cortex-M0. 57 минут назад, AlanDrakes сказал: Могу предложить подобный алгоритм работы: Я уже несколько раз излагал на этом форуме свой, более простой алогритм: Загрузчик при старте проверяет, был ли это программный сброс (SYSRESETREQ). Если это не программный сброс, то он проверяет контрольную сумму приложения и если она совпала - перекидывает вектора и передает управление приложению, не трогая ни прерывания, ни периферию. Если для проверки контрольной суммы используется встроенный модуль CRC и ПДП, то они сбрасываются в исходное состояние. Таким образом приложение всегда стартует как бы с чистого листа. Если в п.2 контрольная сумма не совпала или зажата специальная нога принудительного запуска загрузчика (это позволяет восстановить устройство, впавшее в кому из-за ошибки в приложеннии) - загрузчик ожидает команды начать обновление. При этом он может отвечать еще на одну-две команды, сообщая, например, тип устройства и версию железа. Все эти команды являются подмножеством команд основного приложения. После получения команды "начать обновление", загрузчик либо делает программный сброс и попадает в п.4, или переходит в п.4 сам. Если это программный сброс - значит приложение перед этим получило команду обновления, загрузчик переходит сразу на отсылку подтверждения команды обновления и прием образа обновления. После обновления загрузчик вызывает сброс контроллера собакой (WDT), таким образом загрузчик после сброса снова с чистого листа попадет в п.2, проверит целостность загруженного образа и запустит его, если обновление было успешным. Если же обновление было неуспешным - загрузчик попадет в п.3 и будет готов к повторной попытке. Приложение, получив команду "начать обновление", делает программный сброс. Загрузчик после сброса снова начинет работать как бы с чистого листа, попадет в п.4, пошлет подтверждение приема команды обновления и начнет собственно обновление. При этом переход приложенние->загрузчик и загрузчик->приложение происходят через сброс контроллера, работе в новом режиме не мешают всякие оставшиеся случайно активными от старого режима периферия, прерывания и ПДП. Вектора переносит загрузчик, все изменение приложения для работы с загрузчиком сводится к указанию нового адреса начала флеша редактору связей (линкеру). Индикатором перехода является уже существующий в контроллере флаг программного сброса. Программе обновления абсолютно неважно - работает в данный момент приложение или загрузчик, запуск обновления возможен в любой момент, не нужны магические передергивания питания, зажатия кнопок в момент включения или запуск обновления непеременно в течениии 30 секунд после подачи питания. Приложение готово к работе практически мгновенно после подачи питания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба 48 минут назад, Сергей Борщ сказал: Я уже несколько раз излагал на этом форуме свой, более простой алогритм: Всё-таки лучше разделять собственно "обновление firmware" и "загрузку нового firmware" как разные этапы. Блок-схемы переходов в этих этапах по одинаковым событиям будет разными Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sz36 0 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба Всем спасибо, буду пробовать Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба 1 час назад, jcxz сказал: Всё-таки лучше разделять собственно "обновление firmware" и "загрузку нового firmware" как разные этапы Чем лучше? У автора темы есть внешняя память, это хорошо. Он может разделять этапы, если захочет. Я изложил свой алгоритм, кому не нравится - пусть делает лучше. У меня нет внешней памяти для хранения принятого образа - мне приходится писать образ на лету, по мере приема. И вот как-то за мою практику только одно устройство имело достаточно внешней памяти для хранения загруженного образа, все остальные обновляются в процессе загрузки. А ставить контроллер с удвоенным объемом внутреннней памяти только ради разделения этапов я не готов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба 32 минуты назад, Сергей Борщ сказал: Чем лучше? Тем что это разные задачи. И могут находиться как в одном ПО (бутлоадере) так и в разных (обновление - в бутлоадере, загрузка - в рабочем ПО). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба 15 минут назад, jcxz сказал: Тем что это разные задачи. У вас - разные, у меня - одна, заказчику вообще фиолетово: он хочет нажать на кнопку и получить результат. Впрочем, я забыл: на этом форуме ваше мнение единственно верное. Умолкаю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба 3 минуты назад, Сергей Борщ сказал: У вас - разные, у меня - одна, заказчику вообще фиолетово: он хочет нажать на кнопку и получить результат. Впрочем, я забыл: на этом форуме ваше мнение единственно верное. Умолкаю. Вы как то не так прочитали мой пост.... "разные задачи" - это не "разные программы". Задача - в смысле "функционал". То что Вы описали как одну задачу, на самом деле 2 разных. Что у вас что у кого угодно. Они могут быть как в одной программе, так и в разных. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба 5 часов назад, Сергей Борщ сказал: Я уже несколько раз излагал на этом форуме свой, более простой алгоритм: Отличный алгоритм, применяю его, работает как часы. 5 часов назад, jcxz сказал: Всё-таки лучше разделять собственно "обновление firmware" и "загрузку нового firmware" как разные этапы. Зачем? Чтобы вместо одной кнопки "прошить новую версию" было две кнопки "загрузить новую версию" и "применить новую версию"? Разделять имеет смысл только если канал доставки обновления медленный/ненадёжный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 27 марта, 2019 Опубликовано 27 марта, 2019 · Жалоба 18 минут назад, AHTOXA сказал: Зачем? Чтобы вместо одной кнопки "прошить новую версию" было две кнопки "загрузить новую версию" и "применить новую версию"? Нет. Чтобы загружать прошивку по рабочему каналу связи, не мешая работе этого канала. Да и протокол, ходящий по этому каналу, может быть достаточно сложным и какой смысл его писать и отлаживать дважды? Вобщем - речь совсем не о том. Речь о том, что это логически разные задачи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться