Що таке завантажувач і як я його розробив?


53

Я зустрічався з багатьма проектами, в яких мікроконтролер AVR використовує завантажувач (наприклад, Arduino), але цю концепцію я не дуже добре розумію.

Як я можу зробити завантажувач (для будь-якого мікроконтролера)?

Як написав завантажувач, як він запрограмований на мікроконтролер (як і будь-яка програма .hex, записана на флеш-пам’яті AVR, або якийсь інший метод)?


10
Ви позначили його тегом завантажувача , ви це прочитали? Якщо так, то ви читали Arduino Bootloader , Arduino Bootloader продовжена , Arduino Bootloader , хороші інструменти і методи для розуміння структури загрузчиком і Arduino Bootloader Подробиці питання? Усі ці адреси стосуються вашого початкового запитання. Я підрізав це до нового матеріалу.
Кевін Вермер

Доповідь про метод дизайну BootLoader: beningo.com/wp-content/uploads/images/Papers/…
yahya tawil

2
@KevinVermeer Я думаю, що його питання є більш простим.
richieqianle

Відповіді:


103

Завантажувач - це програма, яка працює в мікроконтролері, який потрібно запрограмувати. Він отримує нову програмну інформацію зовні через деякі засоби зв'язку та записує цю інформацію в програмну пам'ять процесора.

Це на відміну від звичайного способу потрапляння програми в мікроконтролер, який здійснюється за допомогою спеціального обладнання, вбудованого в мікросхему для цієї мети. На PIC це інтерфейс, подібний до SPI. Якщо я пам'ятаю правильно, AVR використовують Jtag, або принаймні деякі з них. Так чи інакше, для цього потрібне деяке зовнішнє обладнання, яке змішує шпильки програмування правильно, щоб записати інформацію в пам'ять програми. Файл HEX, що описує вміст програмної пам'яті, походить з комп'ютера загального призначення, тому це обладнання з'єднується з комп'ютером з одного боку та спеціальними штифтами програмування мікро - з іншого. Моя компанія робить програмістів PIC, крім усього іншого, стороною, тому я досить добре знайомий з цим процесом на PIC.

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

Якщо ви впевнені в програмі, яку ви хочете завантажити у свій продукт, і ваші обсяги досить великі, ви можете мати для вас виробника чи дистриб'юторські чіпи програми. Мікросхема припаюється до плати, як і будь-яка інша мікросхема, і пристрій готовий до роботи. Це може бути доречно для чогось, наприклад, іграшки. Після того як прошивка буде зроблена, вона майже зроблена, і вона буде випускатися великими обсягами.

Якщо ваш обсяг менший, або що ще важливіше, ви очікуєте постійної розробки мікропрограмного забезпечення та виправлень помилок, ви не хочете купувати заздалегідь запрограмовані чіпи. У цьому випадку пусті мікросхеми встановлюються на платі, і прошивка повинна завантажуватися на мікросхему в рамках виробничого процесу. У цьому випадку рядки програмного забезпечення апаратних засобів повинні бути доступні якось доступними. Це може бути через явний роз'єм або пого контактні колодки, якщо ви готові створити виробничий тестовий кріплення. Часто такі продукти доводиться перевіряти і, можливо, все-таки калібрувати, тому додаткові витрати на написання програми на процесор зазвичай мінімальні. Іноді, коли використовуються невеликі процесори, спочатку в процесор завантажується спеціальна виробнича тестова прошивка. Це використовується для полегшення тестування та калібрування пристрою, тоді реальна прошивка завантажується після того, як апаратне забезпечення, як відомо, добре. У цьому випадку є деякі міркування конструкції схеми, щоб дозволити доступ до ліній програмування достатньо для того, щоб процес програмування працював, але також не створював надто незручності для схеми. Детальніше про це дивіться у моїйсписання програмування в ланцюзі .

Поки що добре, і завантажувач не потрібен. Однак розгляньте продукт із відносно складною прошивкою, який потрібно оновити на полі або навіть дозволити кінцевому клієнту оновити. Ви не можете очікувати, що кінцевий клієнт матиме гаджет-програміст або знати, як правильно ним користуватися, навіть якщо ви його надали. Насправді це робить один із моїх клієнтів. Якщо ви купуєте їх спеціальний варіант налаштування поля, ви отримуєте одного з моїх програмістів із продуктом.

Однак у більшості випадків ви просто хочете, щоб клієнт запустив програму на ПК та оновив програмне забезпечення магічним чином. Тут надходить завантажувач, особливо якщо ваш продукт вже має порт зв'язку, який може легко взаємодіяти з ПК, наприклад, USB, RS-232 або Ethernet. Клієнт запускає програму ПК, яка спілкується з завантажувачем вже в мікрофоні. Це посилає новий бінарний файл до завантажувача, який записує його в пам'ять програми, а потім призводить до запуску нового коду.

Звучить просто, але це не так, принаймні ні, якщо ви хочете, щоб цей процес був надійним. Що робити, якщо трапляється помилка зв’язку, і нова прошивка пошкоджується до моменту надходження до завантажувача? Що робити, якщо живлення переривається під час завантаження? Що робити, якщо завантажувач має помилку і лаєть на собі?

Спрощений сценарій полягає в тому, що завантажувач завжди працює від скидання. Він намагається спілкуватися з господарем. Якщо хост відповідає, він або повідомляє завантажувачу, що він нічого нового, або надсилає йому новий код. По мірі надходження нового коду старий код перезаписується. Ви завжди додаєте контрольну суму із завантаженим кодом, щоб завантажувач міг визначити, чи є новий додаток неушкодженим. Якщо ні, то він залишається у завантажувачі, постійно вимагаючи завантаження, поки щось з дійсною контрольною сумою не завантажується в пам'ять. Це може бути прийнятним для пристрою, який завжди підключений і, можливо, там, де виконується фонове завдання на хості, який відповідає на запити завантажувача. Ця схема не є корисною для одиниць, які значною мірою є автономними та лише зрідка підключаються до хост-комп'ютера.

Зазвичай простий завантажувач, як описано вище, є неприйнятним, оскільки не існує безпечного відключення. Якщо зображення нового додатка не отримано неушкодженим, ви хочете, щоб пристрій продовжував працювати зі старим зображенням, не бути мертвим, поки не буде виконано успішне завантаження. З цієї причини зазвичай у прошивці є два спеціальні модулі, програма завантажувача та завантажувач. Завантажувач є частиною основного додатка. У рамках регулярного спілкування з хостом можна завантажувати нове зображення програми. Для цього потрібна окрема пам'ять від основного зображення програми, як-от зовнішній EEPROM або використання більшого процесора, щоб половина простору пам’яті програми могло бути виділено для зберігання нового зображення додатка. Завантажувач просто записує отримане нове зображення програми десь, але не запускає його. Коли процесор скидається, що може статися за командою від хоста після завантаження, завантажувач працює. Зараз це повністю автономна програма, яка не потребує можливості зовнішнього спілкування. Він порівнює поточну та завантажену версії додатків, перевіряє їх контрольні суми та копіює нове зображення на область програми, якщо версії відрізняються та перевіряє нову контрольну суму зображень. Якщо нове зображення пошкоджене, воно просто запускає старий додаток, як і раніше.

Я зробив багато завантажувачів, і жодне два не те саме. Немає завантажувача загального призначення, незважаючи на те, що деякі компанії з мікроконтролерів хочуть, щоб ви повірили. У кожного пристрою є свої вимоги та особливі обставини в роботі з господарем. Ось лише декілька конфігурацій завантажувача та інколи завантажувачів, які я використовував:

  1. Базовий завантажувач. Цей пристрій мав послідовну лінію, і він був би підключений до хоста та увімкнувся у міру необхідності. Завантажувач завантажився з режиму скидання і надіслав хосту кілька відповідей на запит на завантаження. Якщо програма для завантаження працювала, вона відповість та надішле нове зображення програми. Якщо він не відповів протягом 500 мс, завантажувач відмовиться від запуску наявного додатка. Щоб оновити прошивку, потрібно було спочатку запустити програму оновлення на хості, а потім підключити та включити пристрій.

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

  3. Зовнішнє зображення EEPROM Як і №2, за винятком того, що зовнішній EEPROM був використаний для зберігання нового зображення програми. У цьому випадку процесор з більшою кількістю пам’яті був би також фізично більшим і в іншій під-сім’ї, яка б не мала необхідну нам суміш периферійних пристроїв.

  4. TCP завантажувач. Це було найскладнішим з усіх. Був використаний великий PIC 18F. Останні 1/4 пам'яті або близько цього містили завантажувач, який мав власну повну копію мережевого стеку TCP. Завантажувач працює від скидання та намагався підключитися до спеціального сервера завантаження у відомий порт за попередньо налаштованою IP-адресою. Це було для великих установок, де завжди була виділена серверна машина для всієї системи. Кожен невеликий пристрій після закінчення скидання перевіриться на сервері завантаження та отримає нову копію програми. Завантажувач замінить існуючу програму новою копією, але запустить її лише в тому випадку, якщо перевірена контрольна сума. Якщо ні, то він повернеться на сервер завантаження і спробує ще раз.

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

