Что такое загрузчик и как мне его разработать?


53

Я встречал много проектов, в которых микроконтроллер AVR использует загрузчик (например, Arduino), но я не очень хорошо понимаю эту концепцию.

Как сделать загрузчик (для любого микроконтроллера)?

После написания моего загрузчика, как он запрограммирован на микроконтроллер (как любая программа .hex, записанная на флэш-памяти AVR, или каким-либо другим способом)?


10
Вы пометили его тегом загрузчика , прочитали ли вы это? Если да, то вы читали Arduino Bootloader , Arduino Bootloader продолженная , Arduino Bootloader , хорошие инструменты и методы для понимания структуры загрузчиком и Arduino Bootloader Подробности вопросы? Это все части вашего первоначального вопроса. Я урезал это до нового материала.
Кевин Вермеер

Статья о методе BootLoader Design: beningo.com/wp-content/uploads/images/Papers/…
yahya tawil

2
@KevinVermeer Я думаю, что его вопрос более прост.
richieqianle

Ответы:


103

Загрузчик - это программа, которая запускается в микроконтроллере для программирования. Он получает новую информацию о программе извне через некоторое средство связи и записывает эту информацию в память программ процессора.

Это отличается от обычного способа загрузки программы в микроконтроллер, который осуществляется с помощью специального оборудования, встроенного в микроконтроллер для этой цели. На PIC это SPI-подобный интерфейс. Если я правильно помню, AVR используют Jtag, или, по крайней мере, некоторые из них. В любом случае, для этого требуется какое-то внешнее оборудование, которое шевелит контакты программирования прямо для записи информации в память программы. HEX-файл, описывающий содержимое памяти программы, создается на компьютере общего назначения, поэтому это оборудование подключается к компьютеру с одной стороны и специальным программным выводам микропроцессора с другой. Моя компания, помимо прочего, делает программистов PIC второстепенными, поэтому я хорошо знаком с этим процессом на PIC.

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

Если вы уверены в программе, которую хотите загрузить в свой продукт, и ваши объемы достаточно высоки, у вас могут быть микросхемы программы производителя или дистрибьютора. Чип припаивается к плате, как и любой другой чип, и устройство готово к работе. Это может быть подходящим для чего-то вроде игрушки, например. Как только прошивка завершена, она в значительной степени готова и будет выпускаться в больших объемах.

Если ваши объемы ниже или, что более важно, вы ожидаете продолжения разработки прошивки и исправления ошибок, вы не хотите покупать предварительно запрограммированные чипы. В этом случае на плату устанавливаются чистые микросхемы, и микропрограмма должна быть загружена на микросхему как часть производственного процесса. В этом случае аппаратные линии программирования должны быть как-то доступны. Это может быть через явный разъем или контактные площадки pogo, если вы хотите создать тестовый прибор. Часто такие продукты должны быть протестированы и, в любом случае, откалиброваны, поэтому дополнительные затраты на запись программы в процессор обычно минимальны. Иногда, когда используются небольшие процессоры, в процессор сначала загружается специальное тестовое программное обеспечение. Это используется для облегчения тестирования и калибровки устройства, тогда настоящая прошивка загружается после того, как аппаратное обеспечение, как известно, хорошо. В этом случае существуют некоторые соображения по проектированию схемы, позволяющие обеспечить достаточный доступ к строкам программирования для процесса программирования, но также не слишком усложнять схему. Для получения более подробной информации об этом, см. Мойревизия внутрисхемного программирования .

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

Однако в большинстве случаев вы просто хотите, чтобы клиент запустил программу на ПК и волшебным образом обновил прошивку. Именно здесь начинается загрузчик, особенно если ваш продукт уже имеет коммуникационный порт, который может легко взаимодействовать с ПК, таким как USB, RS-232 или Ethernet. Клиент запускает программу для ПК, которая говорит с загрузчиком уже в микро. Это отправляет новый двоичный файл в загрузчик, который записывает его в память программы и затем запускает новый код.

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

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

