A instrução AVR SEI ( http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_SEI.html ) aguarda a conclusão da próxima instrução antes de ativar as interrupções.
Se eu usar outra instrução para definir o sinalizador I no SREG, isso também esperará 1 instrução?
Em outras palavras: a espera é um recurso da instrução SEI ou do registro de status?
Se é um recurso da instrução SEI, em que momento o sinalizador é realmente configurado, no ciclo que executa o SEI ou com a próxima instrução?
avr
interrupts
assembly
Jay Jay
fonte
fonte
Respostas:
Resultados empíricos!
Enquanto as outras respostas são bem pensadas e bem fundamentadas, são todas incompletas ou apenas conjecturas. Onde a documentação é ambígua, devemos experimentar e testar todos os casos.
Esta pergunta merece uma resposta conclusiva, então vamos retirar um AVR e começar a definir alguns bits!
Procedimento
Para testar, fiz um pequeno programa do Arduino (ATMEGA328P) que ...
while (1)
)INT0
diminuindo)Eu usei um banco de testes que acenderia um LED na instrução única após as interrupções serem ativadas. Ao tentar diferentes maneiras de ativar interrupções no banco de testes e verificar o LED, eu poderia dizer se a instrução após a instrução de ativação foi executada ou não.
Se o LED não acender, sei que o ISR foi executado (e bloqueado) imediatamente após a ativação das interrupções.
Se o LED acender, sei que a próxima instrução foi executada antes da chamada do ISR.
Resultados
SEI
instrução (caso base)Código:
sei
Resultado: LED aceso. Seguindo a instrução executada.
OUT
instruçãoCódigo:
Resultado:
LED aceso. Seguindo a instrução executada.
ST
instruçãoCódigo:
Resultado:
LED aceso. Seguindo a instrução executada.
Conclusão!
P: A espera é um recurso da instrução SEI ou do registro de status?
R: Parece que alterar o
I
bit inSREG
de a0
para a1
permitirá que a seguinte instrução seja executada a seguir, mesmo que haja uma interrupção pendente, independentemente da instrução usada para definir o bit.Notas
Isso realmente se transformou em uma pergunta muito interessante, com muitas complicações. Se você estiver interessado nos detalhes, confira ...
http://wp.josh.com/2016/01/05/different-ways-to-set-i-bit-in-avr-sreg-besides-sei/
fonte
Entendo, a partir da documentação, que executar a
sei
instrução não é diferente de escrever diretamente um 1 no bit I do SREG. A vantagem da instrução é que você não precisa carregar primeiro um valor1<<I
em um registro de trabalho para alterar o SREG, economizando tempo.Para elaborar, usando
sei
:Definir o bit usando
sbi
(só funcionaria se o SREG estivesse nos 32 bytes inferiores do mapa de registro, mas parece que na maioria, se não todos, não está).Escrevendo para bit diretamente no SREG:
O
I
bit deve ser definido em SREG assim que asei
instrução (sbi
ouout
) for concluída. No entanto, quaisquer interrupções pendentes não serão tratadas até que a próxima instrução seja concluída - o bit será definido, mas é necessário um ciclo extra para que as interrupções sejam ativadas. Como uma interrupção não pode ser manipulada no meio da instrução e algumas instruções levam mais de um ciclo para serem executadas, elas especificam o tempo necessário para serem ativadas como uma instrução. Este deve ser o caso de todas as versões do código - ou seja, cada uma das opções acima causará o atraso de uma instrução.Depois de um pouco de pesquisa, achei esse tópico no fórum do Arduino, no qual vários testes diferentes foram realizados para verificar o comportamento. Parece concordar com o que eu disse acima.
Além disso, de acordo com esse encadeamento, se o
I
sinalizador já estiver definido, não haverá resposta atrasada de uma interrupção causada, osei
que implica que a resposta atrasada é causada não pela própria instrução, mas pelo hardware interno controlado peloI
sinalizador - portanto, qualquer operação que muda a bandeira em SREG, sejasei
ouout
ousts
terá exatamente o mesmo comportamento.fonte
SBI
não pode ser usado para definir oI
bit;SREG
portanto, qualquer código que faça isso provavelmente não foi realmente testado na vida real porque ele nem será montado.SBI
só pode funcionar com as mais baixas 32 registros e SREG é a ranhura 63.out
era o que eu estava usando originalmente. Eu pensei em encontrar um AVR (pode ser um ATTiny) que tem o SREG nos 32 registros mais baixos, mas eu posso estar imaginando.O IMHO que escreve para o SREG ainda atrasa 1 instrução pode ser testada assim (pseudocódigo):
Infelizmente, não tenho tempo para fazê-lo :(
fonte
Não é isso que diz. As documentações dizem
não que aguarde a próxima instrução. Eu li isso como o sinalizador é definido imediatamente, mas, embora habilitado, nenhuma interrupção será tratada até que a próxima instrução seja executada.
fonte