Для чого нам потрібен завантажувач окремо від нашої прикладної програми в мікроконтролерах?


28

Навіщо нам потрібна окрема програма в одній пам'яті флеш-програми мікроконтролера, зокрема STM32F103, яку називають завантажувачем?

Що в ньому особливого, щоб він не був відокремлений від основної прикладної програми?

Взагалі кажучи, чи завантажувач мікропроцесорної системи (скажімо, PowerPC MPC8270) виконує таку ж роботу, як і мікроконтролера (скажімо, ARM STM32F103), або вони роблять принципово різні роботи один від одного, і все ж обидва називають "завантажувачем" ?


2
з тієї ж причини у вас є окремі мікросхеми та деталі, а не одна гігантська монолітна структура
Emobe

Ви цього не робите. Просто введіть свою програму за допомогою перемикачів та індикаторів на консолі комп'ютера.
Гарячі лизання

1
Строго кажучи, вам не потрібна окрема програма завантажувача на мікроконтролері. Але ми найчастіше обираємо його для додаткових функцій корисності, які він пропонує. Якщо ці функції не потрібні, а не потрібні, ви можете видалити завантажувач. Завантаження завантажувача мікроконтролерів зазвичай використовується для спалювання нової програми у спалах. Іноді він може бути використаний для налагодження функцій, деяких точок перерви підтримки та інших приємних функцій. На мікрокомп'ютері, як правило, завантажувач завантажує програми з масової пам'яті і там знадобиться.
ghellquist

Відповіді:


55

Завантаження завантажувача на мікроконтролері відповідає за оновлення основної мікропрограми через канал зв'язку, окрім заголовка програмування. Це корисно для оновлення мікропрограмного забезпечення в полі над BLE, UART, I2C, SD-картами, USB і т. Д. Буде вкрай незручно вимагати від клієнтів придбання програмістів просто для оновлення програмного забезпечення на своїх пристроях.

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

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


3
У нас це та сама причина. Вони перебувають у тому ж спалаху, але завантажувач вирівняний з межею стирання і досить розумний, щоб видалити спалах вище, ніж його власні адреси.
Джошуа

3
У деяких випадках заголовок програмування мікропроцесора може бути фактично недоступним без необхідності розбирати корпус виробу, тому можливість перепрограмувати його через шину комірок без додаткового обладнання є ключовим фактором надійності.
Джон Го-Соко

6
@ alt-rose Завантажувач і програма програми - це окремо складені програми, кожна зі своїм кодом і main()функцією запуску . При включенні живлення запускається завантажувальний код завантажувача і викликає його main(). Програма завантажувача перевіряє дійсну прикладну програму, а потім переходить до коду запуску програми, який викликає прикладну програму main(). Код запуску кожної програми ініціалізує середовище виконання програми для відповідної програми (тобто ініціалізує змінні, стек тощо) і, як правило, жодна програма main()ніколи не повертається до коду запуску.
kkrambo

1
@ alt-rose: Так само, як CPU отримує вихідну адресу завантажувача - це не так. Натомість процесор вказує, що він використовуватиме як початкову адресу завантажувача, а завантажувач вказує, що він використовуватиме як вихідну адресу прикладної програми.
MSalters

4
@kkrambo Хоча це звичайно вірно, немає жодної вимоги (ні загально правдивого факту), що завантажувач повинен бути написаний на мові C або на C, що має а main.
Якк

26
  1. Так що процес завантаження може відновитись після помилок. Припустимо, під час оновлення є помилка зв'язку або відключається живлення. Якщо завантажувач був частиною програми, яку ви оновлювали, користувач не міг би повторити спробу, не використовуючи спеціальне обладнання для перезавантаження на завантажувач.

  2. Деякі мікроконтролери не можуть виконати код з оперативної пам'яті. Якщо завантажувач змішався з іншим програмним забезпеченням, то ви насправді не зможете оновити своє програмне забезпечення, оскільки ви не можете стерти сторінки з флеш-пам’яті, з яких ви зараз виконуєтесь. Робота полягає в тому, щоб спочатку записати новий код на другу половину спалаху, а потім перейти до нього. Потім новий код копіює себе на першу половину спалаху. Звичайно, недоліком є ​​те, що спалювання спалаху зазвичай повільне, і тепер, коли вам доведеться це зробити вдвічі, процес завантаження може зайняти до двох разів довше. Також цей обхід обмежує розмір програми не більше половини від загальної кількості спалаху.

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

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


