Linux: Problemumgehung für I2C Broadcom-Fehler.

Erstellt am 20. März 2013  ·  73Kommentare  ·  Quelle: raspberrypi/linux

Das Broadcom BCM2835 hat einen (Hardware-) Fehler im I2C-Modul.

Das BCM implementiert "Clock Stretching" auf schlechte Weise:

Anstatt eine minimale "Höhe" für die Uhr sicherzustellen, lässt das BCM die I2C-Uhr intern weiterlaufen, und wenn es Zeit ist, die Uhr erneut umzudrehen, prüft es, ob die Uhr hoch geworden ist oder nicht, und wenn sie niedrig ist, ist sie niedrig macht eine "Uhr strecken". Wenn der Slave jedoch nur wenige Nanosekunden vor dieser Prüfung das Taktsignal freigibt, das angibt, dass er für einen neuen Takt bereit ist, kann der Taktimpuls nur 40 ns betragen. (das ist der niedrigste Wert, den ich messen kann, und das ist natürlich ziemlich selten). Bei einem I2C-Takt mit 100 kHz (10 Mikrosekunden) liegen die "schlechten" Momente zum Freigeben des Takts 5 Mikrosekunden auseinander.

Meine Slaves benötigen einen Takt von mindestens 500 ns. (Dies sollte um den Faktor zehn kürzer sein als das, was der Master generieren sollte, wenn er für den 100-kHz-Betrieb konfiguriert ist.)

Das ist ein Hardware-Fehler, gegen den wir im Moment nicht viel tun können. (Tipp für die Hardware-Leute: Anstatt das Clock-Stretching auf diese Weise zu implementieren: Sperren Sie das Zählen des CLOCKDIV-Zählers, während der Takt niedrig bleibt. Dies wird wahrscheinlich einige schnelle Uhren in jedem Zyklus dehnen, aber die Standardkonformität wird sich erheblich verbessern ).

In diesem Fall sendet das BCM ein Byte mit einem sehr kurzen ersten Taktimpuls. Der Slave sieht dann nicht den ersten Taktimpuls. Wenn es also am Ende dieses Bytes Zeit ist, dieses Byte zu bestätigen, wartet der Slave immer noch auf das 8. Bit. Das BCM interpretiert dies als "NAK" und bricht die I2C-Übertragung ab. Zu diesem Zeitpunkt sieht der Slave jedoch seinen 8. Takt und gibt ein "ACK" aus (zieht die SDA-Leitung nach unten). Dies bedeutet wiederum, dass das BCM für die nächste Übertragung keine ordnungsgemäße "START" -Bedingung ausgeben kann.

Vorgeschlagene Problemumgehung für die Software, um die Auswirkungen dieses Hardwarefehlers zu verringern: Wenn eine Übertragung aufgrund eines "NAK" für ein Byte abgebrochen wird, geben Sie vor dem STOP einen einzelnen zusätzlichen Taktzyklus aus, um den Slave zu synchronisieren. Dies muss wahrscheinlich in Software erfolgen.

Dies geschieht nur im "Fehlerpfad", wenn der Slave kein Byte bestätigt. Vielleicht ist es am besten, dies nur zu tun, wenn es NICHT das erste Byte einer Übertragung ist, da der Fehler nicht beim ersten Byte einer Übertragung auftreten kann.

Gehört dieser Software-Fix zum Treiber? Ja. Es ist ein Treiber für eine Hardware, die einen Fehler aufweist. Es ist die Pflicht des Fahrers, diese fehlerhafte Hardware so gut wie möglich zum Laufen zu bringen.

Bug

Hilfreichster Kommentar

Hallo hmf2015,
Dies ist kein Forum. Dies ist ein Bug-Tracker. Diese Liste von Kommentaren beschreibt einen Fehler, der nicht mit Ihren Problemen zusammenhängt. Bitte besprechen Sie Ihr Problem mit einem geeigneten Forum oder Helpdesk. Auch hier freuen wir uns über Ihre Frage: "Vielleicht ist es dasselbe? Vielleicht hilft meine Beschreibung, diesen Fehler zu lösen?" Aber jetzt wissen wir sicher, dass das, was Sie sehen, nichts damit zu tun hat. Bitte "verschmutzen" Sie diese Diskussion nicht weiter.

Alle 73 Kommentare

Wenn eine Problemumgehung im Treiber dazu führt, dass sie für die Mehrheit der Benutzer besser funktioniert, sollte sie unbedingt enthalten sein.
Hast du einen passenden Patch?

Nein noch nicht.

1) Ich habe mich noch nicht mit dem I2C-Treiber befasst. Vor ungefähr einem Jahr hatte ich vor, es selbst zu schreiben, aber bevor ich dazu kam, hatte es jemand anderes geschrieben. Jemand, der diesen Treiber bereits kennt, ist möglicherweise besser dafür gerüstet, dies als fünfminütiges Projekt zu tun. Ich würde mindestens einige Stunden brauchen, um den Fahrer kennenzulernen.
2) Es lohnt sich, zuerst darüber zu diskutieren, wenn Sie (und möglicherweise andere) zustimmen, dass eine Korrektur / Problemumgehung gerechtfertigt ist.
3) Ich wollte dies nur als "Aufgabe" dokumentieren, wir sollten es nicht vergessen ...
4) Vielleicht würde jemand eine andere Problemumgehung vorschlagen.

Apropos Problemumgehungen: Die Problemumgehung kann auch dadurch ausgelöst werden, dass die SDA-Leitung immer noch niedrig ist, wenn wir versuchen, eine neue Transaktion zu initiieren. Das ist eindeutig eine "Problemsituation".

Der Fall "es geht schief" kann für "normale" Fälle selten sein. Viele Leute werden ein Hardware-i2c-Modul am I2C-Bus haben. Damals, als I2C erfunden wurde, war "10us" möglicherweise ein "sehr kurzer" Zeitrahmen für einige Chips, um die Anforderungen zu bearbeiten, so dass ein Dehnen der Uhr erforderlich war. Heutzutage sollte jede Hardware-I2C-Implementierung in der Lage sein, "schnelles I2C" bis zu noch schneller zu verarbeiten.

Dies kombiniert mit der Art und Weise, wie die atmel-Leute ihre asynchronen Module implementiert haben. Anstatt das Modul auf der extern bereitgestellten Uhr (i2c-Slave oder SPI-Slave) laufen zu lassen, läuft das Modul immer noch auf der Prozessortakt. Und es synchronisiert alle eingehenden Signale, indem es sie durch eine Reihe von Filpflops leitet. Gutes Hardware-Design. Die Alternative ist meiner Meinung nach besser: Führen Sie das Modul von der externen Uhr aus und synchronisieren Sie es, wenn die Daten an die andere (CPU-) Uhrdomäne übergeben werden. Dies würde beispielsweise ermöglichen, dass das SPI-Modul mit 20 MHz arbeitet, obwohl die CPU nur mit 8 läuft.

Wie auch immer. Genug Hardware-Streifzug.

Vorgeschlagene Problemumgehung: Geben Sie einen zusätzlichen Taktzyklus aus, wenn zu Beginn einer Transaktion die SDA-Leitung noch niedrig ist. (Es sollte hoch anfangen, um eine "Start" -Bedingung ausgeben zu können).

Erstens weiß ich wenig über I2C. Ich habe mit Gert und anderen über Problemumgehungen gesprochen.

Es sind zwei Probleme mit I2C bekannt:

  1. Das von Ihnen beschriebene Problem beim Dehnen der Uhr
  2. Problem mit der I2C-Zustandsmaschine beim Neustart

Für 1 gibt es nach Ansicht von Gert keine narrensichere Problemumgehung.
Wenn der I2C-Slave das Stretching der Uhr nicht unterstützt, geht es Ihnen gut.
Wenn sich der I2C-Takt um einen begrenzten Betrag erstreckt, kann das Problem durch Verringern der I2C-Taktfrequenz vermieden werden
Der Wechsel zu einem etwas knallenden Treiber für Slaves, die in den vorherigen Fällen nicht fallen, ist eine sichere Problemumgehung.

Ich weiß nicht, ob Ihr Vorschlag funktionieren wird. Es würde mich interessieren zu hören, ob es das Problem reduziert oder es vollständig behebt.

Gert sagt, er habe eine Beschreibung des Fehlers, den er versuchen werde, freigelassen zu werden.

Für 2 haben wir im GPU I2C-Treiber einen Code, der ein Problem mit der Zustandsmaschine umgeht:

/***********************************************************
 * Name: i2c_actual_read
 *
 * Arguments:
 *       const I2C_PERIPH_SETUP_T *periph_setup,
         const uint32_t sub_address,
         const uint32_t data_to_read_in_bytes,
         void *data
 *
 * Description: Routine to actually transfer data to the I2C peripheral
 *
 * Returns: int == 0 is success, all other values are failures
 *
 ***********************************************************/
