Изменение приоритета текущего прерывания в NVIC - PullRequest
0 голосов
/ 27 декабря 2018

У меня есть загадка.Часть, которую я использую (NXP KL27, Cortex-M0 +), имеет ошибки в периферийном устройстве I2C, так что во время приема отсутствует управление потоком.В результате это должно быть прерывание с высоким приоритетом.Я также использую UART, который по своей асинхронной природе не имеет управления потоком при получении.В результате это должно быть прерывание с высоким приоритетом.

Циклический приоритет

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

Прерывание UART должно иметь более высокий приоритет, чем прерывание I2C, потому что для закрытия транзакции I2C необходимоДрайвер (из KSDK NXP) должен установить флаг и дождаться бита состояния.Во время этого ожидания входящие символы в UART могут переполнять регистр сдвига без FIFO.

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

Возможное решение

Решение, которое я нашелс изменением приоритетов прерываний на лету.Когда драйвер I2C закрывает транзакцию, он не получает, что означает, что ошибки, из-за которых байты поступают неуправляемо, не являются проблемой.Я хотел бы понизить приоритет прерывания I2C в NVIC в течение этого времени, чтобы UART мог иметь приоритет над ним, тем самым делая UART счастливым (и не пропуская никаких символов).

Вопрос

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

Другие возможные решения

Существует ряд других возможных решений и причин, по которым они нежелательны.Рефакторинг драйвера I2C для обработки цикла в контексте процесса, а не в контексте прерывания, будет значительным усилием, копаясь в коде поставщика, и влияет на код приложения, который вызывает его.Использование DMA для любой из этих периферийных устройств приводит к потере нетривиального количества доступных каналов DMA и накладным расходам на настройку DMA для каждой транзакции (а также влияет на код приложения, который вызывает драйверы).

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

Тест

У меня есть идея для эксперимента поПроверь, как работает NVIC в этом отношении, но я подумал, что сначала проверю здесь.Если я доберусь до эксперимента, я опубликую ответ с результатами.

Ответы [ 2 ]

0 голосов
/ 31 декабря 2018

Эксперимент

Сегодня я написал небольшой эксперимент, чтобы проверить это на моем конкретном варианте Cortex M0 +.Я оставляю это как неприемлемый ответ, и я считаю, что ответ @Sean Houlihane является наиболее правильным (то есть непредсказуемым).Я все еще хотел проверить поведение и сообщить об этом при определенных обстоятельствах, пока я его использую.

Эксперимент проводился на плате FRDM-KL43Z.Он имеет красный светодиод, зеленый светодиод и две кнопки.Приложение выполнило некоторую настройку GPIO и прерываний, а затем остановилось в бесконечном цикле.

Кнопка 1: обработчик прерываний кнопки 1 был инициализирован с приоритетом среднего уровня (0x80).На каждом падающем фронте кнопки 1 ожидание прерывания.Это прерывание будет переключать состояние зеленого светодиода.

Кнопка 2: Обработчик прерываний для кнопки 2 был инициализирован с приоритетом среднего уровня (0x80), но будет изменен как часть выполнения.Обработчик прерываний кнопки 2 запускает цикл, который длится приблизительно 8 секунд (две фазы по четыре), повторяясь бесконечно.Он включит красный светодиод и уменьшит свой приоритет ниже, чем у кнопки 1. Через четыре секунды он выключит красный светодиод и увеличит свой приоритет над приоритетом кнопки 1. Через четыре секунды он повторится.

Ожидаемые результаты

Если гипотеза подтвердится, когда красный светодиод включен, нажатие кнопки 1 переключит зеленый светодиод, а когда красный светодиод выключится,нажатие кнопки 1 не будет действовать, пока красный светодиод не погаснет.Прерывание кнопки 1 не будет выполняться до тех пор, пока непрерывное прерывание кнопки 2 не будет иметь более низкий приоритет.

Результаты

Это скучный раздел.Все, что я ожидал в предыдущем разделе, произошло.

Заключение

Для экспериментальной установки (NXP KL43Z Cortex M0 +) вступает в силу изменение приоритета прерывания текущего выполняющегося прерывания.пока прерывание работает.В результате мой хакерский обходной путь снижения приоритета во время ожидания ожидания и его восстановления после должен работать для того, что мне нужно.

Редактировать: Более поздние результаты

Хотя экспериментбыл успешным, проблемы начали возникать после того, как обходной путь для первоначальной проблемы был реализованВзаимодействие между обработчиками UART и I2C было относительно непротиворечивым, но третье периферийное устройство стало очень странным в своем обработчике прерываний.Обратите внимание на предупреждение о непредсказуемости.

0 голосов
/ 30 декабря 2018

С архитектурной точки зрения это выглядит НЕПРЕДВИДИМЫМ (изменение приоритета активного в настоящий момент исключения).Кажется, что нет никакой логики для обеспечения более согласованного поведения (то есть логика регистрации, о которой вы беспокоитесь, явно не присутствует в M0 / M0 +).

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

Это указано как непредсказуемое в разделе B1.5.4 ARM v6-M ARM .

Для v7-M (B1.5.4, Приоритеты исключений и приоритет)

Это определение приоритета выполнения означает, что обработчик исключения может выполняться с приоритетом, который выше приоритета соответствующегоисключение.В частности, если обработчик уменьшает приоритет соответствующего исключения, приоритет выполнения падает только до приоритета вытесненного исключения с наивысшим приоритетом.Таким образом, уменьшение приоритета текущего исключения никогда не позволяет:

  • Исключенное исключение для вытеснения текущего обработчика исключений.

  • Инверсия приоритетаисключенных исключений.

Аспект v7-M проясняет некоторые из сложных сценариев, которых следует избегать, если вы пытаетесь использовать непредсказуемое поведение, которое вы определили как полезноес частью M0 +.

...