4
Як приклад пункту 2, деякі мікроконтролери можуть навіть не мати доступної оперативної пам’яті при запуску: наприклад, Raspberry Pi використовує свій графічний процесор для завантаження завантажувача з SD-карти, яка потім дозволяє процесору ARM та пам'яті.
ЕрікФ

11

Вони, як правило, знаходяться там, щоб дозволити оновити свою основну прикладну програму.

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


9

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


2
Це майже все. MCU може отримати код лише за допомогою спеціальної підсистеми програмування (наприклад, AVRICE або JTAG) або вже маючи завантажувач завантаження у спалах. Це рішення програми щодо того, наскільки складний завантажувач, наприклад, деякі системи можуть завантажувати код з WiFi. На дуже низьких рівнях MCU, таких як ATTiny, завантажувач (і серійні штифти) - великі накладні витрати, тому ви завжди використовуєте програміст.
Багатий

7

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


1
На мікроконтролері код, швидше за все, ніколи не знаходиться в оперативній пам'яті, тому його неможливо вилучити. Ви, звичайно, можете відкинути дані завантажувача з оперативної пам'яті.
Бен Войгт

@BenVoigt, це залежить від мікроконтролера. Деякі (в першу чергу з NOR-спалахом) дозволять вам виконувати безпосередньо з спалаху, але інші (як правило, із NAND-спалахом, що стає все більш поширеним явищем) вимагають виконання з оперативної пам'яті. Іноді навіть немає вбудованої спалаху, і вам доведеться скопіювати код із зовнішнього флеш-мікросхеми в локальну SRAM, перш ніж ви зможете виконати що-небудь.
Nate S - Відновіть Моніку

2

Коротка відповідь, тому що програмне забезпечення є приголомшливим.

Ви можете мати все, що завантажувач - це "чисте обладнання". Але набагато простіше, щоб завдання завантажувача були записані як програмне забезпечення, а потім інтерпретувалися апаратними засобами.

Ці завдання можуть передбачати налаштування апаратного забезпечення для "справжнього" програмного забезпечення для запуску (наприклад, на Raspberry Pi (через @ErikF)), мати протокол для заміни "справжньої" програми перед її запуском (перевірити шпильку, якщо цей штифт встановлюється потім перепрошивати реальну програму) або навіть налаштовувати програмне середовище для "реальної" програми.

У меншому масштабі програмного забезпечення, коли ви запускаєте виконувану програму, програма для переміщення завантажувача додатків робить такі речі, як завантаження частин даних у пам'ять, іноді виправляє адреси, налаштовує аргументи до основних чи інших глобальних речей, створює бібліотеки, надані вашою ОС, та потім переходить до початку _mainкоду. Деякі з цих речей можна виконати завантажувачем.

У мікроконтролері деякі завдання, які виконує завантажувач, можуть бути розділені на програму. Компілятор для вашої платформи може автоматично ввести код "установки" у кожен виконуваний файл.

Але наявність його в завантажувальному пристрої означає, що той самий компілятор може працювати на різних апаратних засобах, оскільки завантажувач може "приховати" різницю між платформами.

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


-1

Одна з відповідей, яка не була висвітлена, - це необхідність відокремлення проблем через обмеження мови С.

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

Це робиться для налаштування певних речей, таких як:

  • виділення C стека
  • зчитування покажчика стека в регістр
  • зчитування лічильника програм в реєстр
  • оголошення векторів скидання
  • завантаження другого ступеня (initramfs) в оперативну пам'ять.

Це дуже приблизне наближення до кроків, які я робив, і я описую процес завантаження ARM, він знову відрізняється для x86 та інших архітектур.

Однак принципова причина залишається тією ж: розподіл стеку C потрібно робити з монтажу.


Чому потік? Це і доречно, і точно.
BitShift

-1

Однією з питань, на яку поки не відповіли, є різниця між завантажувачами на мікроконтролерах та мікропроцесорними системами.

Мікроконтролер

Більшість мікроконтролерів мають вбудовану пам'ять ПЗУ, яка містить код програми. Для зміни цього коду зазвичай потрібен пристрій програміста, який підключається до інтерфейсу програмування мікроконтролера (наприклад, ISP на ATMega). Але такі інтерфейси програмування зазвичай часто не дуже зручні у використанні, порівняно з іншими інтерфейсами, оскільки вони можуть бути недоступними у заданому контексті. Наприклад, хоча майже на кожному комп'ютері є порти USB, інтерфейс SPI, необхідний для провайдера, набагато рідше, а інші інтерфейси, такі як PID-інтерфейс, що використовується в ATXMega, підтримуються лише спеціальним програмним забезпеченням.

Так, наприклад, якщо ви хочете оновити програмне забезпечення зі звичайного комп'ютера без зовнішнього обладнання, ви можете використовувати завантажувач, який читає з іншого типу інтерфейсу (наприклад, RS232, USB або RS232 через USB, як на Arduino) для програмування пристрою через загальні інтерфейси.

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

Мікропроцесор

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

У системах x86 / x64 цей завантажувач завантажень є або BIOS, або UEFI (в основному це новіша версія BIOS).

Іноді у вас навіть є кілька завантажувачів, що працюють в ланцюзі. Наприклад, якщо у вас є система з подвійним завантаженням у Windows та Linux, ви можете отримати таке:

  • BIOS / UEFI завантажується і знаходить встановлений GRUB. Потім він завантажує GRUB (= Grand Unified Bootloader)
  • GRUB знаходить якийсь Linux та завантажувач Windows. Користувач вибирає завантажувач Windows.
  • Запускається завантажувач Windows і знаходить встановлені Windows 7 та Windows 10. Користувач вибирає Windows 10.
  • Нарешті, Windows 10 завантажується.

Тож у цьому випадку було три програми, які можна вважати завантажувачем. І GRUB, і завантажувач Windows в основному є, щоб дати користувачеві більш зручний варіант вибору завантаження, ніж BIOS / UEFI. Він також дозволяє запустити декілька ОС з одного жорсткого диска або навіть одного і того ж розділу.

TLDR

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


Хоча корисно відрізняти системи з досить енергонезалежним накопичувачем з випадковим доступом (ROM або flash), щоб утримувати всю програму від тих, яким потрібно запустити код з оперативної пам’яті, є мікроконтролери обох типів та мікропроцесори обох типів.
supercat

Звичайно, різниця між мікроконтролером і мікропроцесором не є жорсткою межею, і деякі мікроконтролери поводяться більше як мікропроцесор і навпаки. Тому я взяв AtMega / Arduino та x86 / x64 як приклади, тому що вони так поводяться.
Даккарон

"мікропроцесори мають ПЗУ, достатньо великий для завантажувача ... У системах x86 / x64 цей завантажувач є або BIOS, або UEFI" Nope. BIOS або UEFI зберігаються у флеш-пам'яті без мікросхеми. Вбудований ПЗУ призначений для функцій ще нижчого рівня, як ініціалізація мікрокоду.
Бен Войгт

@Dakkaron: Я б провів межу між мікропроцесором і мікроконтролером, грунтуючись на тому, чи є чіп розроблений таким, що його можна використовувати для нетривіальних цілей без нічого іншого на шині адреси. 8031 не може бути кваліфікованим, за винятком того, що він є функціонально 8051 (що, безумовно, є мікроконтролером), який не вказаний як що-небудь корисне у внутрішньому ПЗУ, але в іншому випадку був би розроблений таким, щоб використовувати його повністю з внутрішнього зберігання). Щось на кшталт RCA / CDP 1802 не може бути кваліфікованим, хоча його можна використовувати для керування світлодіодним тегом імен ...
supercat

... без зовнішньої оперативної пам’яті та ПЗУ, оскільки конструкції без RAM / ROM без обмежень є обмеженими тривіальними завданнями. Щось на зразок TMS 32050, який, якщо я згадую, має завантажувач і кілька тисяч слів, 16-бітові слова оперативної пам’яті внутрішньо би кваліфікувалися як мікроконтролер; хоча багато додатків вимагають більше додавання більше оперативної пам’яті, якщо підключити через UART до іншої системи, це може служити багатьом цілям без нічого на шині пам’яті.
supercat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.