Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Периферийные устройства

Что такое периферийные устройства?

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

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

Если посмотреть на основную печатную плату старомодного домашнего компьютера 1970-х или 1980-х годов (а на самом деле настольные ПК прошлого не так уж далеки от современных встраиваемых систем), вы ожидаете увидеть:

  • Процессор
  • Чип оперативной памяти
  • Чип ПЗУ
  • Контроллер ввода-вывода

Чип оперативной памяти, чип ПЗУ и контроллер ввода-вывода (периферийное устройство в этой системе) будут соединены с процессором через серию параллельных дорожек, известных как "шина". Эта шина передает адресную информацию, которая выбирает, с каким устройством на шине процессор хочет взаимодействовать, и шину данных, которая передает фактические данные. В наших встраиваемых микроконтроллерах применяются те же принципы — просто все упаковано на одном куске кремния.

Однако, в отличие от видеокарт, которые обычно имеют программный API, такой как Vulkan, Metal или OpenGL, периферийные устройства в микроконтроллерах представлены через аппаратный интерфейс, который отображается на участок памяти.

Линейное и реальное адресное пространство

На микроконтроллере запись данных по произвольному адресу, например 0x4000_0000 или 0x0000_0000, может быть полностью корректной операцией.

На настольной системе доступ к памяти строго контролируется MMU (Memory Management Unit, блок управления памятью). Этот компонент выполняет две основные функции: обеспечение доступа...

На микроконтроллере адресное пространство используется иначе. Например, как упоминалось в предыдущих главах, оперативная память может быть расположена по адресу 0x2000_0000. Если наша оперативная память имеет размер 64 КиБ (т.е. максимальный адрес 0x2000_FFFF), то адреса от 0x2000_0000 до 0x2000_FFFF будут соответствовать нашей оперативной памяти. Когда мы записываем в переменную, находящуюся по адресу 0x2000_1234, внутри происходит логика, которая определяет верхнюю часть адреса (в данном случае 0x2000) и активирует оперативную память, чтобы она могла работать с нижней частью адреса (0x1234 в данном случае). На Cortex-M у нас также есть флэш-ПЗУ, отображенное по адресу 0x0000_0000 до, скажем, адреса 0x0007_FFFF (если у нас флэш-ПЗУ на 512 КиБ). Вместо того чтобы игнорировать все оставшееся пространство между этими двумя областями, разработчики микроконтроллеров отобразили интерфейс для периферийных устройств на определенные адреса памяти. Это выглядит примерно так:

Техническое описание Nordic nRF52832 (pdf)

Отображенные в память периферийные устройства

Взаимодействие с этими периферийными устройствами на первый взгляд кажется простым — запишите правильные данные по правильному адресу. Например, отправка 32-битного слова через последовательный порт может быть настолько же простой, как запись этого 32-битного слова по определенному адресу памяти. Периферийное устройство последовательного порта затем возьмет на себя задачу и автоматически отправит данные.

Конфигурация этих периферийных устройств работает аналогично. Вместо вызова функции для настройки периферийного устройства предоставляется участок памяти, который служит аппаратным API. Запишите 0x8000_0000 в регистр конфигурации частоты SPI, и порт SPI будет отправлять данные со скоростью 8 мегабит в секунду. Запишите 0x0200_0000 по тому же адресу, и порт SPI будет отправлять данные со скоростью 125 килобит в секунду. Эти регистры конфигурации выглядят примерно так:

Техническое описание Nordic nRF52832 (pdf)

Этот интерфейс — способ взаимодействия с аппаратным обеспечением, независимо от используемого языка, будь то ассемблер, C или Rust.