Włącz przerwanie, ale bez ISR

10

Chciałbym wiedzieć, co się stanie, jeśli włączone jest Przerwanie (np. Arbitration Lost Interrupt w module CAN NXP LPC1778), ale dla przerwania nie zdefiniowano ISR.

Kiedy takie przerwanie nastąpi, wiem, że odpowiednia flaga przerwania zostanie ustawiona, ale ponieważ nie zdefiniowałem żadnego ISR, nie będzie przechowywany żaden adres przesunięcia wektora przerwania dla przekazania sterowania dla takiego przerwania, a więc sterowanie przejdzie z powrotem do głównej procedury i mogę zresetować flagę przerwania, odpytując ją w głównej procedurze (tak myślę). Czy będzie jakieś opóźnienie, gdy procesor dojdzie do wniosku, że nie ma ISR, do którego można by wskoczyć?

Wszelkie rozwiązania tego, co może się zdarzyć, mogą mi naprawdę pomóc.

Dzięki.

Aktualizacja:

Włączyłem CAN Interrupt na moim komputerze, ale nie zdefiniowałem ISR. Kiedy przeprowadziłem wewnętrzny test pętli zwrotnej, kod wszedł w nieskończoną pętlę. Oto kod dezasemblacji nieskończonej pętli wykonywanej na LPC1778:

B       .
ENDP

Tak więc, jeśli używasz przerwań, użyj ISR.

AlphaGoku
źródło
3
Nie musisz włączać przerwania, aby móc sondować flagi w swojej głównej funkcji. Jeśli wystąpi warunek, który ustawia flagę, ta flaga zostanie ustawiona bez względu na to, czy włączono powiązane przerwanie.
brhans
Mówisz, że ustawiona zostanie flaga przerwania arbitrażu magistrali, nawet jeśli nie włączę „przerwania w przypadku utraty arbitrażu magistrali” (chociaż nie ma rejestru statusu, który mógłby wskazywać na utratę arbitrażu magistrali, z wyjątkiem rejestru statusu przerwania)?
AlphaGoku,
Tak. W każdym MCU, z którym pracowałem, flagi przerwania są ustawiane za każdym razem, gdy wystąpi warunek, który powinien je ustawić. Włączenie przerwania powoduje, że MCU przenosi wektor na moduł obsługi, gdy ustawiona jest powiązana flaga, a wyłączenie przerwania powoduje, że ignoruje flagę, a nie wektor dla modułu obsługi, mimo że flaga jest ustawiona . Wyłączenie / przerwanie przerwania wpływa tylko na zachowanie procedury obsługi skoku na przerwanie, a nie na ustawienie flagi.
brhans
Wow, to coś, czego nie wiedziałem. Wielkie dzięki. Dlatego każdy kierowca musi okresowo sprawdzać rejestry statusu przerwań i je resetować, nawet jeśli przerwania nie zostały włączone :)
AlphaGoku
@AkshayImmanuelD tylko wtedy, gdy ma to znaczenie. Jeśli przerwanie jest zawsze wyłączone i nic więcej nie obchodzi flagi, to czy jest ustawione czy usunięte, nie ma znaczenia.
hobbs

Odpowiedzi:

17

Jeśli nie zdefiniowano ISR, lokalizacja instrukcji skoku w wektorze przerwań będzie albo zerowa, może być skokiem do procedury wyjątku, może przeskoczyć na początek programu lub może zawierać „powrót z instrukcja interrupt ”(np. RTI).

Oto demontaż tabeli przerwań dla procesora ATMega 16, pokazujący trzy nieużywane przerwania wektoryzowane do procedury, która obsługuje takie przypadki (może po prostu przejść do nieskończonej pętli), i jeden prawidłowy wektor.

  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>

Która z opisanych wcześniej metod obsługi brakującego ISR będzie zależeć zarówno od architektury mikrokontrolera, jak i kompilatora. W przypadku instrukcji RTI lub równoważnej instrukcja natychmiast powróci do aplikacji. Jeśli jednak przerwanie jest wyzwalane poziomem, a nie zboczem, prawdopodobnie spowoduje to, że przerwanie zostanie ponownie uruchomione, więc skończysz w nieskończonej pętli.

Myślę, że może zależeć od architektury układu, czy wewnętrzne przerwania (np. Znak odbierany przez UART) są uważane za wyzwalane poziomem lub wyzwalane zboczem. Przerwania zewnętrzne można zwykle skonfigurować jako jedno lub drugie.

Jest jeszcze jeden przypadek, czasem kilka przerwań jest zgrupowanych razem i używa tego samego wektora. Było to szczególnie prawdziwe w przypadku starszych procesorów, które mogły mieć tylko kilka przerw. W takim przypadku przyczyna przerwania została ustalona przez sondowanie statusu rejestrów przerwań, co jest w pewnym sensie tym, co proponujesz.

Ale w każdym razie jest to zła praktyka, aby mieć przerwy w systemie i nie zdefiniować ISR. Nie rób tego

tcrosley
źródło
2
.... lub może być niezdefiniowany.
Wouter van Ooijen
@WoutervanOoijen to właśnie rozumiałem przez to, że wektor przerwań jest zerowy.
tcrosley,
1
Rejestry stanu nie mogą wskazywać kilku błędów, takich jak ten, o którym wspomniałem powyżej. Ale takie błędy mają przerwanie. Dlatego pomyślałem o włączeniu przerwania tylko po to, aby zidentyfikować błąd i nie używać żadnego ISR. Podczas symulacji LPC1778 za pomocą Keila nie dostałem żadnego wyjątku, więc myślę, że uC musi używać RTI, jak wspomniano
AlphaGoku
1
Coś, o czym należy pamiętać - jeśli włączysz przerwanie, ale twój moduł obsługi nie usunie flagi (lub nie ma modułu obsługi, a domyślne zachowanie to zwykły powrót), najprawdopodobniej okaże się, że MCU skończy się na zawsze utknął w pętli przerwań.
brhans
1
Przerwania PIO w ATSAM3X8E mogą być wyzwalane zboczem, ale raz ustawiony warunek przerwania nie zostanie skasowany, dopóki nie przeczytasz ISR (rejestru statusu przerwania) w procedurze obsługi przerwań - skutkując wspomnianą pętlą @brhans.
Simon Wright
1

To zależy od MCU, kompilatora i reszty kodu.

Z mojego doświadczenia:

  1. AVR - domyślnie, jeśli nie określisz ISR, wówczas wektor przerwań we flashu będzie wynosił 0x0000, co oznacza, że ​​twoja aplikacja będzie się resetować za każdym razem, gdy nastąpi takie przerwanie.

    Jeśli naprawdę potrzebujesz przerwania, ale nie potrzebujesz modułu obsługi (np. Użyj trybu cichego wyłączania ADC i użyj przerwania tylko do wybudzenia MCU), powinieneś użyć makra EMPTY_INTERRUPT

  2. NXP Kinetis (ARM) - wszystkie wektory domyślnie wskazują domyślny moduł obsługi, który ma punkt przerwania, procesor po prostu zatrzyma się i przekaże go do twojego debuggera.

filo
źródło