Jump to content

    

обновление прошивки через эзернет-чо требуется.

Здравствуйте.

Затевается разработка новой железки.

До этого основным типом контроллера для меня был AVR. Если требовался

эзернет ставил ENC28j60.

После того как Атмел умер все это прилично подорожало да и ресурсов

AVR-ки уже маловато.

Сейчас на столе отладка с wiznet -овским чипом W7500p.

Пощупал на нем GPIO, АЦП, таймера.

Поработал с UDP и TCP. Поставил ScmRtos. Вроде все работает и в общем нравится.

Но начальство требует чтобы все было стильно и молодежно, т.е управление через web

и через него-же обновление прошивки.

Ну простенькую вэб-страничку я изобразил, дальше буду читать и думать.

Подходит время рисовать боевую схему. Лоадерами до этого я не занимался и какие

минимальные требования к дополнительному железу не очень не представляю.

У моего контроллера на борту стандартный Кортекс-М0 128К флэша 16к ОЗУ.

Есть ли работающие проэкты для образца или библиотеки?

Ткните, плиз, в соответствующую сторону.

Share this post


Link to post
Share on other sites

Бегло глянул на этот контроллер.
Поставьте внешнюю энергонезависимую память типа EEPROM, а лучше FRAM. Они копеечные, а пригодятся во многом. Небольшие логи писать об ошибках, например. Ну и флаг обновления ПО там можно хранить. Для чисто загрузчика можно вообще ничего внешнего не ставить, если ресурсов внутренних хватает.

Я Web-морды не делаю, у меня для железок утилиты работы с ним есть самописные. В том числе и загрузчик. Но, думаю, это не столь важно. Загрузчик я написал один универсальный, имеет единый протокол общения с железкой, а на стороне железки я поддерживаю этот протокол и все.

Ну а логика работы загрузчика примерно следующая:

1. При старте МК считывает энергонезависимый флажок (переменную), сигнализирующую о необходимости обновить ПО. Этот флажок может находиться как во внутренней памяти МК, так и во внешней, той же EEPROM (как, например, сейчас у меня). Естественно, перед этим настраивается минимально необходимая периферия для обращения к EEPROM. Отмечу, что МК на старте не разгоняю для работы на высоких частотах.

2. Если флажок установлен (нужно обновить ПО), я деинициализирую все, что инициализировал для доступа к энергонезависимому флагу и перехожу в main() загрузчика.

3. В main() загрузчика настраиваю тактовый генератор, периферию Ethernet-а, стек TCP/IP (LwIP, например) и прочую минимально необходимую периферию для приема прошивки.

4. Жду команды "CONNECT" от ПК (по UDP или TCP, тут как угодно).

5. ПК отправляет нужные команды на стирание области Flash-памяти пользовательского приложения, МК отправляет, в свою очередь, ответы, что все хорошо или не хорошо потерлось.

6. ПК отправляет пакеты с прошивкой (тут как душе угодно, можно шифровать, можно нет). МК принимает их, прошивает Flash-память, также отправляет ответы на ПК, что успешно проглотил кусок прошивки. Естественно, каждый пакет я сопровождаю CRC32.

7. После завершения я считаю CRC32 всего образа из Flash и отправляю на ПК. Если CRC32 совпал с тем, что ПК прислал мне при команде "CONNECT", затираю энергонезависимый флаг в памяти и делаю аппаратный сброс по WDT или программный (аля NVIC_SystemReset()).

8. МК сбрасывается, повторяет шаг 1 и видит, что флажок обновления ПО стерт, то есть прошивка завершилась корректно, поэтому она снова приводит в исходное состояние периферию, использованную для доступа к флагу (EEPROM, FRAM и т.д.), настраивает таблицу векторов прерываний, указатель стека и передает управление по адресу начала пользовательского приложения.

В Вашем случае, поскольку внутри SoC уже аппаратно реализован TCP/IP стек часть телодвижений уже не будет нужна, поэтому будет уже намного проще.

Share this post


Link to post
Share on other sites
5 hours ago, KRTPC said:

Ткните, плиз, в соответствующую сторону.

Неудачную RTOS однако выбрали.

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

Например mcuboot    под  RTOS  Zephyr . Поддерживает шифрование и ключи RSA. 
Эта RTOS портирована на все самые ходовые платформы от Arduino до STM32 и ESP8266. Чипы с Cortex-M0 тоже есть в списке.
Имеет TCP стек, драйвер к enc28j60 и кучу других фичей. 

Мало того, Zephyr поддерживает новейшие технологии Web USB и WEB Bluetooth. 
Нынче чтобы работать через броузер не обязательно поднимать TCP сервер. 

 

Share this post


Link to post
Share on other sites

