La instrucción AVR SEI ( http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_SEI.html ) espera a que finalice la siguiente instrucción antes de habilitar las interrupciones.
Si uso otra instrucción para configurar el indicador I en SREG, ¿esto también esperará 1 instrucción?
En otras palabras: ¿Es la espera una característica de la instrucción SEI o del registro de estado?
Si es una característica de la instrucción SEI, ¿en qué punto se establece realmente el indicador, en el ciclo que ejecuta SEI o con la siguiente instrucción?
avr
interrupts
assembly
Jay Jay
fuente
fuente
Respuestas:
¡Resultados empíricos!
Si bien las otras respuestas son reflexivas y bien razonadas, todas son incompletas o solo conjeturas. Cuando la documentación es ambigua, debemos experimentar y probar cada caso.
Esta pregunta merece una respuesta concluyente, ¡así que saquemos un AVR y comencemos a configurar algunos bits!
Procedimiento
Para probar, hice un pequeño programa Arduino (ATMEGA328P) que ...
while (1)
)INT0
bajando)Utilicé un banco de pruebas que encendía un LED en la única instrucción después de que se habilitaran las interrupciones. Al probar diferentes formas de habilitar las interrupciones en el banco de pruebas y verificar el LED, podría decir si la instrucción después de la instrucción de habilitación se ejecutó o no.
Si el LED no se encendió, entonces sé que el ISR se ejecutó (y bloqueó) inmediatamente después de que se habilitaran las interrupciones.
Si el LED se encendió, sé que se permitió ejecutar la siguiente instrucción antes de que se llamara al ISR.
Resultados
SEI
instrucción (caso base)Código:
sei
Resultado: LED encendido. Siguiendo instrucciones ejecutadas.
OUT
instrucciónCódigo:
Resultado:
Llevado en. Siguiendo instrucciones ejecutadas.
ST
instrucciónCódigo:
Resultado:
Llevado en. Siguiendo instrucciones ejecutadas.
¡Conclusión!
P: ¿La espera es una característica de la instrucción SEI o del registro de estado?
R: Parece que cambiar el
I
bit enSREG
de a0
a1
permitirá que la siguiente instrucción se ejecute a continuación, incluso si hay una interrupción pendiente, independientemente de qué instrucción se use para establecer el bit.Notas
Esto en realidad se convirtió en una pregunta muy interesante con muchas complicaciones. Si está interesado en los detalles, consulte ...
http://wp.josh.com/2016/01/05/different-ways-to-set-i-bit-in-avr-sreg-besides-sei/
fuente
Tengo entendido por la documentación que realizar la
sei
instrucción no es diferente de escribir directamente un 1 en el bit I del SREG. La ventaja de la instrucción es que no necesita cargar primero un valor1<<I
en un registro de trabajo para cambiar el SREG, por lo que ahorra tiempo.Para elaborar, usando
sei
:Establecer el bit usando
sbi
(solo funcionaría si SREG estuviera en los 32 bytes inferiores del mapa de registro, pero parece que en la mayoría, si no en todos, no lo está).Escribiendo a I bit directamente en SREG:
El
I
bit debe fijarse en SREG tan pronto como lasei
instrucción (osbi
oout
) completa. Sin embargo, cualquier interrupción pendiente no se manejará hasta después de que se complete la siguiente instrucción: el bit se establecerá, pero se necesita un ciclo adicional para que las interrupciones se habiliten. Debido a que una interrupción no puede manejarse a mitad de la instrucción, y algunas instrucciones tardan más de un ciclo en ejecutarse, especifican el tiempo que lleva habilitarse como una instrucción. Este debería ser el caso para todas las versiones del código, es decir, cada una de las anteriores provocará el retraso de una instrucción.Después de un poco de búsqueda, encontré este hilo en el foro Arduino en el que se realizaron varias pruebas diferentes para verificar el comportamiento. Parece estar de acuerdo con lo que dije anteriormente.
Además, de acuerdo con ese hilo, si el
I
indicador ya está configurado, entonces no hay respuesta retrasada de una interrupción causada por losei
que implica que la respuesta retrasada no es causada por la instrucción en sí, sino en el hardware interno controlado por elI
indicador. por lo que cualquier operación que cambia la bandera en SREG, ya seasei
oout
osts
tendrá exactamente el mismo comportamiento.fuente
SBI
no se puede usar para configurar elI
bit, porSREG
lo que cualquier código que lo haga probablemente no se probó en la vida real porque ni siquiera se ensamblará.SBI
solo puede operar en los 32 registros inferiores y SREG está en la ranura 63.out
fue el que estaba usando originalmente. Pensé que había encontrado un AVR (podría ser un ATTiny) que tiene el SREG en los 32 registros inferiores, pero puedo estar imaginándolo.En mi humilde opinión, escribir en SREG todavía demora 1 instrucción que se puede probar de esta manera (pseudocódigo):
Lamentablemente no tengo tiempo para hacerlo :(
fuente
Eso no es lo que dice. Las documentaciones dicen
No es que espere la próxima instrucción. Leí esto ya que el indicador se establece de inmediato, pero aunque esté habilitado, no se manejarán interrupciones hasta que se ejecute la siguiente instrucción.
fuente