Ativar interrupção, mas nenhum ISR

10

Gostaria de saber o que acontece se uma interrupção estiver ativada (por exemplo: interrupção perdida por arbitragem no módulo CAN do LPC1778 do NXP), mas nenhum ISR foi definido para a interrupção.

Quando ocorre uma interrupção, eu sei que o respectivo sinalizador de interrupção será definido, mas como não defini nenhum ISR, não haverá nenhum endereço de deslocamento do vetor de interrupção armazenado para transferência de controle para essa interrupção e, portanto, o controle passará Para a rotina principal, e eu posso redefinir o sinalizador de interrupção pesquisando-o na rotina principal (é isso que estou pensando). Haverá alguma latência quando a CPU descobrir que não há ISR para o qual pular?

Qualquer solução sobre o que pode acontecer pode realmente me ajudar.

Obrigado.

Atualizar:

Ativei o CAN Interrupt no meu uC, mas não defini um ISR. Quando realizei um teste de loopback interno, o código entrou em um loop infinito. Aqui está o código de desmontagem do loop infinito sendo executado no LPC1778:

B       .
ENDP

Então, se você estiver usando interrupções, use o ISR.

AlphaGoku
fonte
3
Você não precisa ativar a interrupção para poder pesquisar sinalizadores em sua função principal. Se ocorrer a condição que define o sinalizador, esse sinalizador será definido independentemente de você ter ativado ou não a interrupção associada.
brhans
Você está dizendo que um sinalizador de interrupção Perdida na arbitragem de barramento será definido mesmo que eu não ative a "interrupção na arbitragem perdida de barramento" (embora não exista um registro de status que possa indicar a Arbitragem de barramento perdida, exceto o registro de status de interrupção)?
AlphaGoku 28/03
Sim. Em todos os MCU com os quais trabalhei, os sinalizadores de interrupção são definidos sempre que ocorrer a condição que deve configurá-los. Habilitar a interrupção faz com que o MCU vector o manipulador quando o sinalizador associado estiver definido e desabilitar a interrupção faz com que ele ignore o sinalizador e não o vetor para o manipulador, mesmo que o sinalizador esteja definido . Desativar / desativar a interrupção afeta apenas o comportamento do manipulador de salto para interrupção, não o comportamento de configuração do sinalizador.
brhans
Isso é algo que eu não sabia. Muito obrigado. Assim, cada motorista deve periodicamente também verificar os registros de status de interrupção e redefini-las, mesmo que as interrupções não foram habilitados :)
AlphaGoku
@AkshayImmanuelD apenas se for importante. Se a interrupção estiver sempre desabilitada e nada mais se importar com a bandeira, se é definido ou desmarcado é irrelevante.
hobbs

Respostas:

17

Se não houver um ISR definido, o local para a instrução de salto no vetor de interrupção será nulo, poderá ser um salto para uma rotina de exceção, poderá pular para o início do programa ou poderá conter um "retorno de interromper "(por exemplo, RTI).

Aqui está uma desmontagem de uma tabela de interrupção para um processador ATMega 16, mostrando três interrupções não utilizadas vetorizadas para uma rotina que lida com esses casos (pode apenas entrar em um loop infinito) e um vetor legítimo.

  28:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  2c:   0c 94 5c 00     jmp 0xb8    ; 0xb8 <__vector_11>   // <-- ISR
  30:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  34:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>

Qual dos métodos descritos anteriormente para lidar com um ISR ausente dependerá da arquitetura do microcontrolador e do compilador. No caso de uma RTI ou instrução equivalente, ela retornará imediatamente ao aplicativo. No entanto, se a interrupção for acionada por nível, em vez de acionada por borda, provavelmente isso fará com que a interrupção seja acionada novamente, para que você termine em um loop infinito.

Eu acho que pode depender da arquitetura do chip se as interrupções internas (por exemplo, um personagem sendo recebido por um UART) são consideradas disparadas por nível ou por borda. As interrupções externas geralmente podem ser configuradas como uma ou outra.

Há também um outro caso, às vezes várias interrupções são agrupadas e usam o mesmo vetor. Isso era particularmente verdade nos processadores mais antigos, que poderiam ter sofrido apenas algumas interrupções. Nesse caso, a causa da interrupção foi determinada pesquisando o status dos registros de interrupção, que é como o que você propõe.

Mas é uma prática ruim, em qualquer caso, ter interrupções em um sistema e nenhum ISR definido. Não faça isso.

tcrosley
fonte
2
...., ou pode ser indefinido.
Wouter van Ooijen 28/03
@WoutervanOoijen é isso que eu quis dizer com o vetor de interrupção sendo nulo.
tcrosley
1
Os registradores de status não podem indicar alguns erros como o que mencionei acima. Mas esses erros têm uma interrupção. Por isso, pensei em ativar a interrupção apenas para identificar o erro e não usar nenhum ISR. Embora simulando o LPC1778 usando Keil, eu não obter qualquer exceção, então eu acho que o uC deve estar usando a RTI como u mencionado
AlphaGoku
1
Algo a ter em atenção - se você ativar uma interrupção, mas seu manipulador não limpar a sinalização (ou não houver manipulador e o comportamento padrão for um retorno simples), é provável que você descubra que seu MCU terminará para sempre preso em um loop de interrupção.
brhans
1
As interrupções do PIO no ATSAM3X8E podem ser acionadas por borda, mas a condição de interrupção, uma vez configurada, não será apagada até que você leia o ISR (registro de status de interrupção) no manipulador de interrupções - resultando no loop @brhans mencionado.
Simon Wright
1

Depende do seu MCU, compilador e restante do código.

Da minha experiência:

  1. AVR - por padrão, se você não especificar um ISR, o vetor de interrupção no flash será 0x0000, o que significa que seu aplicativo entrará em redefinição sempre que essa interrupção ocorrer.

    Se você realmente precisa da interrupção, mas não precisa do manipulador (por exemplo, use o modo de desligamento de baixo nível de ruído ADC e use a interrupção apenas para ativar o MCU), use a macro EMPTY_INTERRUPT

  2. NXP Kinetis (ARM) - todos os vetores, por padrão, apontam para um manipulador padrão que possui um ponto de interrupção, a CPU simplesmente para e informa ao seu depurador.

filo
fonte