(Específico para o Arduino Uno ...)
O que acontece com a pilha quando ocorre uma interrupção em um microcontrolador AVR e eu chamo uma função? O compilador embutiu o código? Ele armazena em cache a pilha em algum lugar e redefine o ponteiro da pilha? Ele possui uma pilha secundária apenas para interrupções?
Pelo que entendi, o vetor para a interrupção é um comando GOTO direto na montagem. Além disso, não acho que o microcontrolador mexa automaticamente com a pilha, por isso provavelmente é deixado sozinho. No entanto, isso ainda não explica como as funções funcionam durante um ISR.
arduino
interrupts
compiler
Pinguim anônimo
fonte
fonte
Respostas:
O AVR é uma arquitetura RISC, portanto, possui um gerenciamento bastante básico de interrupções no hardware. A maioria dos processadores mexe com a pilha durante as interrupções, embora existam alguns, principalmente o ARM e o PowerPC, que usam métodos diferentes.
De qualquer forma, é isso que o AVR faz para interrupções:
Quando ocorre uma interrupção, o hardware do processador executa estas etapas, que não são apenas um simples GOTO:
Agora, neste momento, o hardware fez tudo o que está fazendo. O software deve ser escrito corretamente para não quebrar as coisas. Normalmente, as próximas etapas são nesse sentido.
Empurre o registro de status para a pilha. (Isso deve ser feito primeiro antes de ser alterado).
Envie todos os registradores da CPU que serão (ou podem ser) alterados para a pilha. Quais registros que precisam ser salvos dessa maneira são definidos pelo modelo de programação. O modelo de programação é definido pelo compilador.
Agora o código de interrupção de trabalho pode ser executado. Para responder ao caso na questão de chamar uma função, ele apenas faz o que sempre faz, pressiona o valor de retorno na pilha e, em seguida, retorna quando terminar. Isso não afeta nenhum desses valores anteriores que salvamos na pilha até agora.
Agora terminamos e queremos retornar da interrupção. Primeiro, precisamos fazer a limpeza do software.
Execute a instrução RTI. O hardware executa estas etapas para esta instrução:
uma. Habilite o sinalizador de interrupção global. (Observe que pelo menos uma instrução deve ser executada antes que a próxima interrupção seja respeitada. Isso impede que interrupções pesadas bloqueiem totalmente o trabalho em segundo plano.)
b. Coloque o endereço de retorno salvo no PC.
Agora estamos de volta ao código normal.
Observe que há alguns pontos em que precisamos ter muito cuidado, principalmente em torno do registro de status e do salvamento de registros que podem ser alterados. Felizmente, se você estiver usando um compilador C, tudo isso será tratado sob as cobertas.
Além disso, você deve observar a profundidade da pilha. A qualquer momento em que as interrupções são ativadas, um ISR pode usar mais da pilha do que é óbvio, observando o código local. Claro, isso realmente não aparece muito, a menos que você esteja levando a memória ao limite.
Aqui está um link que descreve esse processo, se você desejar uma referência.
fonte
ISR_NAKED
). Isso pode permitir que você pule as etapas 5,6,8,9, em um contexto em que você realmente precisa desses ciclos. A desvantagem é que você deve estar absolutamente certo de que preservará quaisquer registros relevantes ou poderá substituí-los sem causar danos.