Обычно простой загрузчик, как описано выше, не является приемлемым, так как не существует отказоустойчивого. Если новый образ приложения не получен в целости, вы хотите, чтобы устройство продолжало запускать старый образ, а не быть мертвым, пока не будет выполнена успешная загрузка. По этой причине в прошивке обычно есть два специальных модуля: загрузчик и загрузчик. Загрузчик является частью основного приложения. Как часть регулярного общения с хостом, может быть загружено новое изображение приложения. Это требует отдельной памяти от основного образа приложения, такого как внешняя EEPROM, или использования более крупного процессора, чтобы половина пространства памяти программы могла быть выделена для хранения нового образа приложения. Загрузчик просто записывает полученный новый образ приложения где-то, но не запускает его. Когда процессор перезагружен, что может произойти по команде с хоста после загрузки, загрузчик работает. Теперь это полностью автономная программа, которая не нуждается во внешних коммуникационных возможностях. Он сравнивает текущие и загруженные версии приложения, проверяет их контрольные суммы и копирует новое изображение в область приложения, если версии различаются, а новая контрольная сумма изображения проверяется. Если новый образ поврежден, он просто запускает старое приложение, как и раньше.

Я сделал много загрузчиков, и нет двух одинаковых. Не существует загрузчика общего назначения, несмотря на то, что некоторые микроконтроллерные компании хотят, чтобы вы верили. Каждое устройство имеет свои требования и особые обстоятельства при работе с хостом. Вот только некоторые из конфигураций загрузчика и иногда загрузчика, которые я использовал:

  1. Базовый загрузчик. Это устройство имеет последовательную линию и будет подключено к хосту и включаться по мере необходимости. Загрузчик запустился после перезагрузки и отправил несколько ответов на запрос загрузки на хост. Если программа загрузки была запущена, она ответит и отправит новое изображение приложения. Если он не отвечает в течение 500 мс, загрузчик отказывается и запускает существующее приложение. Поэтому для обновления прошивки сначала необходимо запустить приложение обновления на хосте, а затем подключить и включить устройство.

  2. Загрузчик программной памяти. Здесь мы использовали следующий размер PIC, который имел в два раза больше памяти для программ. Память программы была примерно разделена на 49% основного приложения, 49% нового образа приложения и 2% загрузчика. Загрузчик запускается из перезагрузки и копирует новый образ приложения в текущий образ приложения при правильных условиях.

  3. Внешнее изображение EEPROM. Как и # 2, за исключением того, что внешняя ЭСППЗУ использовалась для хранения нового образа приложения. В этом случае процессор с большим объемом памяти также был бы физически больше и находился бы в другом подсемействе, в котором не было необходимого количества периферийных устройств.

  4. TCP загрузчик. Это был самый сложный из них. Большой PIC 18F был использован. Последняя 1/4 памяти или около того содержала загрузчик, который имел свою собственную полную копию сетевого стека TCP. Загрузчик запустился после сброса и попытался подключиться к специальному серверу загрузки через известный порт с предварительно настроенным IP-адресом. Это было для больших установок, где всегда был выделенный сервер для всей системы. Каждое маленькое устройство будет регистрироваться на сервере загрузки после сброса и получит новую копию приложения в зависимости от ситуации. Загрузчик перезапишет существующее приложение новой копией, но запустит его, только если проверена контрольная сумма. Если нет, он вернется на сервер загрузки и попытается снова.

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

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


1
Все AVR, за исключением семейства Xmega (с новым 2-проводным интерфейсом), используют интерфейс SPI, сохраняя сброс. Более крупные также имеют JTAG, некоторые имеют параллельное программирование, а более мелкие могут потребовать высокого напряжения, если сброс был перенастроен как ввод / вывод. Некоторые микроконтроллеры, такие как семейства Parallax Propeller и Motorola / Freescale 68HC08, не имеют минимального аппаратного программирования, но имеют загрузчики в ПЗУ.
Янн Вернье

Он сравнивает текущие и загруженные версии приложения, проверяет их контрольные суммы и копирует новое изображение в область приложения, если версии различаются, а новая контрольная сумма изображения проверяется. Да, но что, если во время этого действия отключится питание, в «области приложения» будет поврежденное изображение. Я полагаю, что может быть лучше иметь приложение bootloader-failsafe-app, которое записывает новое приложение во флэш-память mcu, и, если контрольная сумма верна, оно также пишет куда-то "нормально, чтобы загрузить новое приложение". Таким образом, при запуске он проверяет, нормально ли загружать новое приложение, если это не так, он продолжает выполнять себя (отказоустойчивое приложение)
Ervadac

@Erv: Если во время копирования новой версии в текущую версию происходит сбой питания, то контрольная сумма текущей версии не будет выполнена, когда питание вернется и загрузчик снова запустится. Я обычно помещаю слово контрольной суммы в самый конец изображения, чтобы любая частичная запись имела очень высокую вероятность сбоя контрольной суммы.
Олин Латроп

Здравствуй. Я могу порекомендовать вам тип загрузчика 5 - вместо стека TCP вы можете реализовать UDP. Затем используйте TFTP, чтобы загрузить обновление или собственный протокол.
i486

22

Какова концепция загрузчика?

Представьте себе этот сценарий: на вашем микроконтроллере достаточно места для хранения - достаточно для хранения более 2-3 программ или приложений, которые не зависят друг от друга. Предположим, что при загрузке вашего устройства вы можете захотеть выбрать, какое из них запустить. Так что бы вам нужно, чтобы поддержать это? Вам понадобится стартовая программа, которая позволит вам выбирать между остальными во время загрузки.

Как это устроено?

Загрузчик - это та программа - она ​​запускается первой и может загружать другие приложения в определенные места в памяти (как постоянные, например, FLASH, так и энергозависимые, как ОЗУ), а затем переходит к той требуемой программе, где она затем начинает выполнение. ,

Как сделать загрузчик avr (или для любого микроконтроллера)?

Я никогда не делал загрузчик, но вот как я думаю, я бы поступил так: начните писать программу прошивки, как вы это обычно делаете, - но убедитесь, что она расположена в такой области, что она всегда запускается первой, когда устройство загружается. Вдобавок ко мне, некоторые функции, которые я хотел бы использовать в этой маленькой программе: возможность загружать новую программу в доступное место в памяти, удалять ранее загруженную программу, выбирать, какую программу запускать (если их больше, чем 1) и иметь какую-то структуру хранения данных (таблицу переходов, которую можно наращивать?), чтобы иметь возможность запомнить, где находятся другие программы, и перейти к ним. Взаимодействие может осуществляться через UART, где оно может предоставить вам очень простое меню терминала и возможность загружать прошивку по тому же каналу.

Как это запрограммировано на микроконтроллер (как любая программа .hex, записанная на флэш-памяти avr, или каким-либо другим способом)?

Если это полностью чистый чип без существующего загрузчика, который может обновляться сам, вам необходимо записать на FLASH, как вы описали, используя любой метод, необходимый для достижения этой цели (ICSP в случае AVR).

Это ни в коем случае не является исчерпывающим понятием «загрузчиков». В зависимости от того, что вы хотите от одной или от системы, для которой они предназначены, вы можете создать такую, чтобы загружать содержимое в указанное место в ОЗУ вместо FLASH и начинать выполнение в любом произвольном месте в памяти. Или, может быть, вам нужен тот, который способен выбирать, какую операционную систему загружать при загрузке вашего ПК (см., Например, grub ). Загрузчики для 8-битных микроконтроллеров, как правило, очень просты.

Примечание об Arduino: этот загрузчик управляет только одной программой AFAIK, он также берет на себя последовательный порт для управления загрузкой прошивки и других вещей .


К вашему сведению, ответ был написан, чтобы адресовать оригинальные пункты маркировки, которые теперь были отредактированы.
Джон Л

3

Концепция «загрузочного» погрузчика аналогична концепции «заправки» насоса. Другими словами, вам нужно «что-то», которое загружает программу по заданному адресу, а затем начинает выполнение программы по этому заданному адресу. Это что-то, это загрузчик. В простейшем случае загрузчик «появляется» по указанному начальному адресу ЦП (скорее всего, ноль), загружает программу в требуемый сегмент памяти, передает ему управление и «исчезает». Появление и исчезновение контролируется «внешним» оборудованием. Одна из возможных реализаций - использование ПЗУ, которое активируется через «аппаратный» сброс и деактивируется с «программным» сбросом. Загрузчик в ПЗУ может быть настолько простым или сложным, насколько это необходимо, и должен быть записан в двоичной форме, которую понимает конкретный процессор. Если адресное пространство, используемое ПЗУ, не требуется, деактивация ПЗУ не потребуется. Очевидно, что вместо ПЗУ можно использовать EEPROM, ePROM, flash PROM и т. Д.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.