Перейти к содержанию
    

STM32L1XX - свой загрузчик

Hi, All!

1) Есть ли какой-нибудь способ перезаписать свой загрузчик в System Memory (которая с 1FF0 0000), или она в принципе readonly?

2) Если нет, то как тогда принято делать обновление прошивки своего девайса через сеть?  У меня есть внешняя SPI Flash, допустим новая версия прошивки уже загружена из интернета в нее и проверена, каковы дальнейшие действия? Я могу скопировать свой загрузчик в RAM и запустить, чтобы он переписал новую прошивку из внешней SPI Flash во внутренюю Flash кристалла. Но не нравится мне этот способ тем, что если в процессе произойдет какой-либо сбой (электричество, etc), устройство превращается в тыкву. Существует ли иной, более безопасный способ?  

3) Есть мысль поместить загрузчик в последний сектор Flash и переписывать прошивку, исполняя оттуда. Тогда, как я понимаю, таблица векторов прерываний не будет корректной, но, наверное, можно переписать прошивку с полингом, запретив глобально все прерывания на это время. Получится ли так? 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 minutes ago, sz36 said:

Существует ли иной, более безопасный способ?  

Да, есть. Воспользуйтесь поиском. Тема загрузчиков поднималась на форуме не один раз. Это я вам не потому, что лень что-то говорить, а потому что в темах собран богатый опыт. Которым нужно воспользоваться!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

30 minutes ago, sz36 said:

1) Есть ли какой-нибудь способ перезаписать свой загрузчик в System Memory?

Нет, и это правильно!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

49 минут назад, sz36 сказал:

1) Есть ли какой-нибудь способ перезаписать свой загрузчик в System Memory (которая с 1FF0 0000), или она в принципе readonly?

Есть. Обратиться к производителю чипов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Нет. Память именно для этого и Read-only. Писать в неё физически невозможно. Позозреваю масочное ПЗУ на данном месте.

2. Да. Есть варианты, в зависимости от собственно, загрузчика.

3. Можете сделать наоборот. Располагать загрузчик в первых секторах и исполнять прошивку именно с него (не трогая конфигурационные биты). Естественно, собирать прошивку нужно с соответствующим адресом начала памяти.

Практически все контроллеры ARM умеют переносить таблицу векторов в RAM. Многие - даже в произвольное место. Ищите информацию о регистре SCB->VTOR - как раз указатель на смещение таблицы векторов прерываний. На тех кристаллах, что я пробовал лично, он 32-битный и покрывает ВЕСЬ диапазон доступных адресов.

Могу предложить подобный алгоритм работы:

1. Контроллер получает новую прошивку и записывает её во Flash память. Делает в определённом месте соответствующую пометку "Нужно обновиться!".
2. Контроллер перезапускается. Стартует загрузчик.
3. Загрузчик настраивает периферию, прерывания, всё что нужно, проверяет внешнуюю память на наличие прошивки. При необходимости стирает адреса, в которые будет записана новая прошивка. В случае сбоя питания - перезагружается и начинает с начала - стирает и перезаписывает снова.
4. Загрузчик проверяет целостность прошивки, сверяет её с содержимым внешней памяти, снимает метку "Нужно обновиться" и передаёт управление на вектор сброса основной прошивки.
5. Основная прошивка копирует таблицу векторов прерываний в RAM, настраивает адрес этой самой таблицы, и работает будто ничего и не происходило.

ЗЫ: Рекомендую таки оставить лазейку для дополнительного сброса в виде WatchDog'а.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

57 минут назад, AlanDrakes сказал:

Ищите информацию о регистре SCB->VTOR

Или о битах MEMMAP и процедуре перемещения отражения памяти(remap), если придется работать с ядром Cortex-M0.

57 минут назад, AlanDrakes сказал:

Могу предложить подобный алгоритм работы:

