-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Rechenzeitbedarf beim Zahlenausgabe

  1. #1
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.551

    Rechenzeitbedarf beim Zahlenausgabe

    Anzeige

    Das hatte mich nun doch überrascht. Bei einem Testaufbau hatte ich schnell eine Dummyausgabe geschrieben, die mir in Abständen etwas über UART aufs Terminal ausgibt. Der Code im Hauptprogrammabschnitt als Auszug und dazu die Subroutine für die Zahlenausgabe:

    Code:
    / - - - - - - - - - - - - - - -
    ...
        if ( Isec_lk2 == sd )       // Testweise Zeitanzeige und Wobbeln der irLED
        {                           //
          Isec_lk2  = 0;            //
          uputs0 ("\r\tBoardzeit [sek]\t"); //
          uputs0u ( Isecundn );             // 
          uputs0 ("\ttupsi = ");            //
          uputs0u ( Izeit_1 );              //
          if ( Isecundn ==  60 ) sd  =  60; // Ab hier Anzeige alle Minuten
          if ( Isecundn ==  10 ) IRLEDset(275);     //
          if ( Isecundn ==  20 ) IRLEDset( 10);
          if ( Isecundn ==  30 ) IRLEDset(127);
          if ( Isecundn == 300 ) sd  = 300; // Ab hier Anzeige alle fünf Minuten
        }                   // Ende if
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    
    // ============================================================================== =
    // ============================================================================== =
    //      Hilfsfunktion, um Zahlen über das UART auszugeben
      void uputs0u (uint16_t val)   // Zahlen unsigned_Int_16 über UART0 ausgeben
      {
        char buffer[8];
        uputs0 ( utoa(val, buffer, 10) );
      }
    // ============================================================================== =
    // ============================================================================== =
    Und siehe da, der Controller braucht für eine Zehnerpotenz mehr gleich etliche Mikrosekunden mehr. Zur Zeitberechnung: mega168/20MHz, ein tupsi ist eine Zeitscheibe (des internen heart beat) von 50 µs - - also tausend Maschinenzyklen!! Und wenn ich eine Zehnerpotenz mehr über UART ausgeben möchte, rechnet der Ärmste gleich drei von diesen Zeitscheibchen länger . . . das hätte ich nicht gedacht:

    Code:
     Boardtimer on
     C506x00 CiCo m168/babyo/20MHz 14. Sep 2013 18:20
     CIR-Controller, irLED auf PB1
     UART (PD)  mit  57 k Boardzeit [sek] 10 tupsi = 19958
     Boardzeit [sek] 20 tupsi = 19958
     Boardzeit [sek] 30 tupsi = 19958
     Boardzeit [sek] 40 tupsi = 19958
     Boardzeit [sek] 50 tupsi = 19958
     Boardzeit [sek] 60 tupsi = 19958
     Boardzeit [sek] 120 tupsi = 19954
     Boardzeit [sek] 180 tupsi = 19954
     Boardzeit [sek] 240 tupsi = 19954
     Boardzeit [sek] 300 tupsi = 19954
     Boardzeit [sek] 600 tupsi = 19954
     Boardzeit [sek] 900 tupsi = 19954
     Boardzeit [sek] 1200 tupsi = 19951
     Boardzeit [sek] 1500 tupsi = 19951
     Boardzeit [sek] 1800 tupsi = 19951
     Boardzeit [sek] 2100 tupsi = 19951
     Boardzeit [sek] 2400 tupsi = 19951
     Boardzeit [sek] 2700 tupsi = 19951
     Boardzeit [sek] 3000 tupsi = 19951
     Boardzeit [sek] 3300 tupsi = 19951
     Boardzeit [sek] 3600 tupsi = 19951
     Boardzeit [sek] 3900 tupsi = 19951
    Ciao sagt der JoeamBerg

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.03.2011
    Beiträge
    1.397
    @oberallgeier

    Wenn ich dich richtig verstehe, geht es um diese Zeile:

    uputs0 ( utoa(val, buffer, 10) );

    Da verbrauchen zwei Funktionen Zeit: utoa() und uputs0(). Versuch die Zeiten mal zu messen. Mal so als Pseudocode:

    setportbit();
    utoa(val, buffer, 10);
    clearportbit();
    uputs0(buffer);

    Wenn man das Portbit auf dem Scope ansieht, kann man die "utoa-Zeit" messen, die "uputs0-Zeit" kann man an der TX-Leitung der seriellen ansehen.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von malthy
    Registriert seit
    19.04.2004
    Ort
    Oldenburg
    Beiträge
    1.379
    Hey,

    habe mich jetzt nicht weiter gedanklich vertieft, aber kann es sein, dass hier die Zeit zum Tragen kommt, die das eigentliche Senden hardwaremäßig benötigt? Bei 57 kbaud solltest du etwa 1/(57000 kbaud/9 bit) = 1.58e-4 s/byte = 158 µs/byte benötigen - solange dauert das serielle(!) Senden auf dem UART. Also will sagen, bis das nächste Byte verschickt werden kann, dauert es unter allen Umständen ca. 160 µs (wenn ich mich nicht verrechnet habe). Kann aber natürlich auch sein, dass ich das Problem falsch verstanden habe ...

    Gruß
    Malte

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.551
    Zitat Zitat von Klebwax Beitrag anzeigen
    ... Versuch die Zeiten mal zu messen. Mal so als Pseudocode: ...
    Danke für den Tip, ich habe manchmal so meine Schwierigkeiten mit dem Messen von Zeiten - mit nem simplen, analogen Oskar - ohne Speicher, nicht triggerbar auf ein bestimmtes Vorkommnis - da bleibt mir halt in einigen Fällen nur das Messen wie hier gezeigt. Und das reicht doch ... siehe unten.

    Zitat Zitat von malthy Beitrag anzeigen
    ... kann es sein, dass hier die Zeit ... die das eigentliche Senden hardwaremäßig benötigt ...
    Ja, so sehe ich das auch - und das ist ja das Erschreckende. Gefühlt ist so eine kleine Meldung schnell draussen. Da ich demnächst Daten per UART von einem Controller an den anderen senden will, sollte ich mal etwas genauer hinsehen - hat sich ja auch gelohnt (denn die Nachrechnerei hatte nicht so mit den Messwerten zusammengepasst). Gelohnt? Ich habe den RX- und den TX-Puffer zum FIFO von 16 auf 240 gesetzt - und siehe da - es geht schon recht ratzfatzer als vorher *ggg*.

    Erste Messung: RX- und TX-Puffer sind 16 Bytes
    Zeite Messung: Kleinere Byteanzahl (Text in Kurzform)
    Dritte Messung: RX- und TX-Puffer sind 240 Bytes und Text wieder in Langform wie 1.
    Code:
            Boardtimer on
            C506x00 CiCo m168/babyo/20MHz 14. Sep 2013 19:55
            CIR-Controller, irLED auf PB1
            UART (PD)  mit  57 k        Boardzeit [sek] 10      tupsi = 19958
            Boardzeit [sek] 20      tupsi = 19958
            Boardzeit [sek] 30      tupsi = 19958
            Boardzeit [sek] 40      tupsi = 19958
            Boardzeit [sek] 50      tupsi = 19958
            Boardzeit [sek] 60      tupsi = 19958
            Boardzeit [sek] 120     tupsi = 19954
    
            Boardtimer on
            C506x00 CiCo m168/babyo/20MHz 15. Sep 2013 19:10
            CIR-Controller, irLED auf PB1
            UART (PD)  mit  57 k
            B       10      t       19999
            B       20      t       19999
            B       30      t       19999
            B       40      t       19999
            B       50      t       19999
            B       60      t       19999
            B       120     t       19999
            B       180     t       19999
            B       240     t       19999
            B       300     t       19999
    
            Boardtimer on
            C506x00 CiCo m168/babyo/20MHz 15. Sep 2013 19:40
            CIR-Controller, irLED auf PB1
            UART (PD)  mit  57 k    RX/TX-Puffer 240
            Boardzeit [sek] 10      tupsi = 19998
            Boardzeit [sek] 20      tupsi = 19998
            Boardzeit [sek] 30      tupsi = 19998
            Boardzeit [sek] 40      tupsi = 19998
            Boardzeit [sek] 50      tupsi = 19998
            Boardzeit [sek] 60      tupsi = 19998
            Boardzeit [sek] 120     tupsi = 19998
            Boardzeit [sek] 180     tupsi = 19998
            Boardzeit [sek] 240     tupsi = 19998
            Boardzeit [sek] 300     tupsi = 19998
            Boardzeit [sek] 600     tupsi = 19998
    Kleine Erläuterung zur Messzeit in "tupsi". Mein Heartbeat wird über meinen üblichen 50µs-Timer getoggelt - alle Sekunden einmal toggeln. Der 50µs-Timer ist für viele Zwecke praktisch, es gibt für bestimmte Auslöser auch lokale Counter, hier der "Isec_lk2", der mit dem Heartbeat-Toggle und der Zählung der Boardzeitsekunde hochgetickert wird. Die Ausgabe im Test, siehe erstes Posting, erfolgt, sobald der Isec_lk2 den abgefragten Wert erreicht hat - dieses Umschalten geschieht genau dann, wenn der 50-µs-Counter Izeit_1 von 0 auf 20000 gesetzt wird. Die Messzeiten sind also von 20000 abwärts zu werten.

    Manchmal lohnt sich das Nachgucken, -denken, -fragen, -posten ...
    Jedenfalls danke euch Beiden für die Denkanstöße. Schönen Sonntag
    Geändert von oberallgeier (15.09.2013 um 20:11 Uhr)
    Ciao sagt der JoeamBerg

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von malthy
    Registriert seit
    19.04.2004
    Ort
    Oldenburg
    Beiträge
    1.379
    Zitat Zitat von oberallgeier Beitrag anzeigen
    Ja, so sehe ich das auch - und das ist ja das Erschreckende.
    Naja, "erschreckend" ist vielleicht übertrieben, denn was den eigentlichen Sendevorgang angeht, ist "57000 baud" und "158 µs/byte" ja gleichbedeutend (bei 8 Datenbits/ 1 Stoppbit) - und in dem Sinne zu erwarten. Ich wollte auch nur den Unterschied machen zwischen "solange dauert das Senden" und "solange ist die CPU blockiert". Letzteres ist nämlich m. M. n. eben nicht der Fall, der UART kümmert sich ja um Verschicken, in der Zeit kann man ja gut was anderes machen.

    Gruß
    Malte

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.03.2011
    Beiträge
    1.397
    Zitat Zitat von oberallgeier Beitrag anzeigen
    Danke für den Tip, ich habe manchmal so meine Schwierigkeiten mit dem Messen von Zeiten - mit nem simplen, analogen Oskar - ohne Speicher, nicht triggerbar auf ein bestimmtes Vorkommnis - da bleibt mir halt in einigen Fällen nur das Messen wie hier gezeigt.
    Da gibts ein paar Möglichkeiten. Wenn das, was man messen will wiederholt vorkommt, kann man es auch auf einem analogen Scope darstellen. Wenn es sich schlecht triggern läßt, kann man ein Triggersignal auf einem freien Portpin programmieren und das auf den zweiten Scopekanal (oder falls vorhanden auf den externen Trigger) geben und damit triggern.

    Ist das Ereignis nicht periodisch genug, hab ich ab und an schon mal zum Messen das Program umgeschrieben.

    Inzwischen benutze ich dafür eigentlich immer den saleae.

    Ja, so sehe ich das auch - und das ist ja das Erschreckende. Gefühlt ist so eine kleine Meldung schnell draussen.
    Schnittstellen, insbesondere die asynchrone serielle, sind schon eine ziemliche Bremse. Sie können das Echtzeitverhalten eines Systems empfindlich stören. Ich benutze die serielle daher sehr selten. Leider ist der UART via USB die einfachste Schnittstelle und daher das Mittel der Wahl zum Datenaustausch. Ethernet wäre wesentlich besser, ist aber leider aufwendig auf einem µC und hat seine eigenen Zeitanforderungen. SPI mit einigen 10MHz wäre ganz gut, kann aber ein PC nicht wirklich.

    Ein größerer Buffer oder ein UART mit FIFO sind schon mal gut, aber wenn mehr Daten gesendet werden sollen, als Zeit vorhanden ist, hilft auch kein größerer Buffer. Was bleibt, ist die serielle gezielt und sparsam einsetzen.

    Ein LCD, am besten im 8 Bit Mode an einem kompletten Port, ist auch hilreich. Man darf dann nur nicht auf die gängigen Ratschläge hören und den Code mit Delays vollpflastern, sondern geschickt das Ready-Signal auswerten. Dann kann man ein Zeichen so in 2 µs ausgeben. Da kann man dann schon im PWM Interrupt den PWM-Wert Live ausgeben.

    Wenn man die Leistung moderner µCs wirklich ausnuzt, ist eine Datenausgabe schon problematisch. Leider

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  7. #7
    Erfahrener Benutzer Roboter Genie Avatar von malthy
    Registriert seit
    19.04.2004
    Ort
    Oldenburg
    Beiträge
    1.379
    Schnittstellen, insbesondere die asynchrone serielle, sind schon eine ziemliche Bremse.
    Naja, in welchem Sinne? Klar, bei einer gegebenen Übertragungsrate kann man eben nur eine dementsprechende Datenmenge drüberblasen. Aber das ist doch völlig deterministisch, oder? Und das reine Schreiben in das UART Register geht ja dann wieder recht schnell, das meinte ich oben, als ich schrieb, dass man während des Sendens dann ja durchaus wieder andere Dinge tun kann. Oder übersehe ich etwas?

    Gruß
    Malte

  8. #8
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.551
    ... ist die CPU blockiert" ... eben nicht der Fall, der UART kümmert sich ... in der Zeit kann man ...
    Genauso dachte (hoffte) ich eben auch. Daher meine Verwunderung (ok, "Erschrecken" wars nicht) über den Zeitbedarf von schlappen 46 tupsi, siehe mein erstes Posting, Boardzeit 300 s. In üblichen Zeitenheiten also 46 x 50 µs, das sind 2300 µs. Verschickt wurden dabei 37 Byte (incl. Zeilenvorschüben und Tabs), das macht bei meinen 57600 Bd und 9 Bit/Byte rund 156 µs/Byte 5,78 ms oder 115 tupsi. Benötigt hatte ich aber nur 46 - also ist könnte doch alles in Butter und ich zufrieden sein ! ?

    Neee, denn das genaue Hinsehen hatte sich gelohnt, hatte mich zu einer Vergrößerung der Puffer überredet, die vergrößerten Puffer haben dazu geführt, dass nur rund 100 µs (2 tupsi) benötigt wurden für theoretisch 5,8 ms Sendezeit des UART (- also genau Deine Rede malthy!). Und da steckt dann tatsächlich die Arbeit des Hardware-UART - der ja im Hintergrund rödelt. Wenn man ihm nur genug Puffer zuweist, sogar sehr effektiv.

    Wobei ich ja ziemlich sicher bin (könnte fast sagen ich wüsste es) dass die Zeitangabe de fakto geschönt ist - der Controller ist im Programm weitergegangen, weil er ja in dieser Zeit die Bytes schon/nur in den Puffer geschrieben hatte - damit der UART sie danach gemächlich über den Draht schicken kann, während er - der Controller, weiter arbeitet.
    Ciao sagt der JoeamBerg

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.03.2011
    Beiträge
    1.397
    Zitat Zitat von malthy Beitrag anzeigen
    Naja, in welchem Sinne? Klar, bei einer gegebenen Übertragungsrate kann man eben nur eine dementsprechende Datenmenge drüberblasen. Aber das ist doch völlig deterministisch, oder? Und das reine Schreiben in das UART Register geht ja dann wieder recht schnell, das meinte ich oben, als ich schrieb, dass man während des Sendens dann ja durchaus wieder andere Dinge tun kann. Oder übersehe ich etwas?
    Das reine Laden eines Registers ist schnell, das Warten, bis das Register wieder frei ist, eine andere Sache.

    Was ich aber meinte ist, daß leicht viel mehr Daten entstehen als die serielle transportieren kann. So ein ADC liefert schon mal 10k bis 100k Daten pro Sekunde, andere Sensoren leicht ebensoviel. Jetzt mal eine komplexe Rechnung, Sensorfusion oder Filterung durch ein paar serielle Ausgaben live zu Debuggen oder Darzustellen kann leicht dazu führen, daß das Zeitverhalten mehr von der seriellen Schnittstelle als von den Sensoren abhängt.

    Wenn man jetzt vom PC gewöhnt ist, daß so ein paar printf() mit einigen 10kB oder auch MB (auch mal in eine Datei umgeleitet) ohne ein paar PWMs oder Schrittmotoren im Hintergrund und mit einigen Gigabyte als Speicher kein Problem sind, kann einen das schon "Erschrecken".

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    59
    Beiträge
    2.435
    Zitat Zitat von malthy Beitrag anzeigen
    Naja, "erschreckend" ist vielleicht übertrieben, denn was den eigentlichen Sendevorgang angeht, ist "57000 baud" und "158 µs/byte" ja gleichbedeutend (bei 8 Datenbits/ 1 Stoppbit) - und in dem Sinne zu erwarten.
    Die Rechnung stimmt so gar nicht.
    Du hast ein Startbit, die Daten und das Stoppbit.
    Bei 8-Bit Daten sind das dann mindestens 10 Bitzellen, ergibt dann etwa 175µs.
    Dann könnte man noch das Parity-Bit zuschalten und das Stoppbit, kann1, 1.5 oder 2 Bit-Zellen lang sein.
    Im Extremfall kommt man dann auf 1+8+1+2 = 12 Bitzellen.
    Die längeren Stoppbits waren eigentlich dafür gedacht, dem Empfänger etwas mehr Zeit zum Abholen und Auswerten des gerade Empfangenen Bytes zu geben. Sonst haben sie technisch keine Bedeutung.
    Die Verwendung von 5 Datenbits stammt noch vom Telex. So vor 35 Jahren wurden Telexe als TTY oft als Terminal für Computer verwendet.
    7 Datenbits war die Norm für den alten ASCII-Code, welcher nur 7 Bits benutzte, dass es auch noch Umlaute und andere Sonderzeichen gibt, wussten die AMIs lange Zeit nicht

    MfG Peter(TOO)

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Problem beim Konfigurieren von TIMER1 beim M32-Board
    Von dirty_bird_981 im Forum Robby RP6
    Antworten: 8
    Letzter Beitrag: 10.01.2012, 23:52
  2. Fehler beim Selbsttest
    Von Asimo im Forum Asuro
    Antworten: 0
    Letzter Beitrag: 09.08.2008, 16:32
  3. Fehlerhafte Zahlenausgabe bei RN-Digi
    Von FuX im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 27.04.2008, 05:42
  4. Busfrequenz beim PCF8574 und beim PCF8591?
    Von roboter im Forum Elektronik
    Antworten: 2
    Letzter Beitrag: 17.04.2007, 15:34
  5. Antworten: 9
    Letzter Beitrag: 14.03.2005, 21:08

Berechtigungen

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