static int32_t i2c_actual_read(  const I2C_PERIPH_SETUP_T *periph_setup,
                                 const I2C_USER_T *user,
                                 const uint32_t sub_address,
                                 const uint32_t read_nbytes,
                                 void *data,
                                 const int using_interrupt)
{
   int32_t rc = -1; /* Fail by default */
   int32_t status = 0;
   int32_t nbytes;

   uint32_t sub;
   uint8_t* read_data = (uint8_t*)data;
   uint32_t data_read = 0;

   if( NULL != periph_setup && NULL != data ) {

      // confirm that the latch is held for this transaction
      assert( i2c_state.periph_latch[ periph_setup->port ] != rtos_latch_unlocked() );

      // -> START
      // -> Slave device address | WRITE
      // <- Ack
      // -> Sub address
      // <- Ack
      // -> Sub address
      // <- Ack
      // -> ReSTART
      // -> Slave device address | READ
      // <- Ack
      // <- Data[0]
      // -> Ack
      // <- Data[1]
      // -> nAck
      // -> STOP

      I2CC_x( periph_setup->port )     = I2CC_EN | I2CC_CLEAR; /* Enable I2C and clear FIFO */
      I2CS_x( periph_setup->port )     = I2CS_ERR | I2CS_DONE | I2CS_CLKT; /* clear ERROR and DONE bits */
      I2CA_x( periph_setup->port )     = periph_setup->device_address;

      sub = sub_address;
      nbytes = periph_setup->sub_address_size_in_bytes;

      if( 0 == nbytes ) {
         /* No subaddress to send - just issue the read */
      } else {
         /*
           See i2c.v: The I2C peripheral samples the values for rw_bit and xfer_count in the IDLE state if start is set.

           We want to generate a ReSTART not a STOP at the end of the TX phase. In order to do that we must
           ensure the state machine goes RACK1 -> RACK2 -> SRSTRT1 (not RACK1 -> RACK2 -> SSTOP1). 

           So, in the RACK2 state when (TX) xfer_count==0 we must therefore have already set, ready to be sampled:
           READ ; rw_bit     <= I2CC bit 0   -- must be "read"
           ST;    start      <= I2CC bit 7   -- must be "Go" in order to not issue STOP
           DLEN;  xfer_count <= I2CDLEN      -- must be equal to our read amount

           The plan to do this is:
           1. Start the sub-add]ress write, but don't let it finish (keep xfer_count > 0)
           2. Populate READ, DLEN and ST in preparation for ReSTART read sequence
           3. Let TX finish (write the rest of the data)
           4. Read back data as it arrives

         */
         assert( nbytes <= 16 );
         I2CDLEN_x( periph_setup->port )  = nbytes;
         I2CC_x( periph_setup->port )    |= I2CC_EN | I2CC_START; /* Begin, latch the WRITE and TX xfer_count values */

         /* Wait for us to leave the idle state */
         while( 0 == ( I2CS_x(periph_setup->port) & (I2CS_TA|I2CS_ERR) ) ) {
            _nop();
         }
      }

      /* Now we can set up the parameters for the read - they don't get considered until the TX xfer_count==0 */
      I2CDLEN_x( periph_setup->port )  = read_nbytes;
      I2CC_x( periph_setup->port )     |= I2CC_EN | I2CC_START | I2CC_READ;

      /* Let the TX complete by providing the sub-address */
      while( nbytes-- ) {
         I2CFIFO_x( periph_setup->port ) = sub & 0xFF; /* No need to check FIFO fullness as sub-address <= 16 bytes long */
         sub >>= 8;
      }

      /* We now care that the transmit portion has completed; the FIFO is shared and we mustn't read out
         any of the data we were planning on writing to the slave! */

      /* Wait for peripheral to get to IDLE or one of the two RX states - this way we *know* TX has completed or hit an error */
      {
         uint32_t state;
         bool_t state_transition_complete;
         bool_t error_detected;
         do { 
            state = (I2CS_x( periph_setup->port ) & 0xf0000000) >> 28;
            state_transition_complete = ((state == 0) || (state == 4) || (state == 5));
            error_detected = (I2CS_x(periph_setup->port) & (I2CS_ERR | I2CS_CLKT)) != 0;
         } while(!state_transition_complete && !error_detected);

         if (error_detected) {
            /* Clean up, and disable I2C */
            I2CC_x( periph_setup->port ) &= ~(I2CC_INTD | I2CC_INTR);
            I2CC_x( periph_setup->port ) &= ~(I2CC_START | I2CC_READ);
            I2CS_x( periph_setup->port ) = I2CS_CLKT | I2CS_ERR | I2CS_DONE;
            I2CC_x( periph_setup->port ) |= I2CC_CLEAR;
            I2CC_x( periph_setup->port ) = 0;
            return -1;
         }
      }

      if (using_interrupt)
      {
         /* Wait for interrupt to complete. */
         i2c_state.active_buffer[periph_setup->port] = data;
         i2c_state.active_buffer_length[periph_setup->port] = read_nbytes;
         i2c_state.active_buffer_offset[periph_setup->port] = 0;
         i2c_state.pending_transfer[periph_setup->port] = I2C_PENDING_TRANSFER_READ;
         RTOS_LATCH_T latch = rtos_latch_locked();
         i2c_state.pending_latch[periph_setup->port] = &latch;

         /* Enable interrupt. */
         I2CC_x( periph_setup->port ) |= I2CC_INTD | I2CC_INTR;

         rtos_latch_get (&latch);

         i2c_state.pending_latch[periph_setup->port] = NULL;
         data_read = i2c_state.active_buffer_offset[periph_setup->port];

         rc = (data_read == read_nbytes) ? 0 : -1;
      }
      else
      {
         uint32_t time_now = 0;

         /* Loop until we've read all our data or failed. */
         while( 0 == ( I2CS_x(periph_setup->port) & (I2CS_TA|I2CS_ERR|I2CS_DONE) ) ) {
            _nop();
         }

         /* Wait for some data to arrive - we should wait, at most, I2C_TIMEOUT_IN_USECS for data to arrive every time we start waiting */
         time_now = i2c_state.systimer_driver->get_time_in_usecs( i2c_state.systimer_handle );
         while( ((i2c_state.systimer_driver->get_time_in_usecs( i2c_state.systimer_handle ) - time_now) < I2C_TIMEOUT_IN_USECS)
                && ( data_read < read_nbytes )
                && !(I2CS_x( periph_setup->port ) & I2CS_ERR) ) 
         {
            if (I2CS_x( periph_setup->port ) & I2CS_RXD) 
            {
               read_data[ data_read ] = I2CFIFO_x( periph_setup->port );
               data_read++;
               time_now = i2c_state.systimer_driver->get_time_in_usecs( i2c_state.systimer_handle  );
            }
         }

         if( (data_read != read_nbytes) /* Did we read all the data we asked for? */
             || ( (read_nbytes - data_read) != I2CDLEN_x( periph_setup->port ) ) /* Has DLEN decremented? */
             || ( 0 != (I2CS_x( periph_setup->port ) & I2CS_ERR) ) ) { /* Are there any errors? */
            rc = -1;
         } else {
            while( I2CS_DONE != (I2CS_x(periph_setup->port) & I2CS_DONE) ); /* Wait for the peripheral */
            rc = 0;
         }
      }

      /* Clean up, and disable I2C */
      I2CC_x( periph_setup->port ) &= ~(I2CC_INTD | I2CC_INTR);
      if(I2CS_x( periph_setup->port ) & I2CS_ERR) {
         //Wait for it to be idle
         while(I2CS_x( periph_setup->port ) & I2CS_TA)
            _nop();
      }
      I2CS_x( periph_setup->port ) = I2CS_ERR | I2CS_DONE;
      //Finally disable the I2C
      I2CC_x( periph_setup->port ) = 0x0;
   }

   if( !user->skip_asserts ) {
      assert( rc >= 0 );
      _nop();
   }

   return rc;
}      

Ich bin mir nicht sicher, ob die Leute dieses Problem haben, aber das Einfügen könnte hilfreich sein, wenn Sie es sind.

Es ist nicht möglich, diesen Hardwarefehler vollständig zu beseitigen.

In diesem Fall sind sich Master und Slave nicht einig über die Anzahl der Taktzyklen. Daher unterscheiden sich die vom Slave interpretierten Daten und die vom Master beabsichtigten Daten (= Himbeer-Pi = Treiber / Anwendung). Möglicherweise schreiben Sie irgendwo einen völlig falschen Wert in ein Register. Sehr nervig.

Meine vorgeschlagene Problemumgehung würde zumindest dazu führen, dass die nächste Transaktion funktioniert. Die Auswirkungen würden sich halbieren: Nur eine Transaktion wird verpfuscht statt zwei. Es würde das Problem nicht beseitigen.

Wenn der I2C-Slave das Stretching der Uhr nicht unterstützt, geht es Ihnen gut.

Wenn der I2C-Slave keine Taktdehnung benötigt ....

Wenn sich der I2C-Takt um einen begrenzten Betrag erstreckt, kann das Problem durch Verringern der I2C-Taktfrequenz vermieden werden

Ja. Ich habe 10 Geräte "im Feld" an einem Ort. Anscheinend ist die Taktfrequenz (RC-Takt) von drei Modulen so unterschiedlich, dass sie "fertig" werden, wenn sich die Uhr genau im falschen Moment ausdehnt. Durch Reduzieren der Taktfrequenz wurden die Probleme für diese Module behoben.

Wenn die Taktdehnungsverzögerung NICHT festgelegt ist, sondern beispielsweise um mehr als 5 Mikrosekunden variiert, besteht eine mehr oder weniger statistische Wahrscheinlichkeit, dass das Problem auftritt. In meinem Fall benötigt der Slave eine Taktbreite von 0,25 Mikrosekunden. Das Dehnen der Uhr endet also in 5% der Zeit, die zum Zeitpunkt des Zeitwechsels für das BCM führt. Dann geht etwas schief. In diesem Fall würde also etwa 1 von 20 Überweisungen schief gehen. (Spezifikationen sagen min 250ns für einen Takt. Das bedeutet in der Tat nicht, dass es nicht gesehen wird, wenn es kürzer ist. Ich denke, die Wahrscheinlichkeit, dass es gesehen wird, geht linear von 100% bei> 250ns auf 0% bei < 125 ns.)

Ich habe gestern damit verbracht, die Dehnungsperiode der Uhr so ​​zu dehnen, dass sie im 5-Mikrosekunden-Zeitfenster um die 2,5-Mikrosekunden-Marke fällt. Wenn ich den Start des Fensters anstreben würde und meine RC-Uhr etwas schnell läuft, würde ich die "0" drücken, die den Fehler auslöst. Wenn ich 5 anstrebe, das Gleiche. Jetzt ziele ich in die Mitte, weg von den schlechten Orten. Aber ändern Sie den I2C-Takt auf 80 kHz und BAM, ich ziele genau auf den empfindlichen Punkt ... (und wenn es bei 80 kHz nicht passiert, passiert es bei einem Wert zwischen 80 und 100).

Hier ist Gerts Beschreibung des I2C-Fehlers:
https://dl.dropbox.com/u/3669512/2835_I2C%20interface.pdf

Haha! Ich habe mein Testboard genauso instrumentiert. Ich habe die SCL-Spur abgeschnitten und dort einen 0,1-Zoll-Jumper-Stecker montiert. Während ich nicht messe, gibt es dort einen normalen Jumper oder eine Buchse mit einem 100-Ohm-Widerstand, wenn ich es bin.

Ich glaube nicht, dass es nur auf der ersten Uhr passiert. Das würde bedeuten, dass ich das Problem umgehen könnte, indem ich entweder KEINE Taktdehnung überhaupt mache (wie es die meisten Hardware-I2C-Chips wahrscheinlich tun) oder indem ich die Taktdehnung mindestens einen vollen Zyklus dauern lasse.

Ich habe meinen i2c-Slave-Code so instrumentiert, dass sich die Taktdehnung in Schritten von 0,5 Mikrosekunden ändert. Ich kann ihm befehlen, die Taktdehnung über I2C auf XXX zu ändern, und dann funktioniert es 50 Millisekunden lang so, bevor er wieder auf die Standardwerte zurückgesetzt wird. (Falls es nicht funktioniert, muss es wieder funktionieren. Auf diese Weise kann ich schnell einen ganzen Wertebereich nach diesen Einstellungen durchsuchen, während ich die SDA- und SCL-Leitungen mit einem Logikanalysator überwache. Senden einer "Use Delay XXX" und dann Das Senden eines Stichs dauert 25 Millisekunden. Wenn Sie dann einen Zähler im Skript erhöhen und die "nächste Verzögerung" senden, benötigt das Shell-Skript ca. 100 ms. So kann ich 100 mögliche Werte in ca. 10 Sekunden scannen.

Ich habe den Fehler bei längeren Verzögerungen gesehen. Die Theorie: "es passiert nur beim ersten" ist also nicht richtig.

Zum "super effizienten" Interrupt-Handler: Ja, das kann ich auch. Die Sache ist: Mit der Clock-Stretching-Funktion kann ich den Code "Handle this Byte" in die Interrupt-Routine einfügen und muss mir keine Sorgen machen, dass dies einige Mikrosekunden oder einige Millisekunden dauert. Theoretisch stellt die Dehnung der Uhr sicher, dass der Master darauf wartet, dass ich mit der Verarbeitung dieses Bytes fertig bin, bevor er mit dem nächsten fortfährt. Dieser Plan ist mit dem Fehler im 2835 völlig kaputt. Ich lasse jetzt nur das Dehnen der Uhr aufhören und hoffe dann, die Verarbeitung des Bytes in den folgenden 70 Mikrosekunden zu beenden.

Ich muss "Zykluszählung" durchführen, um auf die Mitte der 5-Mikrosekunden-Halbuhr zu zielen, damit ich die Dehnung der Uhr freigeben kann. Wenn ich den Start anstreben würde (um eine Takthochperiode von 4,9 Mikrosekunden zu verursachen), läuft die Uhr auf meinem Slave möglicherweise einige Prozent schneller und der Fehler löst einen halben Zyklus früher aus. Da beide Enden des Halbtaktzyklus gefährlich sind, muss ich einen kurzen, aber ausreichend gültigen Taktzyklus anstreben.

Die Änderung im Modul ist meiner Meinung nach einfach: Wenn SCL "hoch" (dh überhaupt nicht) ist, stoppen Sie die Hauptuhr des I2C-Moduls. Dies hat den Nebeneffekt, dass viel längere I2C-Busse zugelassen werden, da eine automatische Taktdehnung auftritt, wenn die Buskapazität über den Spezifikationen liegt.

Vielen Dank, dass Sie versucht haben zu helfen, iz8mbw, aber diese haben nichts mit diesem (Hardware-) Fehler zu tun.

Ich habe meinen I2C-Takt gemessen und er kommt als 100 kHz heraus, was der Treiber für richtig hält. Der Treiber hat ein "Clock Source" -Objekt, das er nach der Frequenz abfragt und das er verwendet. Ich habe meinen Treiber noch nicht zum Ausdrucken der Frequenz instrumentiert.

Nur zur Information für Leute, die den Fehler in Aktion sehen wollen, habe ich einen "Beweis" in Form eines logischen Analsyer-Dumps.
Hmm, ich kann Bilder anhängen, aber nicht den binären LA-Dump. Dieser ist hier: http://prive.bitwizard.nl/LA_with_bug_scan_50_to_100_microseconds_delay.bin.gz

Im Bild LA_with_bug_shot1.png sehen Sie den kurzen Aktivitäts-Burst: "Verzögerung auf XXX setzen", dann einen kleinen Burst, der versucht, etwa 10 Bytes zu schreiben, der jedoch aufgrund eines NACK abgebrochen wird. Rechts sehen Sie ein richtiges 10-Byte-Paket. Die SDA-Leitung bleibt niedrig, bis der nächste Burst falsch ausgerichtet wird (alle Bits werden verschoben, und in meinem Slave wurde der Zähler "x-Byte-in-Packet" durch die nicht vorhandene Startbedingung zu Beginn dieses Pakets nicht zurückgesetzt .

Im Bild LA_with_bug_shot2.png habe ich den Abschnitt vergrößert, in dem der kurze Impuls auftritt. Dies ist der längste Puls, den ich je gesehen habe: 290 ns. (über Datenblatt-Spezifikation für den Atmel!)
LA_with_bug_shot1
LA_with_bug_shot2

Oh, das ist, woher das kommt!

Ich habe ein Projekt, das ich mit I2C von einem Himbeer-Pi aus steuern möchte, und ich bin ehrlich gesagt kurz davor, einfach aufzugeben und entweder zu einem Beagleboard zu wechseln oder den Pi über SPI mit einem FPGA sprechen zu lassen, das dann das I2C-Zeug erledigt .

Ich habe eine Tafel in der Post, die dazu in der Lage sein sollte (voraussichtliche Zustellung: morgen). SPI-Anschluss, I2C-Anschluss. Wäre ein schönes Projekt, um es mit diesem Board zu versuchen. Senden Sie mir eine E-Mail, wenn Sie auf dem Laufenden gehalten werden möchten.

Aktuelle Situation: Ich sehe ein Verhalten, das mit Gerts kompatibel ist: "Nur der erste Zyklus kann schief gehen", wenn der Slave ein ATMEGA ist, und ich sehe den Fehler in voller Kraft, wenn der Slave einer meiner ATTINYs ist.

Hier sind die Verzögerungen, die ich getestet habe:
i2c_delays_atmega
und der kürzeste SCL-Impuls, der während dieser Testsitzung beobachtet wurde, betrug 4,5 Mikrosekunden.

Beim Testen mit dem Attiny-Slave sind die getesteten Verzögerungen für das ACK:
i2c_delays_attiny

und die minimale Impulsbreite beträgt 41 ns (meine Messauflösung):
i2c_delays_attiny2

Ah. Fand es! Es scheint, dass das Dehnen der Uhr vor dem ACK eines Bytes "gefährlich" ist, aber das Dehnen der Uhr nach dem ACK ist in Ordnung .....

Ich und andere treffen mit Sicherheit das Problem des wiederholten Starts. Ich habe einen Userspace-Hack unter http://cpansearch.perl.org/src/MDOOTSON/HiPi-0.26/BCM2835.xs in proc hipi_i2c_read_register_rs. Dies scheint für die Benutzer zu funktionieren, die gemeldet haben, dass sie es versucht oder den C-Code integriert haben (obwohl dies nur 5 Personen sind), obwohl ich nicht richtig herausgefunden habe, wie festgestellt werden kann, dass die TX-Phase abgeschlossen ist. Ich muss wohl lernen, Kernelmodule zu kompilieren und vorhandene Tests mit dem obigen Code auszuführen.

Könnten wir den Kernel nicht einfach zwingen, die I2C-Hardware zu ignorieren und GPIO-basiertes I2C mit Bitbanged an denselben Pins zu verwenden? Ich würde denken, dass der Overhead dafür akzeptabler wäre als die Fehler in der Hardware selbst.

Welchen Overhead erwarten Sie? Der aktuelle Treiber ist standardmäßig auf 100 kHz eingestellt. Das Lesen von 10 Bytes von einem i2c-Intertialsensor dauert also ungefähr 1 ms. Wenn Sie Bitbang spielen, werden Sie wahrscheinlich die ganze Zeit über CPU-Zyklen durchlaufen ...

Ich würde es vorziehen, wenn der Treiber optional Bitbanging i2c über einen Modulparameter unterstützt (oder ein separates Modul, wenn dies bequemer ist).

Viele Geräte verwenden kein Clock-Stretching (oder Clock-Stretching um einen begrenzten Betrag, damit es bei reduzierter Geschwindigkeit korrekt funktioniert). Daher ist der Hardware-I2C-Treiber in diesen Fällen immer noch vorzuziehen.

Der Kernel selbst verfügt über einen Treiber für Bitbanged-I2C an GPIO-Pins. Dieser Treiber hat einen viel geringeren Overhead als Bitbanging aus dem Benutzerbereich und stellt dieselbe API wie die Hardware-I2C-Treiber bereit. Mein Vorschlag wäre, sowohl diesen Treiber als auch den Hardware-I2C-Treiber als Module zu kompilieren und dann standardmäßig den Hardwaretreiber zu laden.

@Ferroin
Verwenden Sie den Bitbanged-I2C-Treiber auf Pi?
Welche .config-Optionen haben Sie hinzugefügt, um es zu erstellen? Irgendwelche Quell-Patches?
Was tun Sie, um den zu verwendenden Treiber auszuwählen (modprobe? Different / dev / device?)

Ich habe den Treiber auf dem Pi nicht verwendet, aber ich habe einen Freund, der ihn erfolgreich auf einem BeagleBoard verwendet.
Die Konfigurationsoption ist I2C_GPIO.
Wenn sowohl dieser als auch der Broadcom-Treiber als Module konfiguriert wären, wäre die Auswahl des Treibers so einfach wie das Laden des Kernelmoduls.
Das GPIO-Modul benötigt Parameter, um anzugeben, welche GPIOs als SDA und SCL verwendet werden sollen. Ich weiß nicht, was die Parameter sind, aber basierend auf der nicht sehr gut dokumentierten Quelle in dirvers / i2c / busses / i2c-gpio.c, Es sieht so aus, als ob die entsprechenden Parameter 'sda = X scl = Y' sind, wobei X und Y die Pins sind, die Sie verwenden müssen.

Das i2c-gpio-Modul selbst bietet keine Möglichkeit, Parameter an es zu übergeben. Sie benötigen also ein anderes Modul, das Plattformdaten registriert und mindestens Busnummer, SDA- und SCL-Pins konfiguriert. Ich habe einen Proof of Concept für ein solches Modul geschrieben und es hat sogar auf den Pins 0 und 1 funktioniert, aber ohne i2c-bcm2708 geladen (pcf8574 wurde von i2cdetect erkannt, ich konnte einige LEDs mit dem Modul gpio-pcf857x ansteuern). Aber dann habe ich meinen PCF8574 beim Wechseln der Pins verbrannt (und ich habe momentan keine anderen i2c-Chips), sodass ich ihn nicht wirklich testen konnte. Hier ist der Code

@ Kadamsi
Das Festlegen der Parameter des Moduls sda_pin / scl_pin kann hilfreich sein. Da wäre eine Pull-Anfrage.
Kann jemand bestätigen, dass dies für sie funktioniert?

Das ist weniger trivial als es aussieht: Es wird erwartet, dass eine Plattformdatenstruktur vollständig übergeben wird.

Auf der anderen Seite schreibt die Plattform nicht vor, welche GPIOs Sie heute verwenden werden. Daher klingt es vernünftig, die Arbeit zu investieren, um sie zu ändern. (Normalerweise geben die Plattformdaten an: "Wie ist / this / computer verdrahtet?")

@popcornmix
Ich habe vor, sie konfigurierbar zu machen. Ich hatte gestern einfach nicht genug Zeit. Ich möchte auch, dass mehr als ein Bus gleichzeitig erstellt werden kann. Vielleicht auf dynamische Weise, wie GPIOS export und unexport sysfs-Dateien (aber ich bin nicht sicher, ob es möglich ist, einen solchen Bus sauber zu exportieren)? Oh, und ich habe einen anderen pcf8574 gefunden und konnte bestätigen, dass er auch bei verschiedenen GPIO-Pins gut funktioniert, wenn externe Pullup-Widerstände verwendet werden. Leider habe ich keine anspruchsvolleren I²C-Geräte zum Testen. Sind Sie also daran interessiert, ein solches Modul im Standard-Kernelbaum bereitzustellen?

@ Kadamski
Ich habe kein Setup, um solche Module zu testen. Alle vom Chip bereitgestellten Hardwarefunktionen (wie I2C) sollten jedoch über Kerneltreiber verfügen, damit mehr Benutzer sie verwenden können. Wenn die I2C-Hardware Fehler aufweist, die die Verwendung bestimmter Peripheriegeräte verhindern, lohnt sich eine bitbangende Alternative.

Wenn Sie also einen neuen Treiber erstellen, der für Benutzer, die ihn nicht verwenden, harmlos aussieht (dh als Modul erstellt wurde und erst nach dem Laden nichts enthält), und es einige Beweise gibt (dh einige bestätigende Benutzerberichte), funktioniert er ordnungsgemäß Ich freue mich über eine PR.

Wurde die HW auf BCM2837 (in RPi 3) behoben?

Meine Vermutung ist: nein. Aber ich habe heute wahrscheinlich keine Zeit, dies zu testen.

BCM2837 I2C bleibt unverändert.

Das ist bedauerlich, aber danke für die Info.

das ist sehr nervig.

Genau. Hat jemand einen Link zu BCM2837-Errata oder ähnlichem, der angibt, dass das Problem weiterhin besteht? Wäre praktisch, wenn wir die Nachrichten weitergeben müssen. Oder @ P33M , vielleicht können Sie als maßgeblich bezeichnet werden, wenn Sie für Broadcom arbeiten?

Er ist maßgeblich, arbeitet aber nicht für Broadcom.

Das ist gut. Aber ich habe bereits gegoogelt und abgesehen davon, dass P33M anderswo M33P ist, habe ich Schwierigkeiten, einen Ausweis zu finden, den ich sinnvoll weitergeben kann. Was in Ordnung ist, aber bedeutet, dass er keine gute Quelle zum Zitieren ist. :-) Ein Errata-Link wäre also praktisch.

@ P33M funktioniert für Raspberry Pi. Sie können das, was er sagt, als maßgeblich behandeln.

Ich denke nicht, dass es eine Errata-Liste gibt, sollte es wahrscheinlich sein. Ich habe ihn verlassen
um seine Identität zu bestätigen oder nicht!

Am 15. März 2016 um 14:30 Uhr schrieb RalphCorderoy [email protected] :

Das ist gut. Aber ich habe bereits gegoogelt und abgesehen davon, dass P33M M33P ist
An anderer Stelle fällt es mir schwer, einen Ausweis zu finden, den ich sinnvoll weitergeben kann. Welches ist in Ordnung,
aber bedeutet, dass er keine gute Quelle ist, um zu zitieren. :-) Ein Errata-Link wäre also
praktisch.