Я уже несколько раз излагал на этом форуме свой, более простой алогритм:

  1. Загрузчик при старте проверяет, был ли это программный сброс (SYSRESETREQ).
  2. Если это не программный сброс, то он проверяет контрольную сумму приложения и если она совпала - перекидывает вектора и передает управление приложению, не трогая ни прерывания, ни периферию. Если для проверки контрольной суммы используется встроенный модуль CRC и ПДП, то они сбрасываются в исходное состояние. Таким образом приложение всегда стартует как бы с чистого листа.
  3. Если в п.2 контрольная сумма не совпала или зажата специальная нога принудительного запуска загрузчика (это позволяет восстановить устройство, впавшее в кому из-за ошибки в приложеннии) - загрузчик ожидает команды начать обновление. При этом он может отвечать еще на одну-две команды, сообщая, например, тип устройства и версию железа. Все эти команды являются подмножеством команд основного приложения. После получения команды "начать обновление", загрузчик либо делает программный сброс и попадает в п.4, или переходит в п.4 сам.
  4. Если это программный сброс - значит приложение перед этим получило команду обновления, загрузчик переходит сразу на отсылку подтверждения команды обновления и прием образа обновления.
  5. После обновления загрузчик вызывает сброс контроллера собакой (WDT), таким образом загрузчик после сброса снова с чистого листа попадет в п.2, проверит целостность загруженного образа и запустит его, если обновление было успешным. Если же обновление было неуспешным - загрузчик попадет в п.3 и будет готов к повторной попытке.
  6. Приложение, получив команду "начать обновление", делает программный сброс. Загрузчик после сброса снова начинет работать как бы с чистого листа, попадет в п.4, пошлет подтверждение приема команды обновления и начнет собственно обновление.

При этом переход приложенние->загрузчик и загрузчик->приложение происходят через сброс контроллера, работе в новом режиме не мешают всякие оставшиеся случайно активными от старого режима периферия, прерывания и ПДП. Вектора переносит загрузчик, все изменение приложения для работы с загрузчиком сводится к указанию нового адреса начала флеша редактору связей (линкеру). Индикатором перехода является уже существующий в контроллере флаг программного сброса. Программе обновления абсолютно неважно - работает в данный момент приложение или загрузчик, запуск обновления возможен в любой момент, не нужны магические передергивания питания, зажатия кнопок в момент включения или запуск обновления непеременно в течениии 30 секунд после подачи питания. Приложение готово к работе практически мгновенно после подачи питания.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

48 минут назад, Сергей Борщ сказал:

Я уже несколько раз излагал на этом форуме свой, более простой алогритм:

Всё-таки лучше разделять собственно "обновление firmware" и "загрузку нового firmware" как разные этапы. Блок-схемы переходов в этих этапах по одинаковым событиям будет разными

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, jcxz сказал:

Всё-таки лучше разделять собственно "обновление firmware" и "загрузку нового firmware" как разные этапы

Чем лучше?

У автора темы есть внешняя память, это хорошо. Он может разделять этапы, если захочет. Я изложил свой алгоритм, кому не нравится - пусть делает лучше. У меня нет внешней памяти для хранения принятого образа - мне приходится писать образ на лету, по мере приема. И вот как-то за мою практику только одно устройство имело достаточно внешней памяти для хранения загруженного образа, все остальные обновляются в процессе загрузки. А ставить контроллер с удвоенным объемом внутреннней памяти только ради разделения этапов я не готов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

32 минуты назад, Сергей Борщ сказал:

Чем лучше?

Тем что это разные задачи. И могут находиться как в одном ПО (бутлоадере) так и в разных (обновление - в бутлоадере, загрузка - в рабочем ПО).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 минут назад, jcxz сказал:

Тем что это разные задачи.

У вас - разные, у меня - одна, заказчику вообще фиолетово: он хочет нажать на кнопку и получить результат.  Впрочем, я забыл: на этом форуме ваше мнение единственно верное. Умолкаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 минуты назад, Сергей Борщ сказал:

У вас - разные, у меня - одна, заказчику вообще фиолетово: он хочет нажать на кнопку и получить результат.  Впрочем, я забыл: на этом форуме ваше мнение единственно верное. Умолкаю.

Вы как то не так прочитали мой пост.... "разные задачи" - это не "разные программы". Задача - в смысле "функционал". То что Вы описали как одну задачу, на самом деле 2 разных. Что у вас что у кого угодно. Они могут быть как в одной программе, так и в разных.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 часов назад, Сергей Борщ сказал:

Я уже несколько раз излагал на этом форуме свой, более простой алгоритм:

Отличный алгоритм, применяю его, работает как часы.

 

5 часов назад, jcxz сказал:

Всё-таки лучше разделять собственно "обновление firmware" и "загрузку нового firmware" как разные этапы.

Зачем? Чтобы вместо одной кнопки "прошить новую версию" было две кнопки "загрузить новую версию" и "применить новую версию"?

Разделять имеет смысл только если канал доставки обновления медленный/ненадёжный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

18 минут назад, AHTOXA сказал:

Зачем? Чтобы вместо одной кнопки "прошить новую версию" было две кнопки "загрузить новую версию" и "применить новую версию"?

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

Вобщем - речь совсем не о том. Речь о том, что это логически разные задачи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...