Я использовал прерывание по таймеру в своем приложении, в основном по причинам синхронизации, таким как обнаружение тайм-аута для процессов, генерация импульсов и т. д., каждые 1 мс. Теперь у меня есть сомнения.
Предположим, в main(), если я выполняю другую операцию, например, записываю во флэш-память SPI огромный блок данных, и происходит прерывание по таймеру, будет ли процесс записи данных остановлен из-за прерывания по таймеру ISR или данные будут повреждены из-за прерывания по таймеру ISR? Мне просто интересно, определяется ли время прерывания таймера с учетом таких операций, которые составляют полный код приложения?
Если да, то если запись флэш-памяти SPI занимает около 5 мс, а прерывание таймера происходит каждую 1 мс, как я могу отслеживать тайм-ауты, генерацию импульсов и т. д., не ставя под угрозу сценарии повреждения данных, потому что теперь мне нужно изменить прерывание таймера на более чем 5 мс , а затем я не могу сохранить ссылку на тайм-ауты для процессов, где могут потребоваться небольшие тайм-ауты, такие как 1 мс.
Обновлять
Я использую аппаратный таймер, и когда происходит прерывание, я использую счетчик программного таймера (переменную) в ISR, чтобы отслеживать время.
Если вы пишете основной код, в котором запись SPI Flash происходит надлежащим образом, то возникновение прерывания таймера не должно повреждать выполняемую операцию. Если операция основного потока имеет определенные временные зависимости, которые необходимо соблюдать, то необходимо отключать прерывания на короткие периоды времени, когда возникают критические временные окна.
Другое дело, чтобы код прерывания по таймеру был очень простым и лаконичным. Не помещайте реальный код решения в подпрограмму таймера. Вместо этого создайте себе набор переменных таймера, управляемых программным обеспечением. Прерывание по таймеру просто проверяет каждую из этих переменных и, если она не равна нулю, просто уменьшает значение на единицу. Основной код устанавливает одну или несколько из этих переменных в подходящие ненулевые значения, когда требуется период времени. Затем в обычном ходе его основных операций можно проверить переменную таймера, чтобы увидеть, не стало ли оно равным нулю. Таким образом, это может сигнализировать о тайм-ауте или задержке по времени.
запись во флэш-память SPI большого блока данных, и происходит прерывание таймера, будет ли процесс записи данных остановлен из-за прерывания таймером ISR или данные будут повреждены из-за прерывания таймером ISR?
Ни в коем случае (но проверьте техническое описание вашей вспышки, чтобы убедиться). Флэш-память SPI не имеет тайм-аутов, только нижние границы таймингов. У вас есть все время в мире, чтобы закончить запись или любую другую операцию. Никакого повреждения данных не должно произойти, пока вы не коснетесь регистров SPI из вашего ISR (для начинающих позже вы сделаете некоторую блокировку).
определяется ли время прерывания таймера с учетом таких операций, составляющих полный код приложения?
Конечно, вы всегда должны учитывать время, которое может быть потрачено на какой-либо обработчик прерывания. Если у вас есть какая-то очень срочная задача, вы можете отключить прерывания на короткое время, просто сделайте следующее
Сумма максимального времени, проведенного в обработчиках прерываний и в любой одной критической секции (где прерывания запрещены), не должна превышать время между любыми последовательными прерываниями одного и того же типа.
Таким образом, вы по-прежнему будете иметь точный хронометраж и не потеряете никаких прерываний. Большинство (если не все) контроллеров прерываний достаточно умны, чтобы удерживать запрос прерывания до тех пор, пока ЦП не сможет его обработать, но они не будут отслеживать, сколько запросов одного и того же типа возникло без обслуживания.
В дополнение к тому, что сказал @berendi, вы можете сделать две вещи.
1) Отключите прерывания непосредственно перед передачей важных данных. И вместо этого используйте опрос. Предполагая, что вы передаете данные из буфера, отправьте около 10 (здесь можно использовать любое произвольное число) кадров данных и опросите вывод прерывания. Даже если прерывание отключено, флаг будет установлен, поэтому вы можете аппроксимировать* событие, не приостанавливая передачу данных.
2) Держите прерывание включенным. У вас очень мало инструкций внутри ISR. Высокоскоростной контроллер сможет выполнять очень небольшие процессы между передачей данных**. Поскольку периферийное устройство SPI возьмет на себя нагрузку после того, как вы сбросите данные в буфер, у процессора будет мало времени между ними. Он может вместить хорошо рассчитанные события. Учитывайте задержку входа и выхода прерывания, а также время обработки инструкций.
В качестве альтернативы , ЕСЛИ контроллер поддерживает DMA, ваша проблема может быть легко решена.
*при условии, что вы делаете это достаточно часто, чтобы обнаружить два события.
** при передаче критических данных рекомендуется отключать и разрешать прерывания.
АльфаГоку
Майкл Карас
АльфаГоку