Forum: Mikrocontroller und Digitale Elektronik LPC43xx /Cortex M4/M0 - Nested Vector Interrupt Controller -Problem


von Rene F. (fook)


Lesenswert?

Hallo..

ich habe ein neues Problem mit meinem LPC4353 Cortex M4/M0.
Es ist per RMII ein Ethernet-Controller an den Controller angeschlossen 
worden und ich habe die Initialisierungsroutinen aus dem LWIP-Stack bzw. 
der CMSIS-Lib genommen.

Nun kommt es aber ab und zu (!) zu einem Freeze des Systems wenn ich 
folgende Befehle ausführe:
1
NVIC_DisableIRQ(ETHERNET_IRQn);
2
NVIC_ClearPendingIRQ(ETHERNET_IRQn);
3
NVIC_EnableIRQ(ETHERNET_IRQn);
explizit die "EnableIRQ"-Anweisung ist dabei für das Stoppen der 
Ausführung verantwortlich. Deshalb hatte ich schon die entsprechende 
Routine aus der CMSIS extrahiert und in das Programm eingebaut - selbes 
Ergebnis:
1
 NVIC->ISER[0]=1<<5;  // ETHERNET_IRQn=5

ich hatte schon an ein Timing-Problem gedacht und deshalb vor den obigen 
Anweisungen eine Wartezeit eingefügt, aber leider ohne Erfolg.
Die Interrupt-Routine (ETH_IRQHandler) ist zu Testzwecken extra auf 
folgendes beschränkt:
1
void ETH_IRQHandler(void)
2
{
3
  uint32 ints;
4
5
  /* Get pending interrupts */
6
  ints = LPC_ETHERNET->DMA_STAT;
7
8
  /* Clear pending interrupts */
9
  LPC_ETHERNET->DMA_STAT = ints;
10
}

hat jemand vielleicht eine Idee, warum die NVIC-Sequenz manchmal 
funktioniert und manchmal (=häufig) nicht?
Oder gibt es für die Initialisierung des NVIC besondere Hinweise, die 
ich nicht beachtet habe?

vielen Dank.
 Rene.

von Marc P. (marcvonwindscooting)


Lesenswert?

Freeze des Systems? Hast Du einen oder 2 cores laufen?
Den M0 fuer das Ethernet-Zeugs?
Der M4 core 'funkt' rein?

Generell finde ich so ein asynchrones Verwerfen von interrupt requests 
unschoen. Wenn ich mir jetzt noch vorstelle, dass das der andere core 
macht, dann bekomm ich eine Gaensehaut. Bei mir wuerde das nie klappen, 
da waere immer ein Denkfehler drin.

Hab ich das im Manual richtig verstanden, der NVIC des M0 hat die 
gleiche Adresse wie der NVIC des M4, der Unterschied, ist mit welchem 
core man zugreift??

: Bearbeitet durch User
von Rene F. (fook)


Lesenswert?

Marc P. schrieb:
> Freeze des Systems? Hast Du einen oder 2 cores laufen?
> Den M0 fuer das Ethernet-Zeugs?
> Der M4 core 'funkt' rein?

hab den M4 für das Ethernet - der M0 macht garnichts mit Interrupts, 
lediglich ein bisschen IPC zwischen den beiden, aber zu dem Zeitpunkt 
der Initialisierung ist der noch garnicht aktiv :-/

> Generell finde ich so ein asynchrones Verwerfen von interrupt requests
> unschoen. Wenn ich mir jetzt noch vorstelle, dass das der andere core
> macht, dann bekomm ich eine Gaensehaut. Bei mir wuerde das nie klappen,
> da waere immer ein Denkfehler drin.

das "Verwerfen" (du meinst sicher der ClearPendingIRQ-Aufruf) findet wie 
gesagt nur beim Startup des Systems statt und sollte doch wohl erlaubt 
sein, solange ich die Interruptquelle abgeschaltet habe (DisableIRQ).

> Hab ich das im Manual richtig verstanden, der NVIC des M0 hat die
> gleiche Adresse wie der NVIC des M4, der Unterschied, ist mit welchem
> core man zugreift??

Ja.. so liest es sich und auch die Routinen sind die gleichen - aber ich 
habe im M0 eben keine EthernetFunktionalität und nur der M4 soll auf die 
Interrupts reagieren...

Irgendwie seltsam, dass es mal geht und beim nächsten Reset schon 
nichtmehr.

von Marc P. (marcvonwindscooting)


Lesenswert?