Сподіваємось, ви можете побачити, що існує низка інших можливостей, кожна з яких має свої компроміси ризику, швидкості, вартості, простоти використання, простоїв тощо.


1
Усі AVR, за винятком сімейства Xmega (який має новий двожильний інтерфейс), використовують інтерфейс SPI, зберігаючи їх у режимі скидання. Більші з них також мають JTAG, деякі мають паралельне програмування, а більш дрібні можуть вимагати високої напруги, якщо скидання було налаштовано як I / O. Деякі MCU, такі як сімейство пропелерів Parallax та Motorola / Freescale 68HC08, не мають мінімального програмного забезпечення, а завантажувачі в ПЗУ.
Yann Vernier

Він порівнює поточну та завантажену версії додатків, перевіряє їх контрольні суми та копіює нове зображення на область програми, якщо версії відрізняються та перевіряє нову контрольну суму зображень. Так, але що, якщо посеред цієї дії живлення перерветься, у "області додатків" з’явиться зіпсований образ. Я припускаю, що може бути краще мати завантажувач-failsafe-додаток, який записує нову програму у флеш-пам'ять mcu, і якщо контрольна сума дійсна, вона також десь пише "нормально для завантаження нового додатка". Тож на початку він перевіряє, чи нормально завантажувати нову програму, якщо це не так, що вона продовжує виконувати себе (програму failsafe)
Ervadac

@Erv: Якщо живлення припиняється в середині копіювання нової версії на поточну, тоді контрольна сума поточної версії вийде з ладу, коли живлення повернеться і завантажувач знову запуститься. Зазвичай я кладу слово контрольної суми в самому кінці зображення, так що будь-яке часткове записування має дуже хороший шанс виходу з ладу контрольної суми.
Олін Латроп

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

22

Що таке концепція завантажувача?

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

Як це працює?

Запуск завантажувача - це та програма - це перше, що потрібно запустити, і може завантажувати інші програми на певні місця в пам'яті (стійкі, як FLASH, або летючі, як оперативна пам'ять), а потім переходить до потрібної програми, де потім візьме на себе виконання звідти .

Як зробити avr завантажувач (або для будь-якого мікроконтролера)?

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

Як це запрограмовано на мікроконтролер (як і будь-яка.

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

Це аж ніяк не є вичерпним, що таке "завантажувачі". Залежно від того, що ви хочете отримати з однієї системи або системи, для якої вони призначені, ви можете спроектувати її для завантаження матеріалів у вказане місце в оперативній пам'яті замість FLASH та розпочати виконання в будь-якому довільному місці пам'яті. Або, можливо, ви хочете обрати операційну систему під час завантаження ПК (див., Наприклад, grub ). Завантажувачі для 8-бітних мікроконтролерів, як правило, дуже прості.

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


FYI, була написана відповідь на адресу оригінальних пунктів кулі, які тепер були відредаговані.
Джон L

3

Поняття «завантажувального» навантажувача схоже на поняття «заправка» насоса. Іншими словами, вам потрібно "щось", яке завантажує програму на задану адресу, а потім почати виконувати програму за вказаною адресою. Що-небудь, це завантажувач. У найпростішому випадку завантажувач "з'являється" за вказаною початковою адресою процесора (нуль, швидше за все), завантажує програму в потрібний сегмент пам'яті, передає їй управління і "зникає". Зовнішній вигляд і зникнення контролюється "зовнішнім" обладнанням. Однією з можливих реалізацій було б використання ПЗУ, який активується за допомогою «апаратного» скидання та деактивовано скиданням «програмного забезпечення». Навантажувач в ПЗУ може бути таким простим або складним, як потрібно, і має бути записано у двійковій формі, яку розуміє конкретний процесор. Якщо адресний простір, який використовується ROM, не потрібен, дезактивація ROM не буде потрібна. Очевидно, що замість ПЗУ можна використовувати EEPROM, ePROM, flash PROM тощо.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.