Можно ли безопасно использовать последовательный порт в процедуре прерывания SPI?

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

, 👍0

Обсуждение

неудивительно, что ответ, набравший большинство голосов, соответствует догме. но нет, последовательная печать или запись не зависают в прерывании. Это было исправлено в 2013 году. https://github.com/arduino/ArduinoCore-avr/commit/dbe23685c27cb1467dc84140e4899a0bf8e23248, @Juraj


3 ответа


4

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

,

Аппаратная функция последовательной записи (байтов) в ядре Arduino AVR будет работать в режиме прерывания. Он проверяет, отключены ли прерывания, и если да, и буфер заполнен, он непосредственно выполняет функцию прерывания, которая отправляет байты из буфера на выход., @Juraj

@Юрай является повторным входом для записи или печати?, @qwr

его не нужно повторно вводить, @Juraj

@Юрай Это интересно знать. Я не знал о таком поведении, @jose can u c

@josecanuc, это противоречит вашему ответу, но вопрос в ведомом устройстве SPI, где оно может испортить время или я не знаю, что еще, @Juraj

Не стесняйтесь голосовать за мой ответ соответствующим образом. Я написал это, поскольку оно применяется в более общем плане и не затрагивает конкретную проблему подчиненного SPI ISR. Лучшие ответы приветствуются и должны быть проголосованы!, @jose can u c

Самая большая проблема, с которой я столкнулся, заключалась в том, что tx-буфер был полон, и я выполнил Serial.print внутри ISR. Использование самой высокой скорости передачи данных устранило проблемы, которые у меня были. Но я использовал его только для отладки и не доверяю ему при работе с производственным кодом., @Gerben

@Гербен, это было до этого? https://github.com/arduino/ArduinoCore-avr/commit/dbe23685c27cb1467dc84140e4899a0bf8e23248, @Juraj


2

Функция аппаратной последовательной записи (байтов) в ядре Arduino AVR будет работать в режиме прерывания. Он проверяет, отключены ли прерывания, и если да, и буфер заполнен, он непосредственно выполняет функцию прерывания, которая отправляет байты из буфера на выход.

(Все функции записи и печати аппаратного последовательного порта используют функцию записи (байта) для отправки данных.)

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

,

1

Как правило, прерывания должны выполняться как можно быстрее. Это особенно актуально при использовании SPI, поскольку при ISR ведомого устройства ему необходимо поместить байт в регистр данных SPI (SPDR) прежде произойдет следующая передача. Таким образом, рекомендуется полностью избегать последовательной передачи в прерывании, поскольку в простых прерываниях это может быть самая медленная часть прерывания.

,