• Hallo,


    gibt es die Möglichkeit, einen, z.B. von einem externen I2C - Baustein gelieferten, Interrupt auf das Picomod1 - Board zu legen? Ziel ist es eine I2C - Matrixtastatur auszulesen, ohne dass diese andauernd gepollt werden muß.


    Schöne Grüße
    Manfred Domandl
    InterCard

  • Benutzen Sie einfach einen der GPIOs. Für die GPIO-Pins gibt es Routinen zur Behandlung von Interrupts.


    Mit freundlichen Grüßen,


    H. Keller

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Hallo Herr Keller,


    ich versuche gerade die Interrupt-Steuerung in Griff zu bekommen. Dabei steigt der DeviceIoControl mit Fehler 87 aus. Welche Parameter muß ich beim Picomod1 - Starterkit - Board mitgeben:

    Code
    1. DWORD dwIRQ = 42; // Port 2 Pin 40
    2. m_dwSysIntr=SYSINTR_EXTIO;
    3. if(!DeviceIoControl(hDIO1, IOCTL_DIO_REQUEST_SYSINTR, &dwIRQ, sizeof(DWORD), &m_dwSysIntr, sizeof(DWORD), NULL, NULL ) )
    4. return false;



      [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\DIGITALIO]
      "IRQCfg2A"=dword:00000000
      "IRQCfg1A"=dword:00000000
      "UseAsIOA"=dword:00040000
      "IRQCfg0A"=dword:00040000
      "DataInitA"=dword:00000000
      "DataDirA"=dword:00000000
      "UseAsIOB"=dword:00000000
      "Prefix"="DIO"
      "Dll"="DIGIO.dll"
      "Order"=dword:00000097
      "Index"=dword:00000001
      "Ioctl"=dword:00000004
      "Port"=dword:00000001
      "DataDirB"=dword:00000000
      "DataInitB"=dword:00000000
      "FriendlyName"="Digital I/O driver for PicoMOD1"



    Schon im Voraus vielen Dank für Ihre Hilfe.


    Schöne Grüße
    Manfred Domandl
    InterCard

  • Quote from "Domandl"

    DWORD dwIRQ = 42; // Port 2 Pin 40


    42 ist zwar die Antwort auf die Frage nach dem Leben, dem Universum und allem (siehe "Per Anhalter durch die Galaxis"), aber leider klappt das so universell nicht bei der PicoMOD1. Hier muss dann doch die korrekte Bitnummer des Pins mitgegeben werden. Pin 40 liegt laut DeviceDriver-Doku auf Bit 18, wie Sie ja auch schon in den Konfigurationswerten bei UseAsIOA u.ä. korrekt eingestellt haben. Also müssen Sie dwIRQ = 18 angeben.


    Mit freundlichen Grüßen,


    H. Keller

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Hallo Herr Keller, :-)


    herzlichen Dank für die Antwort. Dec 24 als IRQ funktioniert.


    Kann der GPIO5 beim Starterkit verwendet werden als DIO? Die Dokumentationen geben da unterschiedliches an (Picomod1_Startinterface_deu.pdf + Picomod1_DeviceDriver_eng.pdf)?


    Schöne Grüße
    Manfred Domandl
    InterCard

  • Quote from "Domandl"

    Dec 24 als IRQ funktioniert.


    Was mich nun wieder irritiert, da ich eigentlich dezimal 18 gemeint hatte, nicht hex 18.


    Quote

    Kann der GPIO5 beim Starterkit verwendet werden als DIO? Die Dokumentationen geben da unterschiedliches an (Picomod1_Startinterface_deu.pdf + Picomod1_DeviceDriver_eng.pdf)?


    Sie müssen unterscheiden zwischen den Bezeichnungen einzelner Stecker auf dem Starterkit und den Bezeichnungen auf dem Verbindungsstecker auf der PicoMOD1. In der DeviceDriver-Doku werden *nur* die Bezeichnungen des PicoMOD1-Steckers verwendet.


    Der Pin GPIO5 vom GPIO-Stecker des Starterkits liegt bei der PicoCOM1 selbst auf Pin24. Und den können Sie sehr wohl im Device-Treiber konfigurieren: Port 1, Bit 1.


    Mit freundlichen Grüßen,


    H. Keller

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Hallo Herr Keller,


    das mit dem IRQ ist mir nun klar. Bit 9 Port 1 (GPIO5) und daher muß, wenn ich es richtig verstanden habe, der IRQ = 9 (dec) sein, was auch funktioniert.
    Es klappt nun, dass ich den GPIO5 auslese, nur Interrupt bekomme ich keinen. Anbei der Code und die Registry. Vielleicht erkennen Sie den Fehler....




      [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\DIGITALIO]
      "UseAsIOA"=dword:00000200
      "IRQCfg0A"=dword:00000200
      "IRQCfg1A"=dword:00000000
      "IRQCfg2A"=dword:00000000
      "DataInitA"=dword:00000000
      "DataDirA"=dword:00000000
      "UseAsIOB"=dword:00000000
      "Prefix"="DIO"
      "Dll"="DIGIO.dll"
      "Order"=dword:00000097
      "Index"=dword:00000001
      "Ioctl"=dword:00000004
      "Port"=dword:00000001
      "DataDirB"=dword:00000000
      "DataInitB"=dword:00000000
      "FriendlyName"="Digital I/O driver for PicoMOD1"

  • Hallo,


    ich habe nun in den Code einen ReadFile eingebaut und dem WaitForSingleObject 1 mitgegeben. Immer wenn ich ein Signal anlege wird mir das auch ausgegeben, aber es wird kein Interrupt bzw. kein Event erzeugt. Wenn ich dem WaitForSingleObject INFINITE mitgebe, kommt er nicht mehr daraus zurück, egal ob ein Signal anliegt oder nicht. Ich vermute deshalb stark ein Konfigurationsproblem. Interrupt auf GPIO5 funktioniert doch auf dem PICOMOD1 Starterkit, oder?
    Was ist noch falsch an der Konfiguration (Registry)?


    Schöne Grüße
    Manfred Domandl
    InterCard

  • Zuerst mal muss der InterruptDone() mit in die Schleife rein. Jedesemal wenn WaitForSingleObject() mit WAIT_OBJECT_0 zurückkehrt, muss InterruptDone() aufgerufen werden. Ohne das bekommen Sie nur einen einzigen Interrupt und dann nie wieder.


    Was Sie stattdessen vor dem IOCTL_DIO_RELEASE_SYSINTR machen müssen, ist ein Aufruf der Funktion InterruptDisable().


    Mit freundlichen Grüßen,


    H. Keller

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Hallo Herr Keller,


    herzlichen Dank für die Info. Nun funktioniert alles!


    Noch eine letzte Frage zum Interrupthandling. Gibt bezüglich dem Interrupthandling irgendwelche Besonderheiten, bei Ihrer Implementierung im Kernel zu den Picomodboards, oder kann ich dazu auf die übliche CE Literatur (MSDN etc.) zurück greifen?


    Schöne Grüße
    Manfred Domandl
    InterCard

  • Eigentlich ist es in WindowsCE gar nicht gedacht, dass ein Anwenderprogramm selbst Interrupts verarbeitet. Das ist also eine Besonderheit von uns, dass dies überhaupt geht. Eigentlich soll auf Interrupts nur in Rahmen von Treibern reagiert werden. Der Grund hierfür ist, dass Micorsoft eigentlich davon ausgeht, dass eine WindowsCE-Plattform eigentlich keine offene Plattform ist, sondern zur Entwicklung für ein spezielles Gerät verwendet wird und die Entwickler den Platform-Builder zur Verfügung haben und somit selbst Treiber entwickeln können. Wir bei F&S wollen aber diese niederen Dinge dem Kunden abnehmen und bereiten Treiber und Einstellungen in entsprechend vorkonfigurierten Kerneln vor. Somit kommt der Kunde ohne Platform-Builder aus.


    Leider macht Microsoft uns hier immer mehr einen Strich durch die Rechnung. So ist dieses Konzept, wie wir das hier machen, schon unter Windows CE 6.0 nicht mehr möglich. Wir sind gerade dabei, hier ein allgemeingültiges Konzept zu erarbeiten, wie man das doch irgendwie allgemeingültig und zukunftssicher hinkriegt.


    Insofern vermute ich, werden Sie in der allgemeinen WindowsCE-Literatur zum Thema Interrupts nicht fündig. Da müssen Sie schon eher Richtung Gerätetreiber-Entwicklung (Device Driver) suchen.


    Mit freundlichen Grüßen,


    H. Keller

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Hallo Herr Keller,


    nochmals Fragen zum Interrupthandling:


    Hintergrund:
    Unsere Terminals (in Zukunft Picomodboards) werden an Kopierer angeschlossen.
    Die Kopiermaschinen erzeugen pro Kopie Signale. In diesen Signalen sind dann auch Formate
    über sogenannte Pulspakete verschlüsselt. Das Terminal muß also den entsprechenden Eingang
    abscannen und die anliegenden Impulse zählen und auswerten.
    Wir stehen nun vor der Entscheidung, ob das Picomodboard die Zählung übernehmen soll, oder ein
    Extra Pic - Baustein mit eingebaut werden muß.


    Versuchsaufbau:
    Bei unserem Versuchsaufbau wurde an den GPIO5 ein Signalgenerator angelegt, der die Signale einer
    Kopiermaschine simuliert. Die Signale erzeugen dann einen Interrupt. In der Interrupt-Handling-Routine
    wird nun ein anderer Pin des GPIO - Ports umgeschaltet. Dieses Signal wird über ein Oszilloskop angezeigt.
    (Programmcode ist angehängt).


    Ergebnis:
    Es zeigte sich, dass das Antwortsignal um ca. 50 - 200 µs (manchmal auch mehr) jittert.


    Fragen:
    Warum ist das so, wie kommt es dazu?
    Kann eine Vorhersagen zu den Antwortzeiten getroffen werden?
    Wie wird ein GPIO-Eingangssignal zu einem Interrupt?
    Können die Registry-Einstellungen oder sonstige Einstellungen (welche?) das Ergebnis verändern?
    Können die Prioritäten Auswirkungen auf das Ergebnis haben? Sollte im Programmbeispiel nicht, da höchste Priorität.


    Schon im Voraus herzlichen Dank für Ihre Hilfe.


    Schöne Grüße
    Manfred Domandl
    InterCard



  • Ein Interrupt wird im Kernel durch eine Interrupt-Handler-Funktion abgearbeitet. Je nach aufgetretenem Interrupt wird der entsprechend damit assoziierte Event gesetzt. Dann wird der Scheduler aufgerufen. Gibt es hierdurch nun einen höherpriorisierten Thread, der lauffähig geworden ist, wird sofort zu diesem Thread gewechselt. Wenn nicht, wird am gerade aktuellen Thread weiter gearbeitet, bis dessen Zeitscheibe um ist.


    Man sieht also, dass die Reaktionszeit einzig und allein von der Priorität abhängt, die der zugehörige Interrupt Service Thread (IST, also Thread3 in Ihrem Beispiel) hat. Indem man diesem Thread eine sehr hohe Priorität gibt, kann man fast 100% sicher sein, dass alle Impulse auch tatsächlich empfangen werden, vorausgesetzt sie kommen nicht schneller als die reine Abarbeitungszeit des Codes in diesem Thread.


    Die von Ihnen gemessene Verzögerungszeit addiert sich also aus folgenden Teilwerten auf.


    • Dauer, bis tatsächlich der Interrupt hardwaretechnisch abgearbeitet wird, also z.B. bis alle Register gesichert sind
    • Abarbeitung des kernelinternen Interrupt-Handlers, der die Interruptquelle herausfinden und den zugehörigen Event finden und setzen muss
    • Laufzeit des Schedulers, der eine Neubewertung der Prioritäten vornehmen und Ihren IST aktivieren muss; sprich es findet ein Threadwechsel statt
    • Laufzeit des Codes in Ihrem IST, bis letztendlich der andere Pin geschaltet ist, also z.B. die Laufzeit von DeviceIoControl(), die wegen dem Wechsel zum DIO-Treiberkontext nicht zu vernachlässigen ist


    Der Jitter, also die Schwankung der Zeit bis zum Sichtbarwerden des Signals auf dem zweiten Pin, ergibt sich daraus, dass es noch höher priorisierte Threads als Ihren Thread3 gibt. Denn anders als beim Desktop-Windows gibt es unter Windows CE 256 verschiedene Prioritätsstufen. Und mit THREAD_PRIORITY_TIME_CRITICAL sind sie noch lange nicht auf höchster Priorität. Sie sind noch irgendwo weit über 200 (große Werte bedeuten niedrige Priorität). Die internen Treiber laufen jedoch üblicherweise auf einer Priorität um die 100 und sind damit noch deutlich höher priorisiert. Dadurch kommen diese vor Ihrem Zählthread zum Zuge. Je nach externen Events, also z.B. Traffic auf dem Ethernet, kann also ihr Code tatsächlich noch mehr oder weniger stark ausgebremst werden.


    Probieren Sie mal, Ihrem Thread z.B. eine Priorität von 90 zu geben. Dann sollte der Jitter weg sein.


    Mit freundlichen Grüßen,


    H. Keller

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Guten Morgen Herr Keller,


    herzlichen Dank für die ausführliche und aufschlussreiche Antwort.


    Das Thema Prioritäten ist hierbei wohl sehr wichtig.
    Der define für "THREAD_PRIORITY_TIME_CRITICAL" lautet folgender maßen:
    #define THREAD_PRIORITY_TIME_CRITICAL 0.


    Besser als 0 geht doch nicht, oder verwechsle ich da was?


    Schöne Grüße
    Manfred Domandl
    InterCard

  • Quote from "Domandl"

    #define THREAD_PRIORITY_TIME_CRITICAL 0.


    Besser als 0 geht doch nicht, oder verwechsle ich da was?


    Da haben Sie nun wieder recht. Normal sind diese Werte nur für die Funktion SetThreadPriority() gedacht und da wird THREAD_PRIORITY_TIME_CRITICAL auf die Priorität 248 gemapped. Sie Haben aber ja die Funktion CeSetThreadPriority() verwendet, wo die 0 direkt gesetzt wird. Ja, höher priorisiert als das geht es tatsächlich nicht. Warum sich dann so ein Jitter einstellt, kann ich auch nicht sagen.


    Das heißt, haben Sie schon mal überprüft, ob Sie überhaupt jeden Interrupt mitkriegen, oder ob da welche fehlen? Weil wenn mal ein Interrupt ausgelassen wird, könnte das so einen Jitter auch erklären. Triggern Sie auf Flanke oder Level?


    Mit freundlichen Grüßen,


    H. Keller

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Hallo Herr Keller,


    ob ich jeden IRQ bzw jedes Signal messe hängt von der Frequenz ab, in der das Signal gesendet wird. Das oben beschriebene Ergebnis bezieht sich auf eine Frequenz, bei der jedes Signal gezählt bzw. von der Software gemessen wird.


    Wenn ich die Konfiguration (IRQA0 gesetzt) richtig interpretiere, dann Triggere ich auf Rising Edge.


    Schöne Grüße
    Manfred Domandl
    InterCard

  • Hmm, ich habe mich vielleicht falsch ausgedrückt. Es geht darum, ob die Anzahl extern erzeugter Interrupts und die Anzahl durchs Programm gezählter Interrupts identisch ist, und zwar möglichst bei einer Frequenz gezählt, wo die PicoMOD1 auf jeden Fall noch mitkommen sollte, also ca. 100 Hz bis 1 kHz.


    Warum ich hier nachfrage: wir hatten bei der NetDCU8, die den gleichen Prozessor einsetzt wie die PicoMOD1, auch schon den Verdacht, dass hier hardware-mäßig hin und wieder kantengetriggerte Interrupts verloren gehen. Dort haben wir dann die interne Interruptverarbeitung umgestellt und kantengetriggerte Interrupts durch levelgetriggerte Interrupts emuliert. Seitdem haben die Kunden von keinen Problemen mehr berichtet.


    Ich bin mir momentan aber nicht ganz sicher, ob diese Änderung nun auch schon Einzug in den PicoMOD1-Kernel gefunden hat. Wenn nein, wäre dies nun vielleicht ein weiterer Nachweis, dass es bei kantengetriggerten Interrupts tatsächlich Probleme gibt und man hier auch tunlichst diese Emulation einbauen sollte.


    Mit freundlichen Grüßen,


    H. Keller

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Hallo Herr Keller,


    nö, Sie haben sich richtig ausgedrückt. Genau so habe ich getestet.


    Wie können diese levelgetriggerten Interrupts emuliert werden? Kann ich da was machen?


    Schöne Grüße
    Manfred Domandl
    InterCard

  • Hallo Herr Keller,


    wie sind die nächsten Schritte bezüglich des Jitters und den levelgetriggerten Interrupts?


    Schon im Voraus herzlichen Dank für die Info.


    Schöne Grüße
    Manfred Domandl
    InterCard

  • Wenn Sie bei einer halbwegs niedrigen Frequenz alle Interrupts zählen, also keinen verlieren, dann ist es kein Problem der internen Interruptverarbeitung. Meine Theorie für den Jitter war ja, dass hier und da ein Impuls verloren geht und darum erst der nächste Interrupt erkannt wird und sich so mal ein kleinerer Abstand (alle Interrupts erkannt) und mal ein größerer Abstand (wenn ein Impuls verloren ging) bildet. Wenn Sie aber alle Impulse zählen, ist doch alles OK. Nur dann habe ich nun auch so langsam keine Erklärung mehr für das Zustandekommen des Jitters. Kann es ganz banal sein, dass Priorität 0 einfach nicht erlaubt ist und entsprechend der Thread gar nicht auf hoher Priorität läuft? Probieren Sie mal noch einen Wert von 10. Der nächste Treiber dürfte eigentlich erst in der Gegend von 100 kommen, insofern wäre 10 immer noch absolut höchste Priorität.


    Dass ab irgendeiner höheren Frequenz dann Impulse verloren gehen, ist normal, da dann das Board aufgrund der von mir schon mal genannten Verzögerungen bzw. der reinen Laufzeit des Codes einfach nicht mehr mitkommt, die Interrupts zu verarbeiten. Sprich es kommt schon der nächste Interrupt, während noch der vorherige verarbeitet wird. Dieser neue Impuls geht dann verloren.


    Solange Sie also alle Impulse empfangen, brauchen wir nichts in Richtung emulierter Flanken-Interrupts machen. Das wäre sowieso eine Änderung im Kernel, da können Sie selbst leider nicht helfen.


    Mit freundlichen Grüßen,


    H. Keller

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.