Also Freeze = keine Ethernet Interrupts mehr!?

Kannst Du sicherstellen dass sich nicht einfach der PHY verschluckt hat?
(Mutwillig Interrupt setPend() ).
Ich hatte da vor Jahren mal ein Problem, da hat sich der PHY einfach zur 
Ruhe gesetzt und ohne 'Strom weg und wieder dran' wollte der partout 
nicht mehr.

Hast Du mal den M0 deaktiviert?
Du hast doch f"ur 'nen Zufallsgenerator - um einen solchen handelt es 
sich ja leider - gar nicht so viele Moeglichkeiten. Da w"aren der PHY 
(mit der Aussenwelt) und vielleicht der M0 als asynchrone 
'Signalquellen'. Der Rest ist wohl voellig deterministisch.
Wahrscheinlich verrutscht sogar der Fehler an eine andere Stelle, nicht 
die NVIC-Sequenz oder verschwindet fuer 'ne Weile ganz. Hattest Du noch 
andere 'Ungereimtheiten' zuvor?

von holger (Gast)


Lesenswert?

Also Pending IRQs würde ich nur im Interrupt selber
löschen. Da springt er ja eben auch hin wenn es was
zu tun gibt.

Ansonsten könntest du mal ein knallhartes
1
__disable_irq();
2
...tu was...
3
__enable_irq();

versuchen.

von Rene F. (fook)


Lesenswert?

Marc P. schrieb:
> Also Freeze = keine Ethernet Interrupts mehr!?

Freeze heisst, er macht nicht weiter im Code - also richtig blockierend 
sobald die Zuweisung auf das NVIC->ISER-Register stattfindet...
Hatte es mit einer Debug-Ausgabe davor und dahinter festgestellt (debug 
= gpio-pin-toggle).

In die Ethernet-Interrupt-Routine (das hatte ich ja auch gedacht), kommt 
er dabei nicht...
andere Interrupts? - möglich, aber wie gesagt, da ist es schwierig, 
festzustellen, welche andere Routine nun blockieren sollte, zumal es ja 
jedesmal direkt mit der Zuweisung auf den NVIC zu tun hat.

> Kannst Du sicherstellen dass sich nicht einfach der PHY verschluckt hat?
> (Mutwillig Interrupt setPend() ).

probiere ich morgen mal..

> Ich hatte da vor Jahren mal ein Problem, da hat sich der PHY einfach zur
> Ruhe gesetzt und ohne 'Strom weg und wieder dran' wollte der partout
> nicht mehr.

seltsam ist dann nur, dass ein Reset-Signal am Cortex und ein Neustart 
des Systems manchmal hilft und sich alles in Wohlgefallen auflöst...
den Phy hab ich dabei garnicht separat resettet.

> Hast Du mal den M0 deaktiviert?

.. todo.. morgen :)

[...]
> Hattest Du noch andere 'Ungereimtheiten' zuvor?

in der Tat habe ich schon beobachtet, dass auch meine 
InterProcessorCommunication (IPC) nicht immer reibungslos funktioniert. 
Hatte die Beispiel-Implementierung von NXP benutzt - und die sollte ja 
eigentlich auch laufen.. Aber es passiert bei 1:20 Nachrichten, dass das 
Message-Interrupt-Signal (was durch den folgenden Code auf dem jeweils 
anderen Core erzeugt wird) nicht ankommt.
1
  __DSB();
2
  __SEV();

von Rene F. (fook)


Lesenswert?

bin einen Schritt weiter:

das Deaktivieren des anderen Cores hatte keinen Effekt - war ansich auch 
klar, da er nicht mit dem EthernetIRQ zu tun hat.

Das Problem habe ich nun insofern eingrenzen können, dass tatsächlich 
dauerhaft ein IRQ erzeugt wird, der den Chip eben auch dauerhaft in der 
IRQ-service-routine zum Ethernet hält - da war ich etwas voreilig beim 
ersten Test, aber so wie es aussieht, wird direkt nach Beendigung der 
Routine gleich wieder ein IRQ ausgelöst und ich komme nicht ins 
Hauptprogramm zurück.

Die Quelle habe ich nun bis zum "Receive buffer unavailable"-Interrupt 
zurückverfolgt - was bedeutet, dass dauerhaft versucht wird, einen 
Empfangsbuffer zu belegen, der aber nicht verfügbar ist.

Seltsam nur, dass der Speicher ja doch manchmal ausreichend zu sein 
scheint und dieser Fehler nicht auftritt :( ...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.