- -
Sie erhalten dies, weil Sie kommentiert haben.
Antworte direkt auf diese E-Mail oder sieh sie dir auf GitHub an:
https://github.com/raspberrypi/linux/issues/254#issuecomment -196845789

@RalphCorderoy Ich bin ein Mitarbeiter von Raspberry Pi (Trading) Ltd. Meine Antwort ist maßgeblich.

@ P33M , Ta, das reicht. Tut mir leid wegen dem Ärger.

Dies betrifft ein Projekt, an dem ich arbeite. Glücklicherweise habe ich die vollständige Kontrolle über die Firmware des Slave-Geräts und konnte die Problemumgehung hinzufügen, indem ich meinen Antworten eine zusätzliche Verzögerung (Taktdehnung) für eine halbe Periode hinzufüge, die das schlechte Verhalten überspringt.

Eine gute Analyse des Problems finden Sie auf advamation.com .

Ist diese schlechte Hardware in der I2C-Implementierung von Broadcom vorhanden oder sind Kernel-Optimierungen möglich, damit sich die Hardware korrekt verhält?

Ich habe dieses Problem gerade abonniert, da ich dies auch bei einem Produkt festgestellt habe, das ich entwickle
welches i2c zwischen einem AVR und Pi verwendet. Jetzt muss ich es überdenken.
Hat jemand eine zuverlässige Form des i2c-Bit-Banging verwendet?

@ mwilliams03 , Sie könnten an diesem Projekt interessiert sein, bei dem ich erfolgreich eine 100-kHz- und 400-kHz-I2C-Kommunikation zwischen einem Raspberry Pi und einem AVR hergestellt habe. Ich bin kein Bitbanger, sondern benutze stattdessen die Hardware-I2C-Unterstützung und füge Verzögerungen an wichtigen Punkten ein. Es stellte sich heraus, dass der AVR langsam genug ist, dass bei 400 kHz keine zusätzlichen Verzögerungen erforderlich sind.

Hier finden Sie insbesondere Informationen zu den I2C-Problemen . Beachten Sie auch, dass das TWI-Modul des AVR ein Problem aufweist, das ein schnelles Lesen verhindert .

danke @ pdg137 , ich habe es ausprobiert und beim ersten Mal habe ich 1,2 Millionen Lesevorgänge ohne Fehler erhalten und bin immer noch dabei.

@rewolff sieht so aus, als ob dieses Problem behoben wurde. Wenn dies der Fall ist, schließen Sie dieses Problem.

Und jetzt ... fügen Sie einen Level Shifter und ein 40 cm langes Verlängerungskabel hinzu. Funktioniert es dann? Es besteht die Möglichkeit, dass dies auf der "oberen" Seite der Wellenformen zu einer ausreichenden Verzögerung führt und der Fehler plötzlich erneut auftritt.

Soweit ich das beurteilen kann, denken Broadcom und Mitarbeiter immer noch, dass dieser Fehler auf die ERSTEN 5 Mikrosekunden (eigentlich die halbe Uhr) nach dem letzten Bit eines Bytes beschränkt ist. Wenn Sie dann nur 10 Mikrosekunden hinzufügen, werden die Dinge auf zwei halbe Uhren übertragen, und es sollte keine Probleme geben. Bei meinen Tests finde ich "schlechte" Momente, um zu verhindern, dass sich die Uhr alle 5 Mikrosekunden ausdehnt.

Aufgrund der Symmetrie zwischen SPI und I2C ist es in meinem AVR-Code einfacher, wenn das nächste Datenbaby im Interrupt "Nächste Daten" "berechnet" wird .... (Ich stelle eine Schnittstelle zur Verfügung, an der das Weiterlesen zulässig ist, also ein 16-Byte-Puffer ist nicht immer genug.).

Ich bin nicht überzeugt.

Ich habe Probleme mit SMBus zwischen einem Respberry Pi und einem ATMEGA 324PA. Könnten diese mit diesem Problem zusammenhängen? https://stackoverflow.com/questions/39274784/talking-smbus-between-raspberr-pi-and-atmega-324pa-avr-not-clock-stretching

Soweit ich das beurteilen kann, denken Broadcom und Mitarbeiter immer noch, dass dieser Fehler auf die ERSTEN 5 Mikrosekunden (eigentlich die halbe Uhr) nach dem letzten Bit eines Bytes beschränkt ist.

@rewolff : Ich müsste den Mitarbeitern von Broadcom zustimmen. In meinen Tests erhalte ich mit einem Raspberry Pi 3 und 100 kHz I2C (der sich bei gedrosselter CPU auf 62 kHz verlangsamt) ähnliche Ergebnisse wie bei der

Die Animation scheint gut zu sein. Dies entspricht jedoch nicht meiner Erfahrung. Vielleicht sollte ich einen Test einrichten. Könnte eine Weile dauern. Es ist mit anderen Sachen beschäftigt.

Aber wenn dies der Fall wäre, würde einfach ein "usleep (10)" in meiner Interrupt-Routine (mit Hardware-Clock-Stretching) normalerweise den Trick machen und die Dinge nicht blockieren. Ich bin mir ziemlich sicher, dass dies nicht der Fall war. :-(

@rewolff : Beim Raspberry Pi 3 wurde die CPU auf 600 MHz gedrosselt, was zu einer Standard-I2C-Geschwindigkeit von 62 kHz führte. Sie sollten also 17 Mikrosekunden im ISR Ihres Slaves schlafen, wenn der ISR an der fallenden Flanke von SCL beginnt. Wenn Sie der Meinung sind, dass die CPU auf unter 600 MHz gedrosselt wird, sollten Sie länger schlafen.

Wäre es möglich, das i2c -gpio-param-Modul von @kadamski in den Raspberry Pi-Kernel aufzunehmen? Ich kann bestätigen, dass dieser Ansatz für meine Anwendung (AVR-Software I2C-Slave) recht gut zu funktionieren scheint und es etwas umständlich ist, die erforderlichen Header für den Himbeerkern zu installieren. Daher wäre es großartig, ihn verfügbar zu haben.

Es wäre auch eine gute Problemumgehung, um den HW-Fehler zu beheben, der diesem ganzen Problem zugrunde liegt.

@onnokort Du meinst wie das i2c-gpio-Overlay, das seit November 2015 in aktuellen Kerneln vorhanden ist? https://github.com/raspberrypi/linux/blob/rpi-4.4.y/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts
Aus der README für Overlays:

Name:   i2c-gpio
Info:   Adds support for software i2c controller on gpio pins
Load:   dtoverlay=i2c-gpio,<param>=<val>
Params: i2c_gpio_sda            GPIO used for I2C data (default "23")

        i2c_gpio_scl            GPIO used for I2C clock (default "24")

        i2c_gpio_delay_us       Clock delay in microseconds
                                (default "2" = ~100kHz)

@ 6by9 :

@popcornmix @ 6by9 Kann dies geschlossen werden? Ich war schon eine lange Zeit dort und das dt param Zeug aus meiner Lektüre scheint eine anständige Option zu sein.

Die empfohlene Problemumgehung für Geräte, die mit unserer I2C-Hardware definitiv nicht gut funktionieren, ist die Verwendung des i2c-gpio-Overlays, das die Pins bitbasht.

Andernfalls wird die Taktdehnung in der Adress-ACK-Phase vom Upstream-Treiber unterstützt.

Sehr geehrte Damen und Herren, heute habe ich den BNO055 im Paket GY-955 aus Ostasien getestet, der sich bei 100_000 Hz mit einem Pi 2B (BMC2835) sehr hässlich verhält. Für Tests habe ich die Frequenz des I2C-Busses von 50_000 auf 400_000 Hz geändert und Probleme bei 100_000 Hz festgestellt, aber für 50_000, 85_000, 115_000 und 125_000Hz funktioniert der Code von Adafruit (Adafruit_Python_BNO055) ziemlich gut mit der I2C-Verbindung, 150_000 Hz scheint für den BNO055 zu schnell zu sein, es funktioniert, aber die Werte sind manchmal falsch. Ich gestehe, ich habe die Frequenz nicht mit einem Oszilloskop getestet, sondern nur die Datei / sys / class / i2c-adapter / i2c-1 / of_node / clock-frequenz vorgelesen, daher bleibt eine gewisse Unsicherheit offen. Jetzt beginne ich mit der Implementierung einer vollständigen Schnittstelle zum BNO055 in ADA.
Facit: Der Hardwarefehler in der BMC I2C-Behandlung tritt nur bei 100_000 Hz auf, er muss bestätigt werden.

Nur zu Ihrer Information, der Hardwarefehler tritt auf, wenn das Slave-Gerät die Taktdehnung ausführt und die SCL-Leitung nach 0,9 bis 0,999 I2C-Taktperioden freigibt. Die Leitung beginnt zu steigen, und die pi-Hardware sagt: Oh, er hat keine Taktdehnung durchgeführt, damit ich den nächsten Taktimpuls liefern kann, indem ich die Taktleitung wieder nach unten ziehe.

Der Fehler tritt auf, wenn die verbleibende Zeit in der Taktperiode ausreicht, damit die Clk-Leitung den "HIGH" -Schwellenwert für die Himbeere überschreitet, jedoch nicht für die Slave-Geräte, ODER wenn der Slave eine Rauschfilterung hat und während <x% der Zeit ein Hoch berücksichtigt normaler I2C-Taktzyklus ein Fehler.

Dies geschieht nicht "nur bei 100 kHz", sondern auch bei vielen anderen Frequenzen, außer dass die Antwortzeit des Slave-Geräts dann einen anderen Wert haben muss.

Angenommen, der Takt ist 100 kHz, also wäre ein normaler Zyklus 5us hoch und 5us niedrig. Angenommen, bei t = 0 startet der pi den letzten Taktzyklus, indem er die Taktleitung nach unten zieht. Bei t = 5us gibt der pi das Taktsignal frei, aber der Slave ist immer noch beschäftigt und hält den Takt niedrig. Bei t = 9us ist der Slave fertig und gibt das Taktsignal frei. Bei t = 10us schaut der pi auf das Taktsignal und denkt: Ok, keine Taktdehnung, also fahren Sie fort und es zieht das Taktsignal wieder nach unten. Das Taktsignal war jetzt nur für 1us hoch (etwas weniger aufgrund der Kapazität und der Zeitkonstante der Pullup-Widerstände) und wird vom Slave möglicherweise nicht gesehen. Jetzt ist ein anderes Gerät nicht nach 9 Mikrosekunden bereit, sondern nach 10,5. Jetzt bei 100 kHz wird der pi "immer noch niedrig, Taktdehnung, weitere 5 Mikrosekunden warten. Jetzt erhalten wir einen Takt von 4,5 Mikrosekunden und die Dinge werden funktionieren. Aber lassen Sie dieses Gerät bei 90 kHz laufen, und es wird in Schwierigkeiten geraten pi sieht 11 Mikrosekunden vom Start an und das Taktsignal war weniger als eine Mikrosekunde lang hoch -> Probleme.

Die Leute, die sich darüber beschweren, sind NICHT diejenigen, die diese anderen Geräte haben. Diese arbeiten mit dem Standardwert von 100 kHz. Aber der Fehler ist immer noch sehr real und würde auf diesen Geräten einfach bei anderen Busgeschwindigkeiten als den Geräten auftreten, die Sie und ich haben.

Vielen Dank für die Antwort, es erklärt sehr gut, warum ich bei den von mir gewählten Frequenzen eine zuverlässige Übertragung erhalten habe:
bei 100_000 Hz treten die Probleme im Zeitraum von 9 bis 9,99 µs auf
bei 85_000 Hz beginnen die Probleme bei 1_000_000 / 85_000 * .9 = 10,59 µs> 9,99 s, daher wird die Taktdehnung ignoriert. Ich gehe davon aus, dass für alle Frequenzen unter 85_000 Hz der Startpunkt der Probleme höher als 10,59 µs ist .
bei 115_000 Hz beträgt der Buszyklus 1_000_000 / 125_000 = 8,7 µs <9 µs, daher wird die Taktstrecke korrekt erkannt, bei allen Frequenzen über 115_000 Hz beträgt der Buszyklus weniger als 8,7 µs.
Wenn ich also Probleme habe, kann ich die Frequenz berechnen, die ich brauche.
(Ich habe die Informationen unter http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html gelesen.)
es wurde 0,5 anstelle von 0,9 einer Periode notiert).

Gut. Dies hängt davon ab, was Ihr Slave als gültiges Taktsignal erkennt. Und wie viel Verzögerung der RC in Ihrem Bus einführt. In meinem Fall betrachtet der AVR, den ich als Slave verwende, Impulse mit weniger als zwei Taktzyklen als Störung. Bei einem internen RC-Takt von 8 MHz (+/- 10% !!!) muss der Impuls mindestens 250 ns betragen, um erkannt zu werden. I2C-Spezifikationen erfordern 5 Mikrosekunden, daher gibt es einen Faktor von 20 "Spielraum" zwischen dem, was offiziell erforderlich ist und dem, was nicht mehr funktioniert.

Zuerst dachte ich, ich würde die Taktstrecke in meinem Sklaven erhöhen, um ein bisschen 12us zu sagen. Dies funktioniert so lange, bis die Buskapazität genügend Verzögerung hinzufügt, um erneut ein Problem zu verursachen. Es ist also sehr schwierig, das Problem zu umgehen. Es ist ärgerlich, Ihren Kunden mitteilen zu müssen, dass sie den Standard-100-kHz-i2c nicht verwenden sollen.

Entschuldigung, aber ich brauchte einige Zeit, um ein vollständiges Implementierungs- und Testszenario zu schreiben.
Ich danke Ihnen für all die Informationen, die Sie mir gegeben haben, es war sehr hilfreich.
Mein Testszenario besteht aus 2 MEMS (BNO055 als GY-055, MPU9255 als MPU-9250/6500, WHO_AM_I-Register als MPU9255) und 1 GPIO-Extender PCF 8574 (PCF 8574).
Der I2C-Takt am Pi (2b) wurde auf 125 kHz eingestellt, was durch Lesen von / sys / class / i2c-Adapter / i2c-1 / of_node / Taktfrequenz überprüft wurde.
Mein Code läuft 100 Mal, liest Daten aus dem MEMS und schreibt Daten für PCF mit einer Verzögerung von 0,1 Sekunden.
Ergebnis:

  • Die Initialisierung des MEMS war erfolgreich.
  • Das Lesen der MEMS-Daten über den I2C-Bus war über alle Zyklen erfolgreich.
  • Das Schreiben von Daten in die PCF über den I2C-Bus war über alle Zyklen erfolgreich.

Daher akzeptieren MEMS und PCF einen Takt, der höher als der Standardwert von 100 kHz ist.
In einer älteren Umgebung erfolgt die Kommunikation mit dem AVR über eine serielle Leitung, in meiner zweiten erfolgt die Kommunikation über USB, aber sie ist noch nicht abgeschlossen. Eigentlich bin ich über die vom BNO055 verursachten I2C-Busprobleme gestolpert, aber ich denke Für meine Umgebung habe ich eine Problemumgehung für einen Pi 2b gefunden und ich hoffe, dass es auch mit einem Pi 3 funktioniert. Das ist der nächste Test. Und dann muss ich 2 andere MEMS integrieren, 1 VL53L0X und 1 BME280. Ich hoffe, dass es mit der neuen Frequenz funktioniert und die Buskapazität all diese Elemente akzeptiert.

Ich spiele jetzt mit diesem Problem auf einem RPi 3 Model B + und sehe andere Ergebnisse als im Advamation-Artikel beschrieben. Das Silizium wurde kürzlich nicht gedreht, oder?

Die kurze Version ist, Dinge scheinen zu funktionieren, wenn ich mich bei read-preACK, write-preACK oder write-postACK strecke; Das einzige Mal, dass ich sicher sein muss, dass ich mich entweder lang oder gar nicht dehne, ist read-postACK. Ich muss mein Experiment noch aufräumen, bevor ich etwas Bestimmtes sagen kann.

Zunächst ein Hinweis zur Terminologie. Der Advamation-Artikel sagt:

I2C mit dem Raspberry Pi funktioniert also nur, wenn
der Slave verwendet überhaupt kein Clock-Stretching oder
Der Slave streckt die Uhr erst am Ende / direkt nach einer I2C-Lese-ACK-Phase (nach dem Lesen von ACK / NACK), dann aber um mehr als 0,5 Taktperioden.

Der Begriff "I2C-Read-ACK-Phase" scheint etwas mehrdeutig. Wenn es sich um einen I2C-Lesebefehl handelt (dh das R / W̅-Bit nach der Adresse ist gesetzt), schreibt der Slave das A̅C̅K̅-Bit und liest es nicht, entgegen der Klammer. Wenn ich hier "read-postACK" sage, meine ich, dass das R / W̅-Bit direkt nach der Adresse gesetzt wurde (und vermutlich nicht wie bei SMBus durch das Protokoll geändert wurde), sodass der Slave gerade seine A̅C̅K̅-Antwort geschrieben hat.

Wie hier bereits angedeutet, scheint es, dass der RPi, wenn er feststellt, dass SCL von einem Slave niedrig gehalten wird, seinen internen SCL-Takt um einen halben Zyklus (5 μS) verzögert. Der Fehler wird ausgelöst, wenn der Slave die SCL für fast einen halben Zyklus niedrig hält. In diesem Fall lässt das RPi die SCL weiterhin hoch und zieht sie unmittelbar danach nach unten, wenn die SCL-Uhr ausgelöst wird. Dies führt zu einem Runt-Clock-Impuls, den einige Geräte möglicherweise als Impuls sehen, während andere dies nicht tun. (Als Referenz: Die I2C-Spezifikation impliziert eine nominelle SCL-Hochzeit von 5 μS und legt eine Mindestzeit von 4,0 μS bei 100 kHz fest. Dies ist die Standardgeschwindigkeit der I2C-Schnittstelle des RPi.)

In meinen Experimenten würde in den Phasen Read-PreACK, Write-PreACK und Write-PostACK das RPi sicherstellen, dass die maximal zulässige SCL-Hochzeit etwa 4 μS beträgt. Es schien bereit zu sein, seine SCL-Uhr in diesen Phasen zurückzuschieben. Ich vermute, dass das RPi die SCL-Leitung kurz nach der Freigabe abgetastet hat, und wenn SCL immer noch niedrig war, hat es seinen SCL-Takt eine halbe Phase zurückgeschoben.

In der Read-PostACK-Phase sah ich jedoch, dass das RPi kleine Uhren (<4 μS, oft 2 μS oder weniger) aussenden würde, wenn die SCL-Leitung für etwa 6–9 μS niedrig gehalten würde. Ich vermute, dass die Broadcom-Ingenieure in dieser Phase einen anderen Weg einschlagen, um die Wahrscheinlichkeit zu verringern, dass sie eine Halbphase auf einer Leitung mit hoher Kapazität verzögern müssen. Leider - wie wir gesehen haben - fällt es zu kurz.

Daher muss mein aktueller Code die SCL in der Read-PostACK-Phase von Lesevorgängen, die eine Weile dauern können (z. B. ADC-Konvertierungen), über einen halben Zyklus hinaus verlängern. Wenn ich es nicht schaffe

Die aktuellen Tests, die ich durchführe, verwenden einen PIC16F1619 als Slave-Gerät. Das Slave-Gerät verwendet eine Schleife, um die Uhr sowohl in Lese- als auch in Schreibbefehlen vor und nach dem Backen zu dehnen. Die Länge dieser Schleife plus Overhead variiert von 3 μS (weniger als die Zeit, in der der RPi den SCL niedrig hält) bis 90 μS in Schritten von 0,35 μS. Ich habe ein Python-Programm auf dem RPi, das Werte zu zwei Registern unterscheidet, sie dann zurückliest und bestätigt, dass die Rücklesewerte korrekt sind. Die verwendeten Werte

Piquan,
Broadcom hat dies heruntergespielt, indem es verkündete, dass dieses Problem nur auf der ersten Zeitstrecke auftritt. Ich glaube nicht, dass dies der Fall ist. Sie sollten dies überprüfen können. Die Proklamation scheint den Aussagen von Broadcom zu folgen.

@rewolff Nun, es könnte etwas an ihrer Interpretation liegen. Wenn mit "erste Taktdehnung" "das erste Mal in einer bestimmten Phase, dass SCL um mehr als eine Taktübersetzung gedehnt wird" gemeint ist, dann ist ihre Beschreibung korrekt: Wenn Sie um mehr als einen Taktzyklus strecken, dann ja: insgesamt Phasen, wenn Sie sich um> 0,5 Zyklen dehnen, sind Sie in guter Verfassung. Zumindest in den vagen Experimenten, die ich bisher gemacht habe; genauere Experimente stehen noch aus.

Ich bin froh, einige bessere Experimente durchführen zu können, um zu demonstrieren, wann der I2C des RPi Taktstrecken bewältigen kann und nicht, und Repros zu erhalten, die BCM an die Ingenieure senden kann.

Leider gibt es eine sehr bedeutende Silizium-Drehzahl, die sie benötigen würden, um dieses Problem zu beheben. Sie müssen den SCL-Teilertakt nicht ankreuzen, wenn SCL niedrig gehalten wird (von einer internen oder externen Quelle). Dies erfordert wahrscheinlich eine Änderung des Siliziumpegels, die teuer ist. Die meisten ECOs sind auf Metallniveau, was… nicht billig, aber viel billiger als Silizium ist.

Mein Hauptziel hier ist es, die Arten von Sklaven zu charakterisieren, die mit dem RPi funktionieren würden und nicht, mit einigen experimentellen Beweisen.

Es hört sich so an, als ob wir solidere Daten wie Repro-Szenarien benötigen, um Broadcom davon zu überzeugen, den I2C-Controller neu zu konstruieren. Selbst mit soliden Daten müssen die Ingenieure das Management davon überzeugen, dass es sich lohnt, Silizium für die nächste Überarbeitung zu überarbeiten.

Trotzdem werde ich einige Zeit in das Entwerfen reproduzierbarer Szenarien investieren, damit die BCM-Ingenieure das Problem klar erkennen und testen können. Ich werde mich jedoch auf die Community-Mitglieder hier verlassen, um Broadcom meine Ergebnisse mitzuteilen. Ich habe keinen Kanal zu ihnen.

Ich sollte etwas über meinen vorherigen Kommentar für die Community klarstellen, über Änderungen von Silizium und Metall.

Weißt du, wenn du ein Board von SparkFun oder Adafruit bekommst, hat es oft Spuren, die du schneiden oder zusammenlöten kannst, um sein Verhalten zu ändern? Die meisten I2C-Karten haben Spuren, die Sie ändern können, um die Adresse zu ändern, die Pull-up-Widerstände zu aktivieren oder zu deaktivieren usw.

Mikrochip-Designer machen das Gleiche. Es gibt viele Änderungen, die sie an den Metallschichten eines Mikrochips vornehmen können, so dass sie die Siliziumschichten nicht ändern müssen. Das liegt daran, dass das Wechseln von Siliziumschichten schwierig und teuer ist (wie das Wechseln des Chips auf einer Platine), während Metallschichten viel einfacher zu wechseln sind (wie das Wechseln der Spuren auf einer Platine).

In den Metallschichten können viele nützliche Änderungen vorgenommen werden, da Designer vorausdenken und Metallverbindungen (im Wesentlichen Jumper) herstellen, die das Verhalten eines Chips ändern.

Aber wenn es eine Änderung gibt, die sie nicht geplant haben und nicht herausfinden können, wie sie durch Umleiten von Spuren innerhalb des Chips vorgenommen werden soll, müssen sie das Silizium ändern. Silizium benötigt viel mehr Planung, Verifizierung und Maskierung, daher ist es schwierig, Änderungen vorzunehmen.

Viele Unternehmen werden eine Siliziumschicht, die „gut genug“ ist, so lange wie möglich verwenden. Sie werden einige Teile der Siliziumschicht in mehreren Revisionen des Chips wiederverwenden.

Ich vermute, hier befindet sich BCM: Sie benötigen gute Beweise dafür, dass dieser Fehler nicht in Treibern oder Metall behoben werden kann, bevor sie eine Neugestaltung dieses Teils der Siliziumschicht von Grund auf rechtfertigen können.

Es ist äußerst unwahrscheinlich, dass das vorhandene Silizium erneut repariert wird, um dieses Problem zu beheben (haben Sie 1 Mio. USD übrig?). Zukünftige Chips könnten jedoch eine Lösung haben, wer weiß.

Am Mittwoch, den 05. September 2018 um 02:13:19 Uhr -0700 schrieb Joel Ray Holveck:

Es hört sich so an, als bräuchten wir solidere Daten wie Repro-Szenarien
überzeugen Sie Broadcom, den I2C-Controller neu zu konstruieren. Sogar mit
Solide Daten müssen die Ingenieure das Management davon überzeugen
Es lohnt sich, Silizium für die nächste Überarbeitung zu überarbeiten.

Sie hatten bereits sechs Jahre und drei Siliziumrevisionen, wo sie
haben ihre Entscheidung demonstriert: "wird nicht reparieren".

Wenn Sie sich um> 0,5 Zyklen dehnen, sind Sie in guter Verfassung.

Das glaube ich nicht. Jedes Mal, wenn Sie CLK im "kurz vor dem" veröffentlichen
Broadcom sieht wieder "Zeitraum, Sie bekommen kurze Impulse. Ich kann leicht
verzögern Sie die Freigabe des Taktsignals um beispielsweise 5 nutzlose Mikrosekunden auf
immer außerhalb des 0,5-Zyklus sein. Das hat aber nicht funktioniert.

Am Mittwoch, den 05. September 2018 um 02:28:53 Uhr schrieb James Hughes:

Es ist äußerst unwahrscheinlich, dass es zu einer Reaktion der
Vorhandenes Silizium, nur um dieses Problem zu beheben (haben Sie 1 Mio. USD übrig?). Zukunft
Chips können jedoch die Lösung haben.

Das bezweifle ich. Wir gingen von BCM2835 mit bekanntem Fehler zum BCM2836 mit
der gleiche Fehler zum BCM2837 mit genau dem gleichen Fehler zum BCM2837B0.

Warum wird die nächste Revision Ihrer Meinung nach anders sein?

BCM hat einen Zielmarkt: Telefone und TV-Sticks für diese Chips. Im
In ihrem Zielmarkt macht niemand Software-I2C für allgemeine Zwecke
Mikrocontroller wie AVRs und PICs. Sie werden dies NICHT beheben.

Es ist eine Schande, dass dieser Ermittlungsaufwand erforderlich ist, auch wenn er großartig ist. Als ich vorher nach einem Erratum gefragt habe, das dies abdeckt, dachte man, es gäbe keines. Hat sich das jetzt geändert und es gibt eine URL? Im Idealfall würde Broadcom der Community helfen, indem es den Fehler genau beschreibt. Wenn er auftritt, können Problemumgehungen oder Bewertungen kompatibler Komponenten leichter und sicherer durchgeführt werden. Selbst im Ausmaß des Ausschnitts relevanter HDL, wenn sie nicht versuchen wollen, dies genau in eine Beschreibung zu übersetzen.

Der Vorschlag, den Halbbit-Taktteiler anzuhalten, wenn die Taktdehnung zugelassen wird, ist gut. Es würde funktionieren.

Das Problem dabei ist, dass ein Teil des I2C-Moduls dann mit "voller Taktrate" laufen müsste. Jetzt ist das I2C-Modul ein schönes Low-Power-Modul, da es normalerweise nicht schneller als 200 kHz läuft.

Der Hauptgrund für meinen Beitrag war das, was ich zu Beginn meines ursprünglichen Beitrags gesagt habe:

Ich spiele jetzt mit diesem Problem auf einem RPi 3 Model B + und sehe andere Ergebnisse als im Advamation-Artikel beschrieben. Das Silizium wurde kürzlich nicht gedreht, oder?

Wenn wir nach dem Advamation-Bericht 2013 erhebliche Änderungen an der I2C-Hardware oder am I2C-Treiber vorgenommen haben und die Community weiß, wie sich diese auf diesen Fehler auswirken können, sollte ich meine Experimente entsprechend ändern.

Ich weiß, dass das grundlegende Problem in der Hardware liegt, aber nach allem, was ich weiß, hat jemand experimentell herausgefunden, dass das Ändern eines scheinbar nicht verwandten Registers im Treiber tatsächlich das Verhalten dieses Fehlers ändert. Ich habe auch nicht bestätigt, dass das BCM2837 das gleiche I2C-Modul wie das RPi 2 hat (das letzte Mal konnte ich eine endgültige Bestätigung finden, dass die I2C-Hardware unverändert war, seit dieses Problem erstmals gemeldet wurde). Ich habe auch keine Informationen über die BCM283x-Stufen gefunden. Soweit ich weiß, hätte es in der BCM2836-Ära einen Metallwechsel geben können.

Ich bin nicht daran interessiert, Broadcom zu verprügeln, darüber zu spekulieren, wie sie zukünftige Revisionen oder ähnliches ändern könnten.

Mein primäres Ziel ist es, das aktuelle Verhalten klar zu dokumentieren. es sieht so aus, als ob es sich im Laufe der Zeit verändert hat. Ich habe das sekundäre Ziel, zukünftigen Benutzern zu ermöglichen, meine Experimente zu reproduzieren, um festzustellen, ob die Ergebnisse noch gültig sind, oder um Verbesserungen vorzunehmen oder andere Bedingungen zu testen. Ich habe ein weiteres sekundäres Ziel, damit die Broadcom-Ingenieure die Tests problemlos reproduzieren können, wenn sie möchten. Beides bedeutet, dass ich meine Experimente veröffentlichen muss, was auch hilft: Aufgrund meiner eigenen Hybris werde ich, wenn ich meine Experimente veröffentliche, mehr darauf aus sein, sie rigoros zu machen.

Mein aktueller experimenteller Plan ist die Verwendung eines PIC16F1619 als Slave-Implementierung. Es ist schnell und vielseitig genug, um Experimente zum Dehnen der Uhr durchzuführen, einfach genug, um damit zu arbeiten, und häufig genug, damit andere Experimentatoren meine Ergebnisse reproduzieren können. Wenn die Ergebnisse nicht eindeutig sind, kann ich auch ein Experiment mit einem FPGA erstellen. Ich könnte sehen, ob ich mit einem anderen Raspberry Pi in einer Bit-Bashing-Konfiguration als Slave eine angemessene Granularität erzielen kann, aber ich vermute, dass ich etwas ohne ein ganzes Betriebssystem benötigen werde, um Echtzeit-Tests durchzuführen.

Um noch ein paar Dinge anzusprechen, die auftauchten:

Entschuldigung, dass mein ursprünglicher Beitrag unvollständig war; Ich habe versehentlich einen frühen Entwurf gepostet. Ich lasse es so wie es ist, da die Änderungen, die ich vorgenommen habe, ziemlich geringfügig sind.

Ich beanspruche keine Originalität in Bezug auf die Idee, den Taktteiler anzuhalten, während SCL extern niedrig gehalten wurde. Ich habe das woanders gelesen, erinnere mich aber nicht, wo; Ich dachte, es wäre von Gert van Loo im I2C-Clock-Stretching-Thread auf raspberrypi.org , aber ich kann es jetzt nicht finden, also muss ich das woanders gesehen haben. Ich bin nicht davon überzeugt, dass dies das Leistungsprofil erheblich verändern würde.

Der I2C-HW-Block wurde im bcm2835 / 6/7 nicht repariert / geändert und ist wahrscheinlich nicht vorhanden, da dies Antworten des Chips erfordern würde, was einfach viel zu teuer ist.

Ich weiß nicht, wer Advamation ist, aber sie sind der RPF (T) -Gruppe nicht zugänglich, daher kann ich die Richtigkeit der Artikel nicht garantieren.

Sehr geehrte Damen und Herren, ich habe ein sehr seltsames Phänomen auf meinem Pi 2B und 3, ich versuche zu erklären:
Als ich Ende Juni mit der Implementierung des BNO055 begann, verwendete ich einen älteren Raspbian (ich weiß jetzt nicht die Version) und bekam mit i2cdetect viele ungültige I2C-Adressen. Dafür habe ich im Netz gesucht und dieses Forum mit guten Informationen gefunden. Dafür habe ich die I2C-Frequenz wie oben beschrieben geändert und alle Geister verschwinden und ich kann arbeiten. Mitte August habe ich Raspbian auf raspbi-dev 4.14.62-v7 + hochgestuft und das System wurde ein bisschen instabil, aber ich kann arbeiten. Von Update zu Update wurde das System instabiler, und es wurden Lecks auf der SD-Karte festgestellt. Daher habe ich Raspbian über NOOBS neu installiert (Linux raspbi-dev 4.14.62-v7 + # 1134 SMP Di 14. August 17:10:10 BST 2018 armv7l) und ich habe vergessen, die I2C-Frequenz einzustellen, aber es sind keine Geister aufgetreten. Okay, ich benutze keinen Mikrokontroller im Bus, nur MEMS und GPIO Extender, aber ich glaube, es gibt eine Problemumgehung in Raspbians i2c-Code. Außerdem denke ich, dass die erkannten Lecks von einem unvollständigen Upgrade stammen. Ich verwende dieselbe Karte und es werden keine Lecks erkannt.

@ hmf2015 Bei diesem Problem handelt es sich um ein sehr spezifisches I2C-Problem. Probleme mit der SD-Karte werden nicht durch dieses I2C-Problem verursacht. Wenn Ihre SD-Karte nicht richtig funktioniert, sollten Sie eine neue SD-Karte ausprobieren. Einige Karten sind nicht gut und funktionieren nicht mehr schnell. Meine SD-Karte funktionierte letzten Monat nicht mehr und ich musste sie ersetzen.

Normalerweise sind I2C-Geister nicht auf dieses Problem zurückzuführen. Sie treten am häufigsten auf, weil:

  • Sie haben keine gute Stromversorgung. Ich mag diesen .
  • Ihre Kabel sind zu lang. I2C funktioniert nicht gut mit Kabeln, die länger als 1 m sind.
  • Ihre Kabel sind kapazitiv gekoppelt. Wenn Sie die I2C-Pins (SCL und SDA) miteinander verdreht haben, kann dies zu einem Problem führen. Manchmal verwenden Menschen Twisted-Pair-Kabel (wie Ethernet-Kabel), die die I2C-Pins verdrehen und Probleme verursachen. Wenn Sie Twisted-Pair-Kabel verwenden müssen, verdrillen Sie SCL mit Vss (Masse) und SDA mit Vdd (3,3 V). Schauen Sie sich die I2C-Spezifikation in Abschnitt 7.5 an.
  • Ihr I2C-Gerät hat 5V. Der Raspberry Pi führt E / A mit 3,3 V durch. Wenn die Spannungen unterschiedlich sind, kann dies zu Problemen führen. (Der BNO055 benötigt 3,3 V. Wenn Sie ihn also mit 5 V verwenden, liegt ein Problem vor.)

Ich sagte, dass wir über ein bestimmtes Problem sprechen. Einige Geräte können aufgrund dieses Problems Geisterbilder erzeugen, aber nicht viele Geräte. Wenn Geräte aufgrund dieses Problems Geister machen, machen sie nicht viele Geister. Ich denke, dein Problem ist anders.

Ich weiß nicht, was Sie meinen, wenn Sie sagen, dass Sie "Lecks auf der SD-Karte festgestellt" haben. Das ist ein wichtiges Problem, aber es ist kein Problem, über das wir in der Ausgabe dieser Webseite sprechen. In diesem Gespräch geht es um einen bestimmten Fehler. Dieser Fehler betrifft keine SD-Karten.

Ich glaube nicht, dass Raspbian kürzlich die Funktionsweise von I2C geändert hat. Wir denken, dass Raspbian diesen Fehler nicht beheben kann. Wir könnten falsch liegen. Vielen Dank, dass Sie uns davon erzählt haben.

Wenn Sie uns diese Informationen nur mitteilen, um uns zu helfen, dann danken wir Ihnen. Wenn Sie uns diese Informationen mitteilen, um um Hilfe zu bitten, möchten Sie möglicherweise in den Raspberry Pi-Foren nachfragen. In den Foren wird über viele Dinge gesprochen, wie I2C, SD-Karten, GPIO-Extender und vieles mehr. Die Dinge, die Sie sehen, können die gleichen sein, über die wir sprechen, aber sie können verschiedene Dinge sein. Die Leute in den Foren können Ihnen helfen, zu wissen, welche Probleme Sie sehen.

Vielen Dank, dass Sie uns diese Informationen mitgeteilt haben!

Vielen Dank für die Antwort, aber das Problem mit der SD-Karte wurde vom Betriebssystem verursacht. Ich habe die Karte auf meinem (Unix-) Host überprüft und es war in Ordnung, und jetzt funktioniert derselbe CAD nach der Neuinstallation perfekt.
Die Geister auf dem I2C-Bus verschwinden durch eine höhere Frequenz und jetzt, nach der Neuinstallation, erscheinen sie nicht mehr. R / C-Probleme und Reflexionen können meiner Meinung nach ausgeschlossen werden. Ich kenne die 3,3-V-Probleme, aber der minimale 1-Pegel ist geringer.
Das BNO055-Paket verfügt über einen Spannungsregler.
Ich dachte auch, dass die I2C-Probleme die gleichen sein würden wie zuvor, aber im Moment habe ich nicht die Zeit (und das Interesse), in den Quellcode von Raspbian zu schauen, um die Unterschiede zu erkennen. Ich bin interessiert auf einem Arbeitsumfeld.
Die Liste der Elemente sollte nur zeigen, dass ich in einer Andoid-Umgebung (mit einem echten Unix) arbeite, wie es BCM unterstützt, und nicht mit einem Mikrocontroller, den ich über eine serielle Leitung oder USB anschließe, da ich faul bin. In Ihrer Umgebung sind die Bedingungen restriktiver als in meiner, daher kann ich nicht sagen, ob Ihre Probleme geringer werden, aber ich hoffe.

Hallo hmf2015,
Dies ist kein Forum. Dies ist ein Bug-Tracker. Diese Liste von Kommentaren beschreibt einen Fehler, der nicht mit Ihren Problemen zusammenhängt. Bitte besprechen Sie Ihr Problem mit einem geeigneten Forum oder Helpdesk. Auch hier freuen wir uns über Ihre Frage: "Vielleicht ist es dasselbe? Vielleicht hilft meine Beschreibung, diesen Fehler zu lösen?" Aber jetzt wissen wir sicher, dass das, was Sie sehen, nichts damit zu tun hat. Bitte "verschmutzen" Sie diese Diskussion nicht weiter.

@popcornmix
Hallo, vor langer Zeit haben Sie ein Problem mit der I2C-Zustandsmaschine während des Neustarts erwähnt und Code zu diesem Problem veröffentlicht.
Ich bin nicht sicher, was Sie gemeint haben, aber ich habe ein Problem mit dem an I2C angeschlossenen WM8731-Codec.
Nach 2-3 Neustarts legt der I2C-Bus vollständig auf. i2cdetect zeigt außer der ersten Zeile keine Informationen an und legt ebenfalls auf. Die einzige Möglichkeit zur Wiederherstellung ist der Ausschalt- / Ausschaltzyklus.
Sieht das nach einem von Ihnen erwähnten Problem aus?
Ich benutze 4.19 Mainine Kernel.

@ sergey-suloev Wenn i2cdetect nach 8 oder 16 Adressen nicht weiter scannt, würde ich sagen, dass dies nichts mit diesem Problem zu tun hat. Das Problem tritt auf, wenn Geräte die Uhr dehnen, um anzuzeigen, dass sie noch nicht für den nächsten Taktzyklus bereit sind. Als I2C vor fast 40 Jahren entwickelt wurde, war dies möglicherweise auch für Hardware-Implementierungen denkbar. Heutzutage ist die Hardware immer rechtzeitig bereit, um den nächsten Taktzyklus zu bewältigen, da 10 Mikrosekunden Zeit für etwas sind, das in Hardware implementiert ist.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

mohmedelwany picture mohmedelwany  ·  5Kommentare

kucharskim picture kucharskim  ·  7Kommentare

Nuntis-Spayz picture Nuntis-Spayz  ·  5Kommentare

thomasklingbeil picture thomasklingbeil  ·  4Kommentare

HankB picture HankB  ·  8Kommentare