Опубликован: 24.11.2024 | Доступ: свободный | Студентов: 2 / 0 | Длительность: 05:47:00
Лекция 6:

Прерываемые приложения

Архитектура прерываний FE310

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

Архитектура прерываний FE310 (Изображение из руководства пользователя FE310-G002, воспроизведено с разрешения компании SiFive, Inc.)

Рис. 5.10. Архитектура прерываний FE310 (Изображение из руководства пользователя FE310-G002, воспроизведено с разрешения компании SiFive, Inc.)

Platform-Level Interrupt Controller (ПЛИС) - это глобальный контроллер прерываний в системе RISC-V. Этот контроллер обеспечивает так называемый сигнал Machine External Interrupt ядру E31. Как показано на схеме, этот контроллер отвечает за внешние устройства ввода/вывода.

Core-Local Interruptor (CLINT) генерирует локальные прерывания, связанные с определенными аппаратными потоками (или сокращенно harts). Прерывания, обеспечиваемые этим контроллером, - это прерывание машинного программного обеспечения и прерывание машинного таймера.

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

Уровень 1: Регистры машинного режима процессора RISC-V

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

Машинный режим RISC-V полагается на 8 регистров управления и состояния (CSR) для обработки исключений и прерываний. Это первый уровень регистров прерываний, с которыми мы должны работать.

Здесь приведено описание КСО (нам не обязательно использовать все из них):

  • mstatus (Machine Status) Этот регистр содержит бит Machine Interrupt-Enable (MIE), который является активно-высоким глобальным разрешением прерываний.
  • mip (Machine Interrupt Pending) Этот регистр содержит биты ожидания машинного прерывания для всех трех машинных прерываний: Машинное внешнее прерывание (MEIP), Машинное программное прерывание (MSIP) и Машинное таймерное прерывание (MTIP).
  • mie (Machine Interrupt-Enable) Этот регистр содержит биты разрешения машинного прерывания для всех трех машинных прерываний: Машинное внешнее прерывание (MEIE), Машинное программное прерывание (MSIE) и Машинное прерывание таймера (MTIE).
  • mcause (Machine Exception Cause) Этот регистр содержит код, указывающий, какое прерывание или исключение произошло последним. Опять же, здесь делается различие только между MEI, MSI, MTI и рядом исключений.
  • mtvec (Machine Trap Vector) Этот регистр содержит адрес для перехода при возникновении прерывания или исключения. Ловушка - это термин, используемый для обозначения упреждающих событий, таких как исключения и прерывания. Этот регистр поддерживает 2 режима: Прямой и Векторный. Задача программиста - направить этот регистр на единственный обработчик прерывания (в прямом режиме) или записать серию инструкций перехода на несколько обработчиков (в векторном режиме).
  • mtval (Machine Trap Value) В этом регистре хранится дополнительная информация об исключении: Адрес ошибки, недопустимая команда и ноль для других исключений.
  • mepc (Machine Exception PC) Этот регистр указывает на команду, в которой произошло исключение.
  • mscratch (Machine Scratch) В этом регистре хранится одно слово данных для временного хранения обработчиков ловушек. Эта часть данных может быть буфером, который можно использовать в качестве стека для сохранения состояние. Это не обязательно, поэтому текущий стек может использоваться в начале и конце обработчиков прерываний для сохранения используемых в них регистров.

Как получить доступ к КСО

КСО не отображаются в памяти, поэтому в базовом целочисленном ISA есть 6 специальных инструкций для доступа к этим регистрам. Это более 12% набора команд, поэтому следует, что эти команды должны быть важными.

Единственным способом доступа к этим регистрам являются инструкции CSRRW{I}, CSRRS{I} и CSRRC{I}. Не волнуйтесь, инструментарий компилятора позволяет встраивать инструкции ассемблера в код на языке Си.

Уровень 2: Регистры контроллера прерываний на уровне платформы

Нас интересует использование Контроллера прерывания на уровне платформы (ПЛИС) для прерываний от внешних устройств. Это второй уровень регистров прерываний, с которыми мы должны работать.

Как мы видели на принципиальной схеме ПЛИС имеет 52 источника. Это все контакты, подключенные к модулям ввода/вывода, включая их функции GPIO и аппаратного ввода/вывода. Нумерацию этих источников прерываний мы можем найти в таблице 26 руководства FE310:

Сопоставление источников прерываний ПЛИС в микроконтроллере FE310 (Изображение из руководства пользователя FE310-G002, воспроизведено с разрешения компании SiFive, Inc)

Рис. 5.11. Сопоставление источников прерываний ПЛИС в микроконтроллере FE310 (Изображение из руководства пользователя FE310-G002, воспроизведено с разрешения компании SiFive, Inc)

Для обработки запросов ввода-вывода в модуле ПЛИС мы будем использовать следующие регистры, привязанные к памяти:

  • enable1 and enable2 (Interrupt-Enable) Это регистры разрешения прерываний, которые мы рассматривали ранее. И снова, каждый бит разрешения прерывания расположен по номеру бита, указанному в исходном отображении ПЛИС. Младшая половина этого 64-битного слова - enable1, а старшая половина - enable2, расположены по адресам 0x0C002000 и 0x0C002004, соответственно.
  • pending1 and pending2 (Interrupt Pending) Это регистры ожидания прерывания, которые мы видели ранее, совпадающие по порядку битов с регистрами разрешения прерывания. Эти регистры расположены по адресам 0x0C001000 и 0x0C001004 соответственно.
  • priority1 through priority52 (Priority Registers) Приоритеты не устанавливаются по умолчанию, поэтому хорошей практикой является установление желаемого приоритета для всех прерываний, которые вы собираетесь использовать. Эти регистры предназначены для каждого из 52 источников прерываний ПЛИС. Приоритет 0 означает "не прерывать", а приоритет 7 - высший приоритет. Эти регистры расположены по адресам 0x0C000004 - 0x0C0000D0.
  • claim (Interrupt Claim/Complete Register) Чтение этого регистра возвращает идентификатор самого приоритетного ожидающего прерывания и очищает бит ожидания для этого прерывания в регистре ПЛИС pending1 или pending2. Регистр утверждения находится по адресу 0x0C200004.

Уровень 3: Устройство ввода/вывода

Как и большинство микроконтроллеров, FE310 оснащен множеством устройств ввода/вывода. Кроме принципа работы эти устройства отличаются способом реализации прерываний:

  • Каждое устройство ввода/вывода способно генерировать как минимум одно прерывание на уровне ПЛИС. Однако они могут различать несколько внутренних источников для прерываний ПЛИС. Например, устройства UART (модули асинхронной последовательной передачи данных) могут генерировать только одно прерывание на уровне ПЛИС на устройство, но они имеют биты включения и ожидания прерывания, чтобы реагировать на два события. Когда последовательная передача закончилась и когда были получены некоторые данные. Таким образом, UART может поддерживать два источника прерываний, используя 1 прерывание ПЛИС.
  • Другой пример - модуль GPIO, который поддерживает 32 прерывания ПЛИС (по одному на каждый вывод), но модуль GPIO может реагировать на нарастающие фронты, спадающие фронты, высокие или низкие уровни для каждого из этих выводов.
  • Другие устройства могут генерировать большее количество прерываний ПЛИС для поддержки всех своих функций. Например, модули ШИМ поддерживают по 4 ПЛИС-прерывания: ровно по одному на канал.

Регистры прерываний GPIO в микроконтроллере FE310

Вспомните регистры GPIO из таблицы 52 руководства пользователя:

Смещение и описание регистров конфигурации GPIO (Изображение из руководства пользователя FE310-G002, воспроизведено с разрешения компании SiFive, Inc.)

Рис. 5.12. Смещение и описание регистров конфигурации GPIO (Изображение из руководства пользователя FE310-G002, воспроизведено с разрешения компании SiFive, Inc.)

Обратите внимание, что в адресах с 0x18 по 0x34 находятся регистры разрешения прерывания и ожидания прерывания. Как уже упоминалось, они предназначены для генерации прерываний в случаях падающего фронта, нарастающего фронта, высокого состояния и низкого состояния. Как и другие регистры модуля GPIO, эти регистры разрешают прерывания или указывают на ожидающие прерывания, относящиеся ко всем 32 выводам модуля GPIO, побитово.

Простое приложение, управляемое прерыванием

Прежде чем исправлять наше неисправное приложение "Мигание и яркость", давайте начнем с более простого приложения, чтобы ознакомить вас с процессом.

Вспомните, как работает наш первый демонстрационный вход GPIO: Кнопка 0 выключает светодиод на плате, а кнопка 1 включает его, вот так:

while(1){
if(Red_V_read_pin(0) == 0)    // Считать входной пин 0
Red_V_clear_pin(5);        // Выключить светодиод
else if(Red_V_read_pin(1) == 0) // Считать входной пин 1
Red_V_set_pin(5);            // Включить светодиод 
}

Затем измените это приложение, чтобы заменить обработку кнопки 1 на управление прерыванием.

Для этого приложения можно использовать то же оборудование, которое мы используем для приложения "Мигание и яркость".