Какие прерывания Коры-M3 я могу использовать для работы общего назначения?

У меня был бы некоторый код, который должен быть выполнен как результат конкретного ухода прерывания.

Я не хочу выполнять его в контексте самого прерывания, но я также не хочу, чтобы это выполнилось в режиме потока.

Я хотел бы выполнить его в приоритете, это ниже, чем прерывание высокого уровня, которое ускорило его выполнение, но также и приоритет что выше, чем уровень потока (и некоторые другие прерывания также).

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

Которые лучшие должны использовать и что лучший способ вызвать их?

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

Спасибо,

7
задан Captain NedD 2 May 2010 в 01:23
поделиться

4 ответа

ARM Cortex поддерживает особый вид исключений, называемый PendSV. Кажется, вы могли бы использовать это исключение именно для выполнения своей работы. Практически все вытесняющие ОСРВ для ARM Cortex используют PendSV для реализации переключения контекста.

Чтобы заставить его работать, вам нужно установить приоритет PendSV low (записать 0xFF в регистр PRI_14 в NVIC). Вы также должны установить приоритет для всех IRQ выше PendSV (записать меньшие числа в соответствующие регистры приоритета в NVIC). Когда вы будете готовы обработать все сообщение, запустите PendSV из высокоприоритетной ISR:

*((uint32_t volatile *)0xE000ED04) = 0x10000000; // trigger PendSV

ЦП ARM Cortex затем завершит вашу ISR и все другие ISR, которые, возможно, были вытеснены им, и в конечном итоге он перейдет в хвостовую цепочку к исключению PendSV. Здесь должен находиться ваш код для анализа сообщения.

Обратите внимание, что PendSV может быть вытеснен другими ISR. Это все нормально, но вам, очевидно, нужно помнить о защите всех общих ресурсов с помощью критического участка кода (кратковременное отключение и включение прерываний). В ARM Cortex вы отключаете прерывания, выполняя __asm ​​(«cpsid i»), и вы включаете прерывания с помощью __asm ​​(«cpsie i»). (Большинство компиляторов C предоставляют для этой цели встроенные встроенные функции или макросы.)

15
ответ дан 6 December 2019 в 09:18
поделиться

. Вы используете RTOS? Обычно этот тип вещей обрабатывается с помощью потока с высоким приоритетом, который получает сигнал о выполнении некоторой работы с помощью прерывания.

Если вы не используете ОСРВ, у вас всего несколько задач, и работа, запускаемая прерыванием, не слишком ресурсозатратна, возможно, проще всего будет выполнить свою высокоприоритетную работу в контексте обработчик прерывания. Если эти условия не выполняются, то реализация того, о чем вы говорите, станет началом самой базовой многозадачной ОС. Это может быть интересный проект сам по себе, но если вы хотите просто выполнить работу, вы можете рассмотреть простую ОСРВ.

Поскольку вы упомянули некоторые особенности выполняемой вами работы, вот обзор того, как я справлялся с подобной проблемой в прошлом:

Для обработки полученных данных через UART - один метод, который я использовал, когда Работа с более простой системой, которая не имеет полной поддержки для постановки задач (т. е. задачи являются циклическими в простом , а цикле), заключается в наличии общей очереди для данных, полученных от UART. Когда срабатывает прерывание UART, данные считываются из RDR (Регистр данных приема) UART и помещаются в очередь.Уловка, позволяющая справиться с этим таким образом, чтобы указатели очереди не были повреждены, состоит в том, чтобы тщательно сделать указатели очереди изменчивыми и убедиться, что только обработчик прерывания изменяет указатель хвоста и что только задача `` переднего плана '', которая читает данные вне очереди изменен указатель заголовка. Общий обзор:

  • производитель (обработчик прерывания UART):

    1. считывает queue.head и queue.tail в локальные переменные;
    2. увеличивает локальный хвост указатель (, а не фактический указатель queue.tail ). Оберните его в начало буфера очереди, если вы увеличили значение после конца буфера очереди.
    3. сравните local.tail и local.head - если они равны, очередь заполнена, и вам придется выполнить любую подходящую обработку ошибок.
    4. в противном случае вы можете записать новые данные туда, где local.tail указывает
    5. , только теперь вы можете установить queue.tail == local.tail
    6. возврат из прерывания (или обработать другой UART связанные задачи, если это необходимо, например, чтение из очереди передачи)
  • потребитель («задача» переднего плана)

    1. считывает queue.head и queue.tail в локальные;
    2. если local.head == local.tail , очередь пуста; вернуться, чтобы позволить следующей задаче выполнить некоторую работу
    3. прочитать байт, на который указывает local.head
    4. инкремент local.head , и при необходимости обернуть его;
    5. установить queue.head = local.head
    6. перейти к шагу 1

Убедитесь, что очередь queue.head и .tail являются энергозависимыми (или записывают эти биты в сборку), чтобы убедиться в отсутствии проблем с последовательностью.

Теперь просто убедитесь, что ваша очередь принимаемых данных UART достаточно велика, чтобы вместить все байты, которые могут быть получены до того, как задача переднего плана получит шанс на выполнение. Задаче переднего плана необходимо перенести данные из очереди в свои собственные буферы, чтобы создать сообщения для передачи в задачу «обработчик сообщений».

3
ответ дан 6 December 2019 в 09:18
поделиться

Проверьте документацию по процессору. Некоторые процессоры будут прерываться, если вы запишете бит, который обычно нужно очистить внутри прерывания. В настоящее время я использую SiLabs c8051F344 и в разделе спецификации 9.3.1:

«Программное обеспечение может моделировать прерывание, установив любой флаг ожидающего прерывания на логику 1. Если прерывания разрешены для этого флага, запрос прерывания будет сгенерировано, и ЦП выполнит вектор к адресу ISR, связанному с флагом ожидания прерывания. "

0
ответ дан 6 December 2019 в 09:18
поделиться

"Более официальный способ" или скорее традиционный метод заключается в использовании приоритетного вытесняющего многозадачного планировщика и шаблона "отложенного обработчика прерываний".

1
ответ дан 6 December 2019 в 09:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: