Зачем нам нужна отдельная программа в той же флэш-памяти программ микроконтроллера, в частности STM32F103, которая называется загрузчиком?
Что особенного в этом, чтобы отделить его от основной прикладной программы?
Вообще говоря, выполняет ли загрузчик системы на основе микропроцессора (скажем, PowerPC MPC8270) ту же работу, что и микроконтроллер (скажем, ARM STM32F103), или они выполняют принципиально разные задачи друг от друга, и оба они называются «загрузчиками»? ?
microcontroller
stm32
programming
flash
bootloader
альт-роза
источник
источник
Ответы:
Загрузчик на микроконтроллере отвечает за обновление основной прошивки по каналу связи, отличному от заголовка программы. Это полезно для обновления встроенного программного обеспечения в полевых условиях через BLE, UART, I2C, SD-карты, USB и т. Д. Было бы крайне неудобно требовать от покупателей приобретать программаторы только для обновления встроенного программного обеспечения на своих устройствах.
Причина, по которой загрузчик хранится отдельно, заключается в надежности. Загрузчик и код приложения размещены в отдельных разделах флэш-памяти, поэтому код приложения может быть удален и перезаписан загрузчиком без изменения чего-либо, связанного с кодом загрузчика.
Если загрузчик и приложение были сохранены вместе, то код загрузчика должен быть скопирован в ОЗУ, прежде чем он сможет работать, так как любое обновление прошивки удалит код загрузчика во флэш-памяти. Если отключить питание с помощью кода загрузчика в ОЗУ и очистить флэш-память, устройство будет заблокировано.
источник
main()
функцию. При включении питания загрузочный код запускается и вызывает загрузчикmain()
. Программа начального загрузчика проверяет правильность прикладной программы и затем переходит к коду запуска прикладной программы, который вызывает прикладную программуmain()
. Код запуска каждой программы инициализирует среду выполнения C для соответствующей программы (т. Е. Инициализирует переменные, стек и т. Д.) И, как правило, ни одна из программmain()
никогда не возвращается к коду запуска.main
.Так что процесс загрузки может восстановиться после ошибок. Предположим, что произошла ошибка связи или отключение питания во время обновления. Если бы загрузчик был частью приложения, которое вы обновляли, то пользователь не смог бы повторить попытку без использования специального оборудования для перепрошивки на загрузчик.
Некоторые микроконтроллеры не могут выполнять код из оперативной памяти. Если загрузчик был смешан с остальной частью программного обеспечения, вы фактически не смогли бы обновить свое программное обеспечение, потому что вы не можете стереть страницы флэш-памяти, из которых вы сейчас выполняете. Обходной путь - сначала записать новый код во вторую половину флеш-памяти, а затем перейти к нему. Новый код затем копирует себя в первую половину флеш-памяти. Конечно, недостатком является то, что горение флэш-памяти обычно происходит медленно, и теперь, когда вам приходится делать это дважды, процесс загрузки может занять вдвое больше времени. Кроме того, этот обходной путь ограничивает размер вашего приложения, чтобы он не превышал половины вашей общей флэш-памяти.
Хорошо написанные загрузчики пытаются проверить, что на устройстве существует действительный код, прежде чем пытаться его выполнить. Если загрузчик и другой код были смешаны вместе, то как вы могли быть уверены, что ваша подпрограмма проверки будет работать, если весь код не загрузится?
Аутентификация. Безопасные загрузчики перед выполнением пытаются проверить, что загруженное приложение соответствует цифровой подписи. Но если загрузчик и другой код были смешаны вместе, вы не можете контролировать то, что выполняется на устройстве, потому что, как только пользователь загружает новый код, вы не можете контролировать то, что происходит при запуске.
источник
Они обычно там, чтобы позволить вам обновить вашу основную прикладную программу.
Вам нужен код, который знает, как стереть и перепрограммировать внутреннюю флеш-память, которая не может быть основной программой, поскольку, когда она сама стирается, она не сможет перепрограммироваться.
источник
Загрузчик позволяет MCU взаимодействовать с чем-то другим, чтобы принять новую программу, сохранить ее и запустить после сброса. Если у вас не было загрузчика, то нужен программист для доступа к памяти и установки программы на место.
источник
В дополнение к другим правильным ответам о разрешении перепрограммирования основной прошивки из загрузчика, другое преимущество наличия отдельного загрузчика состоит в том, что вы можете логически отделить задачи «сделать один раз при загрузке» от кода, который вам нужен во время выполнения. Затем, после того, как загрузчик завершит свои начальные задачи по настройке, основная микропрограмма может вытеснить загрузчик со всем его ненужным кодом из памяти, экономя значительное пространство ОЗУ. Этого можно достичь и другими способами, но разделение загрузчика и встроенного ПО значительно упрощает работу на многих архитектурах.
источник
Короткий ответ, потому что программное обеспечение является удивительным.
Вы можете иметь все, что загрузчик делает «чисто аппаратным». Но гораздо, намного, намного проще иметь задачи, которые загрузчик действительно записывает как программный, а затем интерпретировать аппаратно.
Эти задачи могут включать настройку аппаратного обеспечения для запуска «настоящего» программного обеспечения (например, на Raspberry Pi (через @ErikF)), наличия протокола для замены «настоящей» программы перед ее запуском (проверьте вывод, если этот пин-код устанавливается, затем перепрошивается реальная программа) или даже настраивается программная среда для «настоящей» программы.
В менее микромасштабном программном обеспечении, когда вы запускаете исполняемый файл, который перемещает загрузчик приложения, выполняет такие вещи, как загрузка частей ваших данных в память, иногда фиксирует адреса, устанавливает аргументы для основных или других глобальных вещей, раскручивает библиотеки, предоставляемые вашей ОС, и затем переходит к началу
_main
кода. Некоторые из этих вещей могут быть выполнены загрузчиком.В микроконтроллере некоторые задачи, которые выполняет загрузчик, могут быть разделены на программы. Компилятор для вашей платформы может автоматически вставлять «установочный» код в каждый исполняемый файл.
Но наличие его в загрузчике означает, что один и тот же компилятор может работать на другом оборудовании, поскольку загрузчик может «скрыть» разницу между платформами.
Завершите это тем, что флэш-память основной программы не рискует загрузчиком (и возможностью перепрошивки основной программы), и наличие нетривиального загрузчика - довольно хорошая вещь.
источник
Один из ответов, который не был рассмотрен, - это необходимость разделения проблем из-за ограничений языка Си.
Обычно загрузчики написаны на смеси ассемблера и C, с самого раннего этапа загрузки в ассемблере.
Это сделано для настройки некоторых вещей, таких как:
Это очень грубая аппроксимация предпринятых шагов, и я описываю процесс загрузки ARM, он снова отличается для x86 и других архитектур.
Тем не менее, основная причина остается той же: выделение стека C должно выполняться из сборки.
источник
Одна часть вопроса, на которую до сих пор не было ответа, - это различие между загрузчиками на микроконтроллерах и микропроцессорных системах.
микроконтроллер
Большинство микроконтроллеров имеют встроенную память ПЗУ, в которой содержится их программный код. Для изменения этого кода обычно требуется устройство программиста, которое подключается к интерфейсу программирования микроконтроллера (например, ISP на ATMega). Но эти программные интерфейсы обычно не очень удобны в использовании по сравнению с другими интерфейсами, поскольку они могут быть недоступны в данном контексте. Так, например, хотя почти каждый компьютер имеет порты USB, SPI-интерфейс, необходимый для ISP, гораздо реже, а другие интерфейсы, такие как PID-интерфейс, используемый в ATXMega, поддерживаются только специальным программным обеспечением.
Так, например, если вы хотите обновить программное обеспечение с обычного компьютера без какого-либо внешнего оборудования, вы можете использовать загрузчик, который считывает данные с интерфейса другого типа (например, RS232, USB или RS232 через USB, как на Arduino), чтобы запрограммировать устройство через общие интерфейсы.
Тем не менее, если вам не нужны эти функции, загрузчик является полностью необязательным. Микроконтроллер по-прежнему может запускать свой код полностью без загрузчика.
Микропроцессор
На микропроцессоре дела обстоят немного иначе. В то время как большинство микропроцессоров имеют ПЗУ, достаточно большое для загрузчика, эти ПЗУ не достаточно велики, чтобы вместить полную ОС. Таким образом, цель загрузчика - инициализировать оборудование, найти загрузочную ОС, загрузить и запустить ее. Таким образом, загрузчик имеет решающее значение для каждой загрузки.
В системах x86 / x64 этот загрузчик является либо BIOS, либо UEFI (в основном, более новой версией BIOS).
Иногда вы можете даже запустить несколько загрузчиков в цепочке. Например, если у вас есть система двойной загрузки с Windows и Linux, вы можете получить следующее:
Таким образом, в этом случае было три части программного обеспечения, которые можно считать загрузчиком. Как GRUB, так и Windows Bootloader в основном предназначены для того, чтобы предоставить пользователю более удобный вариант выбора загрузки, чем тот, который им предоставляет BIOS / UEFI. Он также позволяет запускать несколько ОС с одного жесткого диска или даже с одного раздела.
TLDR
Таким образом, хотя в обеих системах загрузчик выполняет похожие действия (помогая пользователю выбрать, какой код загружать), они оба сильно отличаются друг от друга тем, как они выполняют это и что именно они делают.
источник