У меня есть загадка.Часть, которую я использую (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 в этом отношении, но я подумал, что сначала проверю здесь.Если я доберусь до эксперимента, я опубликую ответ с результатами.