Fehler im NI2C Treiber?

  • Hallo!


    Ich arbeite seit einiger Zeit an einer Applikation auf der NetDCU8, die intensiv die I2C Schnittstelle (NI2C Treiber) nutzt. Dabei ist immer wieder aufgefallen, daß sporadisch falsche Werte von Geräten am I2C Bus kommen. Dies ist unabhängig von der I2C Frequenz, vom angeschlossenen Gerät od. sonstigen Umständen, die ich nachvollziehen konnte.
    Erschwert wird die Fehlerlokalisierung dadurch, daß der Fehler oft 10 - 20 Minuten gar nicht eintritt. Generell tritt der Fehler nach subjektiven Schätzungen nur alle paar Minuten auf, aber da unsere Applikation sicherheitsrelevant ist, können wir gar keinen Schnittstellenfehler akzeptieren!


    Zur Verdeutlichung hier ein Testprogramm von mir, um den Fehler zu lokalisieren:



    Das Programm versucht in einer Schleife 5 Bytes von einem Gerät (AWG) über I2C zu lesen. Dieses Gerät sendet bei jeder Anfrage die selben 5 Bytes:
    0xFC, 0x01, 0x76, 0xFF, 0xFF
    Wenn ein Fehler auftritt, wird der Ausgang J5/2 für 1msec von 'H' auf 'L' geschaltet. Dieses Signal wurde genutzt um einen Oszilloskop zu triggern.
    Gemessen und ausgewertet wurden die I2C Signale SCLK und SDA kurz vor dem Triggerpunkt (== gelesener Fehler) und kurz danach (== korrekte Daten).
    Dadurch konnte man erkennen, daß KEINE falschen Daten über die I2C geschickt wurden (die gesendeten Daten waren korrekt), sondern der I2C Master (NI2C Treiber) generiert beim vorletzten gesendeten Byte kein ACK Signal, aber liefert trotzdem 5 gelesene Bytes aus. Diese 5 Bytes sind aber nicht korrekt. Beispiele für fehlerhaft gelieferte Daten z.B.:
    0x4B, 0xFC, 0x01, 0x76, 0xFF oder
    0x2C, 0xFC, 0x01, 0x76, 0xFF
    bei vielen Meßversuchen wurden aber schon alle möglichen falschen Daten geliefert, so daß man keine eindeutige Aussage über die falschen Daten machen kann.


    Im Testprogramm ist ein auskommentierter Bereich, der 4 Bytes von einem anderen I2C Gerät liest. Hier konnte ein ähnliches Fehlerbild beobachtet werden!
    Auffällig ist, daß die falsch gelesenen Daten meist den richtigen Daten um 1 Byte verschoben entsprechen!


    Nach den Erkenntnissen der umfangreichen Tests, die ich durchgeführt habe, ist eine Störung auf der I2C auszuschließen. Ebenso können wir einen Programmfehler unsererseits od. seitens der gelesenen Geräte ausschließen, da ein Kollege von mir einen eigenen I2C Treiber (in einer PIC, ohne die NetDCU) programmiert hat, der bei mehrstündigen Testläufen keinen einzigen Fehler dieser Art gesendet hat.
    Wir betreiben den I2C Bus mit 200kHz (andere Frequenzen verändern aber das Fehlerverhalten nicht) und haben keinen Touchscreen über die I2C angeschlossen.


    Als Beleg habe ich Oszilloskop Bilder vom korrekt gelesenen Datenblock und von fehlerhaft gelesenen Datenblöcken. Da ich diese hier aber nicht anhängen kann werde ich sie bei Interesse per E-Mail verschicken.


    In dem Beitrag:


    <!-- m --><a class="postlink" href="http://fs-net.de/phpBB2/viewtopic.php?t=691&highlight=ni2c">http://fs-net.de/phpBB2/viewtopic.php?t ... light=ni2c</a><!-- m -->


    wird auch von sporadischen I2C Fehlern gesprochen:


    "Was man immer wieder bemerken kann, ist, dass äußere Einflüsse die I2C-Übertragung beeinflussen können. So kommt es sporadisch immer mal wieder zu einem Übertragungsfehler, von dem sich das System aber nach spätestens 1 Sekunde erholt. "


    Evtl. ist der oben beschriebene Fehler auf den selben NI2C Treiber Bug zurückzuführen?




    Hat irgendjemand ähnliche Probleme mit der I2C Schnittstelle?
    Gibt es bereits Lösungen für dieses Problem?
    Ich brauche dringend eine Lösung, da unsere Applikation mit diesen Fehlern nicht leben kann!


    Vielen Dank für jede Hilfe,



    Gunther

  • Ich hätte einen möglichen Ansatzpunkt, wo eventuell in diesem Testprogramm etwas schief gehen könnte.


    Sie verwenden für SCHEDULE und GET_RESULT immer das gleiche Message-Header-Array msg_read_awg[], ohne dessen Inhalt jemals wieder aufzufrischen. Es wird nur zu Beginn des Programms global initialisiert. Der chFlags-Eintrag ist aber nicht nur ein Ausgangsparameter, sondern auch ein Eingangsparameter. Das heißt die Übertragung verhält sich anders, wenn bei chFlags der Wert 0 oder 1 übergeben wird. Und zwar genau dahingehend, ob die NetDCU beim Empfang das letzte Byte der Übertragung mit ACK quittiert oder nicht.


    Sie beginnen mit chFlags=0. Das heißt die NetDCU quittiert das letzte Byte beim Empfang *nicht*. Aber vermutlich sendet die Gegenstelle bei allen Bytes brav ein ACK, weshalb nach dem ersten Zyklus nun chFlags auf 1 steht. Da Sie diesen Wert nirgends zurücksetzen, wird nun im nächsten SCHEDULE auch mit chFlags=1 gearbeitet. Das heißt ab nun quittiert auch die NetDCU das letzte empfangene Byte mit ACK.


    Ich vermute nun, dass in einer Übertragung Ihr AWG irgendwann einmal beim letzten Byte kein ACK gesendet hat, vermutlich weil das Byte nicht ordentlich dort ankam. Dies wird nun mit chFlags=0 quittiert, so dass im nächsten Zyklus die NetDCU das letzte Byte nun wieder nicht mehr quittiert. Dies ist nun vermutlich der fehlerhafte Zyklus, den Sie sehen. Möglicherweise sehen Sie in Ihrem Oszilloskop-Bild aber gar nicht so weit zurück, dass Sie den tatsächlich fehlerhaften vorangegangen 6-Byte-Zyklus noch sehen, sondern nur den aktuellen, der Ihre fehlerhaften Daten enthält.


    Mein Vorschlag wäre darum, entweder für GET_RESULT ein anderes Array als bei SCHEDULE zu verwenden. Oder das Array in jedem Durchlauf vor dem SCHEDULE wieder neu vorzubelegen.


    Vielleicht sollten Sie mal darauf achten, ob in chFlags ab und zu unterschiedliche Werte (0 oder 1) zurückkommen. Bisher löst dies in Ihrem Testprogramm wegen Abfrage auf >1 noch keine unterschiedliche Behandlung oder gar einen Fehler aus. Auch wäre es interessant, was tatsächlich im Fehlerfall in chFlags stand, also welcher Fehler konkret auftrat. Und hier wäre wie gesagt auch der vorangegangene Zyklus noch interessant.


    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.

  • Vielen Dank für die schnelle Reaktion!


    Leider kann das nicht der Grund für den NI2C Fehler sein, da in unserer Applikation vor JEDEM SCHEDULE das Message Header Array komplett
    neu gesetzt wird und der selbe Effekt auftritt. Ich habe zur Vereinfachung im Testprogramm darauf verzichtet.


    Nun habe ich Ihre Vorschläge im Testprogramm übernommen:



    und den Testlauf wiederholt.
    Dabei wurden wieder die selben I2C Fehler (falsche Daten gelesen) angezeigt - OHNE daß ein chFlags Fehler angezeigt wurde!
    D.h. trotz der vorgeschlagenen Änderungen wird im Fehlerfall vom NI2C Treiber gemeldet, daß er 5 korrekte Bytes empfangen hat,
    obwohl diese 5 Bytes NICHT vom I2C Gerät gesendet wurden!
    Einfach gesagt: ich habe das Testprogramm über 1 Stunde laufen lassen und es ist NIEMALS eine Bedingung eingetreten, in der:
    msg_read_awg[0].chFlags != 1 ODER
    msg_read_awg[1].chFlags != 0
    war. Trotzdem wurde mehrmals ein Datenpacket empfangen, das definitiv NICHT vom I2C Gerät gesendet wurde!!!


    Außerdem haben wir bei den Messungen mit dem Oszilloskop mindestens 10 Schedules (je 8 Bytes) vor und nach dem Triggerpunkt aufgezeichnet
    und es war KEIN Fehler auf dem Oszilloskop erkennbar, der vor dem fehlerhaft gelesenen Packet aufgetreten ist.
    Zusätzlich habe ich in meinem Testprogramm eine printf(... Zeile, die bei einem Flag Fehler (if read_awg() != 0) einen Ausdruck auf den BS
    der NetDCU vornimmt und es wurde nie ein Flag Fehler angezeigt.


    Deshalb müssen wir weiterhin davon ausgehen, daß der NI2C Treiber hier ein Fehlverhalten hat.
    Wenn Ihnen die aufgezeichneten Oszilloskopbilder bei der Fehlerlokalisierung eine Hilfe wären, würde
    ich Ihnen diese gerne zuschicken (3 Bilder a ca. 2MBytes).




    Mit freundlichen Grüßen,


    Gunther Beck

  • Vielen Dank für ihre weiteren Tests. Dann liegt es offensichtlich nicht an dem, was ich vermutet hatte.


    Ich gehe auch davon aus, dass Sie die aktuellste Version 1.5 des NI2C-Treibers einsetzen.


    Ich fasse mal zusammen. Aus Sicht der chFlags läuft alles komplett fehlerfrei ab. Dennoch kommen hin und wieder Daten, die falsch sind, wobei es häufig ein Versatz um ein Byte ist. Auf dem I2C-Bus sieht hingegen alles völlig korrekt aus, die übertragenen Daten sind da noch korrekt. Die Fehler hängen nicht von der Datenrate 200 kHz ab, auch bei niedrigeren Datenraten tritt er auf.


    Ich muss sagen, ich bin baff. Was mich hier besonders stutzig macht ist die Tatsache, dass die NetDCU beim vorletzten Byte laut ihren Angaben kein ACK sendet. Wie das passieren kann, ist mir schleierhaft. Das kann laut Quelltext des Treibers gar nicht sein. Da kann ein fehlendes ACK nur beim letzten Byte der Message passieren.


    Vielleicht sollten Sie doch mal die Oszilloskopbilder senden.


    Sie könnten auch mal probieren, in der Registry zum I2C-Treiber [HKLM\Drivers\Builtin\I2C1] einen DWORD-Value "Debug" mit dem Wert 8 zu setzen. Dann werden bei ein paar Sonderfällen Meldungen auf der Debug-Schnittstelle ausgegeben. Vielleicht liefert uns das einen Hinweis.


    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.

  • Ja, wir setzten den NI2C Treiber Version 1.5 ein.


    Ich glaube Ihre Zusammenfassung ist nicht ganz korrekt, dehalb nochmals kurz:
    Aus Sicht der SW (NI2C Treiber) läuft alles korrekt, es werden 5 Nutzbytes empfangen, die chFlags stimmen exakt, es ist auch sonst kein Fehler erkennbar. Manchmal sind jedoch die Nutzdaten nicht korrekt. In diesem Falle kann man auf der I2C Schnittstelle (Hardware) erkennen, daß der I2C Master nur 4 Nutzbytes empfängt (fehlendes ACK), der SW Treiber meldet aber trotzdem für dieses Packet 5 korrekt Empfangene Nutzbytes.


    Ja, das Fehlerbild ist nicht abhängig von der Datenrate der I2C.


    Aus meinen Erkenntnissen in dieser Problematik würde ich vermuten, daß evtl. im Treiber der Puffer Zähler (Ringzähler?) einen Fehler macht und "glaubt" 5 Nutzbytes empfangen zu haben --> für den Treiber ist die Übertragung erledigt.
    Hier ein paar Beispiele von falsch empfangenen Datenpacketen. Oft ist dabei eine Verschiebung um 1 Byte zu erkennen! Deshalb glaube ich nicht, daß der Treiber ein Problem mit der Quittierung allgemein hat, ich vemute es ist nur ein Puffer bzw. Zähler Problem.


    Gemessene Fehlerbilder:


      AWG:
      first read AWG values: FF D8 EF : FF FF
      1. ERROR AWG: 4B FF D8 : EF FF [2897578]
      3. ERROR AWG: FF D8 63 : EF FF [2927852]
      5. ERROR AWG: 2F FF D8 : EF FF [3300477]
      7. ERROR AWG: 2F FF D8 : EF FF [4499492]


      first read AWG values: FF D8 EF : FF FF
      1. ERROR AWG: 4B FF D8 : EF FF [5515742]
      3. ERROR AWG: FF FF D8 : EF FF [6901405]


      first read AWG values: FF D8 EF : FF FF
      1. ERROR AWG: 4B FF D8 : EF FF [616984]


      first read AWG values: FF D8 EF : FF FF
      1. ERROR AWG: FF FF D8 : EF FF [266718]


      first read AWG values: FE 79 60 : FF FF
      1. ERROR AWG: 4B FE 79 : 60 FF [1370887]



      BusModul:
      first read modul values: FF FF 00 00
      1. ERROR modul: FF FF FF 00 [2270761]
      3. ERROR modul: FF FF FF 00 [2942835]


      first read modul values: FF FF 00 00
      1. ERROR modul: 49 FF FF 00 [6275535]
      3. ERROR modul: FF FF FF 00 [6304508]

      first read modul values: FF FF 00 00
      1. ERROR modul: FF FF FF 00 [264183]


      first read modul values: FF FF 00 00
      1. ERROR modul: FF FF FC 00 [495275]
      3. ERROR modul: 49 FF FF 00 [582248]


    Ich habe eine Debug Session geöffnet und das Testprogramm über 1 Stunde laufen lassen. Dabei sind wieder NI2C Fehler (ca. 20 Stck) aufgetreten, aber es wurde kein einziger Fehler im DCUTerm geloggt - obwohl ich Debug = 255 eingestellt hatte.
    Hier die Meldungen komplett, damit sie die Version und Frequenz der I2C erkennen können!



      Microsoft Windows CE Ethernet Bootloader Common Library Version 1.1 Built Sep 5 2006 16:56:30
      Microsoft Windows CE Bootloader for NetDCU8 Built Sep 5 2006
      Portions copyright (c) 2005 F&S Elektronik Systeme GmbH
      Boot Loader, Version 1.24
      StepStone Loader, Version N816


      Samsung: 256MBit (32MB)
      Create partition for boot section ... Success
      Create partition for kernel section ... Success
      Create partition for FFSDISK section ... Success
      System ready!
      Preparing for download...
      Press >S< to step into monitor...
      AUTO BOOT enabled
      Kernel read from flash disk started finished
      INFO: OEMLaunch: Jumping to Physical Address 0x30142738h (Virtual Address 0x80142738h)...



      Windows CE Kernel for ARM (Thumb Enabled) Built on Jun 24 2004 at 18:25:00
      ProcessorType=0920 Revision=0
      sp_abt=ffff5000 sp_irq=ffff2800 sp_undef=ffffc800 OEMAddressTable = 80142600
      NetDCU8 V1.20 - Firmware Init
      Copyright (c) 2005 F&S Elektronik Systeme GmbH
      Build: Oct 24 2006/19:16:52
      Hardware-Watchdog: ON
      KITL: OFF
      Samsung: 256MBit (32MB)
      Sp=ffffc7cc
      OEMIoControl: Unsupported Code 0x10100b4 - device 0x0101 func 45
      OEMIoControl: Unsupported Code 0x101008c - device 0x0101 func 35
      Samsung: 256MBit (32MB)
      OEM: Not cleaning system hive
      OEM: Not cleaning user profiles
      DM9CE: StationAddress [ 00-00-00-00-14-c5 ]
      DeviceFolder::LoadDevice!Enumerate Found deprecated load instructions at (Drivers\BuiltIn\AFD). Driver cannot be unloaded.DeviceFolder::LoadDevice!Enumerate Found deprecated load instructions at (Drivers\BuiltIn\PPP). Driver cannot be unloaded.OEMIoControl: Unsupported Code 0x10100d0 - device 0x0101 func 52
      OEMIoControl: Unsupported Code 0x10100f8 - device 0x0101 func 62
      MBD: ActiveKey (copy) = Drivers\Active\23 (@ 0x0005A270)
      PIF: ActiveKey (copy) = Drivers\Active\24 (@ 0x0005A670)
      CID: ActiveKey = Drivers\Active\26 (@ 0x0005CED0)
      SDIO: Reset ...ok
      SDHC: SetClockRate=100000
      NI2C: Version 1.5, ActiveKey = Drivers\Active\30
      NI2C: Debug = 0x000000ff = 255
      NI2C: ClockFreq = 0x00030d40 = 200000
      NI2C: Priority256 = 0x00000067 = 103
      NI2C: Interrupt service thread ID: 0x61dccc9e
      DIO: ActiveKey (copy) = Drivers\Active\31 (@ 0x0005DE70)
      AIN: ActiveKey (copy) = Drivers\Active\32 (@ 0x0005E220)
      Display-Mode: 3, Name SHARP LQ104V1DG11
      Width: 640 Height: 480 Bpp: 16
      OEMIoControl: Unsupported Code 0x10100fc - device 0x0101 func 63
      GetLCDcontrast: read contrast value: 0x1
      GetLCDcontrast: dwDefaultContrast=0x0, contrast=0x1
      Backlight mode can't be read from registry. Defaulting it to enabled state
      DispDrvrBacklightControl ON
      InitializeDisplayHardware Complete
      MATRIX: matrix keyboard is OFF.
      Lyg.p: Layout Manager successfully initialized to 2
      Maximum Allowed Error 7:
      Indicated RS232 Cable Event
      MSIM: IM_ReadRegistry read KB 5
      NI2C: Idle Timeout(0)
      Explorer(V2.0) taskbar thread started.
      AUTORAS:: Dialer notifies: [1] [Dialer Start]
      NDISPWR:: Found adapter [DM9CE1]
      NI2C: Idle Timeout(1)
      NI2C: Idle Timeout(2)
      Posting WM_NETCONNECT(TRUE) message
      AUTORAS:: Dialer notifies: [4] [Dialer Connected]
      NI2C: Idle Timeout(3)
      NI2C: Idle Timeout(4)
      NI2C: Idle Timeout(5)
      NI2C: Idle Timeout(6)
      NI2C: Idle Timeout(7)
      NI2C: Idle Timeout(8)
      NI2C: Idle Timeout(9)
      NI2C: Idle Timeout(10)
      NI2C: Idle Timeout(11)
      NI2C: Idle Timeout(12)
      NI2C: Idle Timeout(13)
      NI2C: Idle Timeout(14)
      NI2C: Idle Timeout(15)
      NI2C: Idle Timeout(16)
      NI2C: Idle Timeout(17)
      NI2C: Idle Timeout(18)
      NI2C: Idle Timeout(19)
      NI2C: Idle Timeout(20)
      NI2C: Idle Timeout(21)
      NI2C: Idle Timeout(22)
      NI2C: Idle Timeout(23)
      NI2C: Idle Timeout(24)
      NI2C: Idle Timeout(25)
      NI2C: Idle Timeout(26)
      NI2C: Idle Timeout(27)
      NI2C: Idle Timeout(28)
      NI2C: Idle Timeout(29)
      NI2C: Idle Timeout(30)
      NI2C: Idle Timeout(31)
      NI2C: Idle Timeout(32)
      NI2C: Idle Timeout(33)
      NI2C: Idle Timeout(34)
      NI2C: [37562] 0x00477260: Device opened
      ####



    Ich werde Ihnen anschließend noch 3 Oszilloskopbilder (2 * fehlerhafte Nutzdaten, 1 * korrekte Nutzdaten) per E-Mail schicken.
    Viel Erfolg und vielen Dank für die Unterstützung!


    Mit freundlichen Grüßen,



    Gunther Beck