Залізо» для початківців

Derrick Klotz, Freescale, Канада

Коли змушуєш працювати свою першу програму для мікроконтролера (МК), відчуваєш дивовижну наснагу. Це може бути просте миготіння світлодіодами, але ти завжди дізнаєшся про щось нове, починаючи розуміти, як усе працює. Коли я досяг цього вперше, то розцінив як запрошення в гру. Я завжди вважав і продовжую вважати, що робота з МК приносить задоволення. Це особливо справедливо за безпосереднього управління регістрами внутрішньої периферії МК, відомому також, як «програмування голого заліза» (bare metal).

Існує багато різних стилів програмування. Але я посилатимуся тільки на один – мій стиль, який використовую зараз для написання програм. Сьогодні мій стиль програмування не той, що був 10 років тому і 20 років тому, і 30 років тому. Сподіваюся, що він розвиватиметься й надалі. Але я не стверджую, що мої методи найкращі і завжди готовий до обговорення.

Для програмування я використовую інтегроване середовище розробки CodeWarrior IDE, шанувальником якого був ще до придбання Freescale компанії розробника Metrowerks. Вона продовжує мені подобатися і у поточному втіленні Eclipse. Існує кілька інших IDE, які я використовую з нагоди, щоб забезпечити програмну підтримку деяких наших клієнтів. Але коли я пишу свій власний код для демонстрації характеристик МК, користуюся CodeWarrior IDE.

Мені подобається також інструмент Processor Expert Software у складі CodeWarrior IDE, що створює шаблон програми, що допомагає швидше запустити МК. Він також генерує добре документований програмний код для ініціалізації та управління периферією. Я часто порівнюю код, згенерований Processor Expert Software зінформацією з довідників та специфікацій на МК. Це допомагає зрозуміти, як керувати периферією мікросхеми та незмінно прискорює процес навчання. Читання технічної документації стає менш стомлюючим. Програмування на апаратному рівні не означає, що ви повинні писати мовою асемблера. Це означає, що ви повинні розуміти мову асемблера. Вам знадобиться дезасемблювання вихідного коду мовою Сі. Це точно покаже, як працює компілятор. Адже не обов'язково те, що він робить, відповідає тому, чого ви від нього хотіли досягти. Це важливий урок, ніколи не плутайте бажаний та дійсний результат компіляції.

Також вам потрібно розбиратися в технічній документації на МК – розподіл пам'яті, регістрах, периферії тощо. Це може налякати, адже зі скороченням геометричних розмірів кремнієвих схем керівництва стають дедалі більше, а МК дедалі складніше. І це також частина веселої гри з мікроконтролером. Як і документація, програма має бути написана у вигляді невеликих легко аналізованих блоків. Тільки так можна розвинути чітке уявлення про управління апаратною периферією МК. Відкушуйте від слона по одному байти (гм!) за раз.

Базовий шаблон

Почнемо з початку. Існує простий та широко використовуваний шаблон запуску МК після подачі живлення. З кількома незначними відмінностями це основна структура, поверх якої компілятори мови Сі та розробники операційних систем реального часу будують свої програмні комплекси. Цей шаблон використовує і Processor Expert Software. На Малюнку 1 показано загальну структуру програми МК.

програми
Малюнок 1.Загальна структура програми МК.

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

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

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

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

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

Зрештою, коли все ініціалізовано, необхідно включити апаратні переривання. І це обов'язково до того, як програма піде в основний цикл функції main(). На вибір є кілька підходів до побудови основного циклу. Три найбільш популярні методи – це кінцеві автомати, планувальники та операційні системи реального часу. Незалежно від обраної структури основної програми, підпрограми-функції, відповідальні за конкретні завдання, виконуються відповідно до програмних подій, тоді як апаратні події запускають функції обробників переривань. У будь-якому випадку, після завершення підпрограми управління передається в головний цикл.

Головний цикл програми - також єдине місце, де слід скидати сторожовий таймер, якщо він увімкнений. Скидання сторожового таймера у кількох місцях програми розходиться з його основною метою – захистом системи від зависання, т.к. можливий «відхід програми» із основного циклу. Ефективне використання сторожового таймера, очевидно, має на увазі мінімальний час виконання підпрограм та функцій обробки переривань.

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

Я вважаю, що важливо розуміти машину, яка виконує твій код. Безумовно, знайдетьсямісце та програми з високим рівнем абстрагування від апаратної частини МК. Але мені приносить справжнє задоволення працювати з «залізом». Я сподіваюся, знайдуться однодумці, згодні зі мною. Це відправна точка у чудовій подорожі до розуміння умов, за яких можна витягти максимум із «заліза» МК.

Переклад: Антон Юр'єв на замовлення РадіоЛоцман