Определение времени прерывания таймера

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

Предположим, в main(), если я выполняю другую операцию, например, записываю во флэш-память SPI огромный блок данных, и происходит прерывание по таймеру, будет ли процесс записи данных остановлен из-за прерывания по таймеру ISR или данные будут повреждены из-за прерывания по таймеру ISR? Мне просто интересно, определяется ли время прерывания таймера с учетом таких операций, которые составляют полный код приложения?

Если да, то если запись флэш-памяти SPI занимает около 5 мс, а прерывание таймера происходит каждую 1 мс, как я могу отслеживать тайм-ауты, генерацию импульсов и т. д., не ставя под угрозу сценарии повреждения данных, потому что теперь мне нужно изменить прерывание таймера на более чем 5 мс , а затем я не могу сохранить ссылку на тайм-ауты для процессов, где могут потребоваться небольшие тайм-ауты, такие как 1 мс.

Обновлять

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

Ответы (3)

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

Другое дело, чтобы код прерывания по таймеру был очень простым и лаконичным. Не помещайте реальный код решения в подпрограмму таймера. Вместо этого создайте себе набор переменных таймера, управляемых программным обеспечением. Прерывание по таймеру просто проверяет каждую из этих переменных и, если она не равна нулю, просто уменьшает значение на единицу. Основной код устанавливает одну или несколько из этих переменных в подходящие ненулевые значения, когда требуется период времени. Затем в обычном ходе его основных операций можно проверить переменную таймера, чтобы увидеть, не стало ли оно равным нулю. Таким образом, это может сигнализировать о тайм-ауте или задержке по времени.

Именно так я использую свой ISR (просто чтобы начать приращение переменной и проверить значение переменной в main()). Но для согласованности времени ISR никогда не должен быть остановлен правильно (в отличие от того, что вы сказали)? В сценарии в моем вопросе, если я хочу завершить процесс SPI, я должен отключить таймер-> полная запись-> включить таймер.
Я не говорил, что вам придется отключать таймер на протяжении всей записи. Что я действительно сказал, так это то, что если код написан правильно, запись не будет повреждена прерыванием таймера. Затем я сказал, что иногда могут быть критические узкие окна, где вам нужно отключить прерывания на очень короткое время. Это может быть связано с временной зависимостью чипа или когда вам нужно гарантировать атомарную операцию над элементом данных, для выполнения которой требуется несколько инструкций ЦП.
Как отметил @berendi, это должно быть хорошо для ситуации с SPI, если я не буду возиться с регистрами SPI из таймера ISR, верно?

запись во флэш-память SPI большого блока данных, и происходит прерывание таймера, будет ли процесс записи данных остановлен из-за прерывания таймером ISR или данные будут повреждены из-за прерывания таймером ISR?

Ни в коем случае (но проверьте техническое описание вашей вспышки, чтобы убедиться). Флэш-память SPI не имеет тайм-аутов, только нижние границы таймингов. У вас есть все время в мире, чтобы закончить запись или любую другую операцию. Никакого повреждения данных не должно произойти, пока вы не коснетесь регистров SPI из вашего ISR (для начинающих позже вы сделаете некоторую блокировку).

определяется ли время прерывания таймера с учетом таких операций, составляющих полный код приложения?

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

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

Таким образом, вы по-прежнему будете иметь точный хронометраж и не потеряете никаких прерываний. Большинство (если не все) контроллеров прерываний достаточно умны, чтобы удерживать запрос прерывания до тех пор, пока ЦП не сможет его обработать, но они не будут отслеживать, сколько запросов одного и того же типа возникло без обслуживания.

Я использую SST25VF010A. Я проверю. Вы говорите, что если мое прерывание по таймеру на самом деле занимает 500 мкс из 1 мс (в худшем случае), я могу отключить прерывание по таймеру на максимальное время менее 1 мс (время до следующего прерывания) + оставшиеся 500 мкс (доступно с 1-го прерывания), если у меня есть поддерживать целостность тайм-аута?.
Нет, не отключайте прерывания более чем на 1 мс. Предположим худший случай: запрос прерывания по таймеру происходит как раз в тот момент, когда вы отключаете прерывания в основном приложении. Теперь, если вы оставите прерывания отключенными более чем на 1 мс, тогда произойдет второе прерывание таймера, в то время как процессор еще не может обслужить первое, поэтому одно прерывание будет потеряно.
Как может произойти прерывание второго таймера, если я отключу прерывание? Кроме того, как вы можете отслеживать «не отключать прерывания более 1 мс» без таймера, который говорит мне не превышать 1 мс ??
- Прерывания не происходит, происходит запрос. Я прошу тебя прекратить то, что ты делаешь, но ты меня не слышишь, значит, ты не останавливаешься. - Программный таймер прерывания просто не работает, пока прерывания отключены, вы не можете использовать его для отслеживания времени, проведенного с отключенными прерываниями. - Если вы считаете, что должны отключать прерывания более чем на 1 мс, то подумайте, должен быть какой-то другой способ. Следует избегать таких конструкций во встраиваемом программировании. Возможно, опишите точную проблему в отдельном вопросе вместе с описанием вашего оборудования.
Я использую прерывание аппаратного таймера. Не программное прерывание.
Если бы вы использовали аппаратный таймер , вы могли бы прочитать его регистры, чтобы определить прошедшее время в любое время . С другой стороны, если у вас есть аппаратное прерывание, вызывающее обработчик прерывания (который является программным), который увеличивает счетчик программного таймера, тогда у вас есть проблема, когда прерывания отключены слишком долго.
Точно. Я использую аппаратный таймер, который увеличивает счетчик программного таймера. Отсюда вопрос.

В дополнение к тому, что сказал @berendi, вы можете сделать две вещи.

1) Отключите прерывания непосредственно перед передачей важных данных. И вместо этого используйте опрос. Предполагая, что вы передаете данные из буфера, отправьте около 10 (здесь можно использовать любое произвольное число) кадров данных и опросите вывод прерывания. Даже если прерывание отключено, флаг будет установлен, поэтому вы можете аппроксимировать* событие, не приостанавливая передачу данных.

2) Держите прерывание включенным. У вас очень мало инструкций внутри ISR. Высокоскоростной контроллер сможет выполнять очень небольшие процессы между передачей данных**. Поскольку периферийное устройство SPI возьмет на себя нагрузку после того, как вы сбросите данные в буфер, у процессора будет мало времени между ними. Он может вместить хорошо рассчитанные события. Учитывайте задержку входа и выхода прерывания, а также время обработки инструкций.

В качестве альтернативы , ЕСЛИ контроллер поддерживает DMA, ваша проблема может быть легко решена.

*при условии, что вы делаете это достаточно часто, чтобы обнаружить два события.

** при передаче критических данных рекомендуется отключать и разрешать прерывания.