2 Arlleex.  Самописная программа на РС  начальству не очень понравится, я думаю. Но идею я понял, спасибо.

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

бросок по питанию?

Пакеты какого размера вы посылаете контроллеру? Равные одной секции флэша? И после приема храните их в

ОЗУ контроллера или в энергонезависимой внешней памяти?

 

Share this post


Link to post
Share on other sites
6 minutes ago, KRTPC said:

2 Arlleex. Самописная программа на РС начальству не очень понравится, я думаю. Но идею я понял, спасибо.

А зря. Иногда даже красивше выглядит, нежели Web-морда. Хотя тут как сделаешь. Можно заморочиться, а можно и нет.

 

6 minutes ago, KRTPC said:

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

бросок по питанию?

К сбоям устойчив. Бросок по питанию - МК перезагрузится, увидит, что прошивка прошла не до конца, программа на ПК увидит, что ответы приходят не ожидаемого формата в данном цикле (прошивка, например). МК снова войдет в загрузчик и снова будет ожидать команды подключения. Отвалился Ethernet - вышли по таймауту в ПК и отписали, что отвалился канал связи. Сеть через кучу коммутаторов и роутеров? Используем TCP. В МК же жесткий автомат приема и обработки пакетов. В нем у меня состояний нет, у меня что-то типа

switch(ServerBoot.Command)

{

    case SERVER_CMD_CONNECT: ... break;

    case SERVER_CMD_ERASE: ... break;

    case SERVER_CMD_PROGRAM: ... break;

   ...

}

 

А флаг правильной отработки загрузчика сбросится только тогда, когда сойдется CRC32 загруженной прошивки с той, что посчитал ПК для того же файла.

Единственное, над чем надо подумать, это как писать прикладное ПО так, чтобы оно обеспечивало корректный вход в загрузчик. У меня шлется специальная команда по Ethernet, в ее обработчике я устанавливаю энергонезависимый флаг в положение "нужно обновить ПО" и делаю программный сброс. Ну а дальше как все описано в первом посте. Тут дело в том, что если программист прикладного ПО затупит и каким-то образом заблокирует обработку команды обновления ПО - то приехали, вскрывай корпус и подключай программатор. Но и это можно обойти. В одном из проектов у меня просто загрузчик всегда стартует безусловно, и, если в течение 5с к нему не подключится TCP-клиент программатора, передает управление основной программе. Там время загрузки системы не критично.

 

6 minutes ago, KRTPC said:

Пакеты какого размера вы посылаете контроллеру? Равные одной секции флэша? И после приема храните их в

ОЗУ контроллера или в энергонезависимой внешней памяти?

У меня сейчас пакеты одинаковой длины, полезных данных с куском образа прошивки из них 1кбайт. Принимаются они по Ethernet и хранятся, естественно, в ОЗУ-буферах. Получается, что я по чуть-чуть скармливаю железке пакеты. Также в общей структуре отправляю общий размер прошивки и текущее количество полезных данных, которые в этом 1кбайт-овом массиве хранятся. Тут тоже на вкус и цвет - можно сделать автомат приема "поумнее" и избавиться от некоторых служебных полей в структуре, но это экономия на спичках. По-хорошему, надо еще, конечно же, некоторые функции загрузчика разместить в ОЗУ перед приемом данных, но мне это не требуется.

Edited by Arlleex

Share this post


Link to post
Share on other sites
1 час назад, KRTPC сказал:

Ну тогда можете не сами писать, а заказать её у других. Здесь есть соответствующий раздел: "Предлагаю работу".

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

Пакеты какого размера вы посылаете контроллеру? Равные одной секции флэша? И после приема храните их в

ОЗУ контроллера или в энергонезависимой внешней памяти?

Начать Вам нужно с изучения раздела "Program Flash" мануала на МК. А не с поиска готовых "либ".

И вопросы безопасного обновления прошивок здесь на форуме уже поднимались неоднократно. Есть подробные описания алгоритмов. Достаточно воспользоваться поиском.

Share this post


Link to post
Share on other sites

Т.е для загрузчика внешняя, а тем более энергонезависимая память в общем-то и не нужна.

Нужно только только хранить признак что бутлодер уже стартовал и  при перезагрузке

надо стартовать в него, а н ев основное приложение? Которое возможно уже и потерто.

Share this post


Link to post
Share on other sites
14 минут назад, jcxz сказал:

Ну тогда можете не сами писать, а заказать её у других. Здесь есть соответствующий раздел: "Предлагаю работу".

Начать Вам нужно с изучения раздела "Program Flash" мануала на МК. А не с поиска готовых "либ".

И вопросы безопасного обновления прошивок здесь на форуме уже поднимались неоднократно. Есть подробные описания алгоритмов. Достаточно воспользоваться поиском.

Раздел " Embedded Flash memory" в даташите я как раз изучаю второй день.  Уже даже сектор флэша стер-записал.

Но от рабочего проекта "на посмотреть" я-бы тоже не отказался...

Share this post


Link to post
Share on other sites
13 минут назад, KRTPC сказал:

Т.е для загрузчика внешняя, а тем более энергонезависимая память в общем-то и не нужна.

Только если в загрузчике реализован и процесс приёма прошивки. Со всеми TCP-стеками и прочей. Но такой загрузчик становится сам уже приличного размера, и в полный рост встаёт проблема обновления прошивки этого самого загрузчика (чем больше загрузчик -> тем вероятнее наличие багов в нём -> тем нужнее его обновление).

Считаю что лучше алгоритм приёма прошивки размещать "вне загрузчика": принимать в энергонезависимую флешь, а в загрузчике только переписывать новую прошивку из flash приёма, в программную flash. Тогда загрузчик будет минимального размера. Да и скорость старта устройства - 5 секунд - это слишком много, для многих из моих устройств даже 1 секунда - было слишком много.

Ещё серьёзные минусы приёма прошивки в загрузчике:

1. Длительный перерыв в штатной работе устройства (на время приёма прошивки). В моих устройствах это было недопустимо.

2. Невозможность передачи прошивки по рабочему протоколу устройства: придётся весь протокол перетаскивать в загрузчик, и он становится собственно рабочим ПО  ;)

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

...

 

Именно поэтому предпочитаю выносить процесс приёма прошивки в рабочее ПО - так гораздо богаче функционал.

Share this post


Link to post
Share on other sites

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

Прием пакетов что по TCP, что по UDP занимает достаточно мало места.

Share this post


Link to post
Share on other sites
6 минут назад, KRTPC сказал:

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

Прием пакетов что по TCP, что по UDP занимает достаточно мало места.

Запускать обмен по ARP, устанавливать TCP-сессию и прочее-прочее - всё равно нужно. А ещё ведь нужно и корректно всё завершить перед перезагрузками, чтобы на компе клиента это нормально выглядело, а не с кучей сообщений о потере коннекта. Размер ПО всё равно получается значительно больше. Чем больше такого ПО - тем вероятность бага больше - тем нужнее обновление загрузчика.

Вам собственно зачем прошивку обновлять? Видимо для того, чтобы баги в ней устранять. А думаете в загрузчике не может быть багов?  ;)

7 минут назад, KRTPC сказал:

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

То что "унутри железный" - это наоборот минус. Когда обнаружится баг в нём железном, то исправить Вы его уже не сможете. Поэтому такое "железное" лучше не использовать.

Share this post


Link to post
Share on other sites
20 minutes ago, jcxz said:

Только если в загрузчике реализован и процесс приёма прошивки. Со всеми TCP-стеками и прочей. Но такой загрузчик становится сам уже приличного размера, и в полный рост встаёт проблема обновления прошивки этого самого загрузчика (чем больше загрузчик -> тем вероятнее наличие багов в нём -> тем нужнее его обновление).

Считаю что лучше алгоритм приёма прошивки размещать "вне загрузчика": принимать в энергонезависимую флешь, а в загрузчике только переписывать новую прошивку из flash приёма, в программную flash. Тогда загрузчик будет минимального размера.

Тут есть и другая крайность, если загрузчик ничего не умеет, не общается с внешним миром, а только перекладывает подготовленную программу из внешней флэши во внутреннюю, то такое устройство гораздо легче "обновить" до состояния кирпича если что-то пойдёт не так. И принимать нормальную прошивку будет уже не кому.

Share this post


Link to post
Share on other sites
46 минут назад, _pv сказал:

то такое устройство гораздо легче "обновить" до состояния кирпича если что-то пойдёт не так. И принимать нормальную прошивку будет уже не кому.

Каким образом? Если исключить случаи преднамеренного вредительства.

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites
58 минут назад, _pv сказал:

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

Если есть разные ревизии устройства, то почему у нас в устройстве нет ID этой ревизии, а в прошивке нет ID ревизии для которой она собрана?

Когда я вёл ПО для линейки устройств (с похожим железом и похожими прошивками (сборка из единых исходников условной компиляцией), то имел в заголовочном файле ID аппаратного исполнения устройства, для которого делается сборка. Соответственно все #if ... #endif выполнялись согласно этого ID. И этот же ID писался в константное место образа прошивки. А загрузчик его проверял и сравнивал со своим ID аппаратного исполнения.

Цитата

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

Зачем?

Это увеличивает сложность загрузчика, соответственно (неминуемо) - уменьшает вероятность его безглючной работы. А баг в загрузчике - он много хуже чем баг в основном ПО.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this