- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 9 von 9

Thema: Cortex M3 unerklärliches Interrupt Verhalten

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076

    Cortex M3 unerklärliches Interrupt Verhalten

    Ich habe ein Problem mit dem LPC1768 Timer generell:
    Ich habe den Timer so initialisiert, daß er jede milli Sekunde aufgerufen wird.
    Im Timerinterrupt drehe ich lediglich ein Portbit um, damit ich mit dem Ossi messen kann ob das Timing stimmt.
    Das Timiung stimmt absolut. Da ich das Portbit bei jedem Interrupt umdrehe XOR müste aber ein symetrisches Rechteck herauskommen.
    Aber, es kommt eine 650 nano Sekunden Flanke gefolgt von dem Rest der gewünschten einen milli Sekunde heruas.
    Ähnlich einer extrem schmalen PWM. Wenn ich die letzte blödsinnige Zeile x-- mit reinkompiliere geht es einwandfrei.
    Wo ist denn da der Zusammenhang. Ich Suche schon den ganzen Tag.
    Erstaunlich aber auch, wenn ich zuerst das Interrupt Bit MR0INT lösche und dann das Portbit umdrehe geht es auch ohne das
    blödsinnige x--. Der Zusammenhang ist mir bisher nicht erklärlich.
    ich kann aber statt x-- auch for (x=0; x < 100; x++) ; benutzen, dann geht es auch wieder richtig.
    Der eigentliche Code scheint also keine Rolle zu speilen, Hauptsache da kommt noch was.
    Ich kann das Interruptbit auch 2 mal löschen dann geht es auch wieder richtig.
    Es sieht so aus, als wenn der Prozossor es nicht mag, wenn als letzte Aktion in der Interrupt Routine das entsprechende
    Interruptbit gelöscht wird. Ich habe es auch mit den Timern 1 2 und 3 probiert, die verhalten sich alle gleich "falsch"
    Steht ein Stück Progrmmcode hinter dem Löschen des Interruptbits ist alles in Ordnung.


    Code:
    int x;
    
    void TMR3_IRQHandler (void)
    {
    
      LPC_FIO1PIN.value   ^= 2;    /* Portbit umdrehen (Oszilloskope Signal) */
      LPC_T3IR.bits.MR0INT = 1;    /* Interrupt Bit loeschen */                 
    
      x--;     /* voelliger Blödsinn, aber ohne geht es nicht richtg ??????? */
    }
    Ein bischen Google und das Problem wurde mir tatsächlich exakt so bestätigt.
    Ganz egal ob NXP oder Analog Devices, der Cortex M3 Kern ist schuld. Das ist jetzt aber nicht negtiv gemeint.
    Ein "DSB" Befehl "Data Synchronization Barrier" als letzter Befehl wirkt Wunder.
    Hiermit wird sichergestellt, daß alle Speicherzugriffe komplett erledigt sind bevor ein neuer Befehl eingeleitet wird.
    Also entweder das Interruptbit NICHT als LETZTES löschen dann z.B. mittels "DSB" Befehl dafür sorgen, das alles reibungslos abläuft.
    Ich hätt mal vorher googlen sollen, aber dafür bin ich stolz es selbst gefunden zu haben.

    Bei IAR Embedded Workbench kann ich den DSB Befehl in der C-Source-Datei so eingeben:

    __asm("DSB"); /* Data Synchronization Barrier */


    ein schönes Wochenende wünsche ich allen.
    Siro
    Geändert von Siro (01.07.2011 um 14:24 Uhr)

  2. #2

    Rtfm

    Tja, ich hole Dich nur ungern aus Deinen Träumen, aber...

    RTFM gilt leider auch hier.
    Ich weiß, daß es mühselig ist, wenn man sich die diversen Datenblätter und Handbücher zum M3 und dann auch noch zum jeweils ausgesuchten Hersteller und Derivat durchlesen muss. Das ist immerhin eine vierstellige Anzahl von Seiten.
    Viele unterlassen das dann und wundern sich dann, wenn solche Effekte wie bei Dir auftreten.
    Dabei sind diese Effekte keine "Probleme", sondern schlicht gewollte Features.
    Und Dein Lösungsvorschlag funktioniert auch nur zufällig, Du hast nämlich die eigentliche Ursache nicht verstanden...

    Hier also die Lösung von einem, der die Handbücher gelesen hat:
    NXP (aber auch andere Anbieter) baut bei seinen LPCs einen Puffer in die APB Bridges. Das machen die, damit die CPU (und DMA) auf APB Devices schreiben können, ohne darauf zu warten, bis der Schreibvorgang zu Ende ist. Das erhöht die durchschnittliche Performance des MCs.
    In Deinem Fall entsteht dadurch das Problem, daß die CPU den Interrupt bereits beendet hat, bevor der Schreibvorgang auf das Register beendet wurde. Durch den DSB-Befehl reicht dann die Zeit zufällig aus, den Schreibvorgang zu beenden.
    Problematisch dabei ist, daß der Schreibpuffer außerhalb des M3-Cores ist. Dadurch bekommt der Core nicht mit, wann der Schreibvorgang abgeschlossen ist und der DSB-Befehl nutzt rein gar nichts. Bei anderer, langsamerer Peripherie ist es also durchaus möglich, daß die Zeit für die Ausführung des DSB-Befehls nicht ausreicht um den Schreibvorgang zu beenden und wieder für einen "unbedarften" Nutzer Seiteneffekte entstehen.

    Also nochmal mein Tip an alle M3-Nutzer:
    Lest Euch die Handbücher und Datenblätter durch!
    Der Cortex-M3 - so einfach der einem beim ersten Ansehen auch erscheinen mag - ist ein komplexes Stück Hardware, welches durchaus so seine Eigenheiten hat. Und die erkennt man nur durchs Datenblatt-Lesen.

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Habe ich da etwas falsch verstanden ? Kann ja sein, ich beziehe mich mal auf folgenden Link:

    http://infocenter.arm.com/help/index.../CHDDGICF.html

    #DSB acts as a special data synchronization memory barrier. Instructions that come after the DSB, in program order, do not execute until the DSB instruction completes. The DSB instruction completes when all explicit memory accesses before it complete.

    oder hier: CortexM3_TRM.pdf Kapitel 14.9 Write Buffer:
    DMB and DSB instructions wait for the write buffer to drain before completing

    Ich habe es so verstanden: Es werden erst alle vorigen Schreibzugriffe erledigt, dann gehts weiter.
    Wenn ich hier tatsächlich falsch liege, bitte ich um nähere Erklärung.

    mfg. Siro
    Geändert von Siro (11.07.2011 um 12:43 Uhr)

  4. #4
    Zitat Zitat von Siro Beitrag anzeigen
    Habe ich da etwas falsch verstanden ? Kann ja sein, ich beziehe mich mal auf folgenden Link:

    http://infocenter.arm.com/help/index.../CHDDGICF.html

    #DSB acts as a special data synchronization memory barrier. Instructions that come after the DSB, in program order, do not execute until the DSB instruction completes. The DSB instruction completes when all explicit memory accesses before it complete.

    oder hier: CortexM3_TRM.pdf Kapitel 14.9 Write Buffer:
    DMB and DSB instructions wait for the write buffer to drain before completing

    Ich habe es so verstanden: Es werden erst alle vorigen Schreibzugriffe erledigt, dann gehts weiter.
    Wenn ich hier tatsächlich falsch liege, bitte ich um nähere Erklärung.

    mfg. Siro

    Den Teil hast Du richtig verstanden.
    Was Du nicht verstanden hast, ist, daß NXP (und andere) in ihre Peripherie auch Schreibpuffer einbauen.
    Und diese sind dem M3-Kern nicht bekannt. Insofern kann ein DSB-Befehl auch nicht wissen, wann diese Puffer weggeschrieben sind. Und darum ist Dein Vorschlag hier falsch.
    Der DSB-Befehl nutzt nur bei Operationen im Kern etwas. Beispiele finden sich in der ARM-Literatur ja zu Hauf.

    Joseph Yiu, der Autor vom Buch "The Definitive Guide to the ARM Cortex-M3" schreibt zu dem Thema übrigens folgendes:

    Normally the Cortex-M3 wait until the previous write is completed before the interrupt return. However, some microcontrollers has a write buffer in the peripheral bridge. The write buffer accelerates single write transfers to peripherals so that the processor don't have to wait until the transfer is done (peripheral bus might be running at slower clock speed).

    However, for clearing an interrupt request, the write buffer reply to the processor that transfer is done, while the actual write transfer actually haven't been completed in the peripheral. So the processor executed interrupt return, and found that the interrupt request from the peripheral is still high and think that it is a new interrupt request.

    Adding memory barrier instruction (e.g. DSB) doesn't always help because the buffer is outside the processor. But it might introduce just enough delay to allow the interrupt to be cleared.
    Calling a function to clear the interrupt pending register NVIC also introduce some extra clock cycles of delay. So the interrupt request is deasserted when interrupt return is executed.

    Another way to solve this problem is to carry out a dummy access to the peripheral, e.g. a read access to the same peripheral, to ensure that the previous write is completed before executing the interrupt return.

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Ersteinmal vielen Dank für deine Informationen.
    Das leuchtet mir jetzt ein. Ich habe nicht damit gerechnet, daß die Peripherie, welche um den Kern gebaut wurde, ebenfalls Buffer beinhalten könnte. Das kann der eigentliche M3 Kern natürlich nicht wissen und damit nützt mir der DSB Befehl eigentlich nur insofern, daß etwas Zeit vergeht und lediglich sichergestellt ist, daß der Write Buffer der CPU fertig ist. Super, bin ich doch gleich wieder ein bischen schlauer geworden.

    "The Definitive Guide to the ARM Cortex-M3" scheint ein sehr gutes Buch zu sein, werde ich mir gleich besorgen. Das sind ja ganz wichtige Informationen, die man dem NXP Datenblatt nicht entnehmen kann.

    dankend Siro

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    21.12.2011
    Beiträge
    9
    Hallo Siro,
    sorry, wenn ich das Thema (auch) nochmal aufgreife. Wie hast du dein Problem denn gelöst?
    Der Timer-IRQ Request ist ja noch nicht gelöscht, wenn die Funktion zurückkehrt. Laut dem letzten Satz "Another way to solve this problem is to carry out a dummy access to the peripheral, e.g. a read access to the same peripheral, to ensure that the previous write is completed before executing the interrupt return. " müsste also das gleiche Register hinterher nochmal ausgelesen werden, um wirklich sicher zu gehen, dass der IRQ-Request auch gelöscht ist. Ich habe jetzt schon viel Beispielcode gesehn, aber sowas nicht.

    Gruß
    René

Ähnliche Themen

  1. Software Reset Cortex M3
    Von Siro im Forum ARM - 32-bit-Mikrocontroller-Architektur
    Antworten: 8
    Letzter Beitrag: 30.01.2011, 22:06
  2. ARM Cortex M3 KettenRoboter
    Von Pajonilaus im Forum ARM - 32-bit-Mikrocontroller-Architektur
    Antworten: 2
    Letzter Beitrag: 30.06.2010, 18:59
  3. Cortex M3 Ramfunction
    Von Siro im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 2
    Letzter Beitrag: 27.04.2010, 08:34
  4. Unerklärliches Zurücksetzen von Variablen im SRAM
    Von autoguider im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 9
    Letzter Beitrag: 04.10.2007, 15:07
  5. Antworten: 9
    Letzter Beitrag: 17.07.2006, 22:47

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen