- LiFePO4 Speicher Test         
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 26

Thema: Asuros SerWrite(..) - Verständnisproblem

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    31.07.2005
    Ort
    Ehningen
    Alter
    50
    Beiträge
    35

    Asuros SerWrite(..) - Verständnisproblem

    Anzeige

    E-Bike
    Guten Abend allerseits,

    ich hab' heut mal ein bisschen in die Funktion SerWrite der asuro.c 'reingeguckt:
    Code:
    /* function for serial communication */
    void SerWrite(unsigned char *data,unsigned char length)
    {
    	unsigned char i = 0;
    	UCSRB = 0x08; // enable transmitter
    	while (length > 0) {
    		if (UCSRA & 0x20) { // wait for empty transmit buffer
    			UDR = data[i++];
    			length --;
    		}
    	}
    	while (!(UCSRA & 0x40)); 
    	for (i = 0; i < 0xFE; i++)
    		for(length = 0; length < 0xFE; length++); 
    }
    Kann mir jemand den Sinn der letzten beiden Zeilen der Funktion erklären?
    Was ich noch verstehe: alle Zeichen werden erfolgreich gesendet, und der ATmega meldet schließlich "Transmit Complete" (UCSRA wird = 0x40).
    Was ich nicht verstehe: anschließend wird noch einmal i von 0 bis 0xFE durchlaufen und unterlagert length von 0 bis 0xFE. Dabei wird aber keinerlei Aktion ausgeführt; und da beide eh' nur lokale Variable bzw. lokale Kopie eines Argumentes sind, werden sie auch nicht beeinflusst.
    Was ich gern wüsste: warum das, übersehe ich was? Was macht da der Compiler draus, wird sowas wegoptimiert (zumindest sofern ich nix übersehen habe...)?

    Interessant fand ich, dass der Prozessor sich beim Schreiben auf die serielle Schnittstelle tatsächlich ausschließlich auf das Senden "konzentriert", während nebenher z. B. die Motoren und irgendwelche Regler laufen. Wenn Zeit also knapp ist, besser keine oder nur ganz kurze Ausgaben über die serielle Schnittstelle - oder gibts andere Trix, die ich nicht kenne?

    Schlaut mich bitte auf!

    Gruß,
    Rakke

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von m.a.r.v.i.n
    Registriert seit
    24.07.2005
    Ort
    Berlin
    Beiträge
    1.247
    Hallo Rakke,

    die beiden letzten Zeilen sollen eine Warteschleife darstellen.
    Wie du schon richtig vermutest wird sowas der Compiler wegoptimieren.
    Sieht zumindest so aus, wenn man ins Asm Listing schaut (spreche allerdings nicht fließend Assembler).
    Einfach mal die beiden Zeilen weglöschen und sehen ob beim Senden Zeichen verloren gehen.

    Besser wäre es, die SerWrite und SerRead Funktionen auf Interrupt Betrieb umstellen, dann wird nicht unnötigt Zeit vertrödelt.
    Wäre doch ne hübsche Aufgabe?

    Gruß Peter

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    31.07.2005
    Ort
    Ehningen
    Alter
    50
    Beiträge
    35
    Hei Peter,

    hm, Warteschleife: warten worauf? (Christkind ?) Die Funktion wird ja danach beendet... Habe jetzt auch mal das Assemblerzeug angeguckt, verstehe aber nur Bahnhof.

    Ansonsten: au ja Interrupt! Jetzt kommen ja ein paar ruhigere Tage, da könnte wohl etwas mehr Zeit übrigbleiben als in der "oh-je-was-schenke-ich-Doris"-Vorweihnachtszeit.

    Bloß muss ich dafür erstemal den CVS-Kram fürs Sourceforge ans Laufen bringen, damit ich nicht wieder quer zu existierenden asuro.c/h arbeite. Das müsste doch bei dir schon laufen (als SF-Admin...) - wie kann ich mich am geschicktesten informieren? Muss ich fürs SSH irgendwas installieren? Gibts da an zentraler Stelle eine Info, die man im asuro-lib-thread verlinken könnte?

    Alaaf,
    Rakke

  4. #4
    Erfahrener Benutzer Roboter Genie Avatar von m.a.r.v.i.n
    Registriert seit
    24.07.2005
    Ort
    Berlin
    Beiträge
    1.247
    Hallo Rakke,

    Vielleicht braucht der IR Transceiver noch eine Zwangspause zwischen einzelnen Zeichen?

    ich benutze smartcvs als CVS client. Gibt es bei http://www.smartcvs.com.
    Die Einrichtung und der Zugriff auf Sourceforge ging damit problemlos.
    SSH Client ist auch dabei.
    Die Demoversion sollte für den normalen Gebrauch ausreichen.
    Werde mal eine Doku zum Einrichten dafür schreiben.

    Gruß Peter

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    31.07.2005
    Ort
    Ehningen
    Alter
    50
    Beiträge
    35
    Hei Peter,

    danke für die fixe Antwort, ich mach mich mal dran (wenn die Tanne geschmückt ist usw.).

    Über eine Stichpunktdoku würde sicher nicht nur ich mich freuen!

    Alaaf,

    Rakke

  6. #6
    Erfahrener Benutzer Roboter Genie Avatar von m.a.r.v.i.n
    Registriert seit
    24.07.2005
    Ort
    Berlin
    Beiträge
    1.247
    Hallo Rakke,

    im CVS ist jetzt auch eine Doku zur Einrichtung des CVS Clients (für SmartCVS).

    Ich habe mich noch mal mit der Warteschleife in der SerWrite Funktion befaßt. Der Code wird nicht wegoptimiert sondern tatsächlich ausgeführt.
    Das heißt, diese Wartezeit scheint doch notwendig zu sein, damit es mit der IR-Schnittstelle funktioniert.
    Vielleicht ist das auch der Grund warum der BootLoader von linux_80 bei einer Drahtverbindung funktioniert, nicht aber über die IR-Schnittstelle.

    Das macht das Umstellen der Sendefunktion auf Interrupt Betrieb natürlich um einiges aufwändiger.

    Gruß Peter

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Hallo zusammen,
    zum Thema mit der Warteschleife: Ich habe sie weggelassen und habe keinen Datenverlust beim Senden.
    Die Funktion überprüft ja nach dem letzten gesendenen Byte, ob es gesendet wurde und damit der Buffer wieder frei ist. --> while (!(UCSRA & 0x40)); <---


    INTERRUPT-BETRIEB
    Ich bin gerade dabei die Schnittstelle, und alle anderen Sensoren, auf Interrupt-Betrieb umzustellen.
    Ist aber noch nicht spruchreif, so dass ich noch keinen Code posten kann.

    Eins vorweg:
    Ich werden wohl nur das Senden über Interrupt gesteuert ausführen. Das Empfangen werde ich im Moment erst mal im pollenden Betrieb lassen.
    Begriffe:
    -> Senden: Asuro sendet.
    -> Empfangen: Asuro empfängt

    Grund:
    Wenn beides per Interrupt läuft, dann hat das aufrufende Programm nicht mehr die Kontrolle in Bezug auf gleichzeitiges Senden und Empfangen. (Sendepuffer noch gefüllt [Interrupt sendet auch lustig weiter], aber es soll auch gleich noch der Empfänger aktiv sein) Hier tritt bei mir grundsätzlich das Problem auf, dass ich meine eigenen gesendeten Zeichen als Echo selbst empfange. Dies macht 'leichte' Probleme, bzw. macht es auch für einen echten Sender (PC) unmöglich, in den geechoten Datentransfer vom Asuro zum PC korrekte Infos vom PC zum Asuro zu bringen.

    Weiteres Problem:
    Wenn die zu sendenen Daten vom Hauptprogramm nur 'abggegeben' werden, um sie per Interrupt auf die Reise zu bringen, dann muss das Interruptsystem dafür einen Puffer bereitstellen.
    Genau hier haben wir etwas zu wenig Speicher im Asuro um großzügig damit umzugehen.
    Als Anzatz habe ich eine feste Pufferlägne gewählt, damit man nicht noch mit malloc hantieren muss. (Die Funktion ist OK, aber viel zu groß)
    Wenn jetzt also dieser statischte Puffer voll ist, soll meine Funktion, wie gehabt, in den pollenden Betrieb wechseln. Genau hier bin ich jetzt bei der Software.

    Viele Grüße vom Sternthaler.

    P.S.: Ich wünsche allen einen guten Rutsch ins Neue Jahr.

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    31.07.2005
    Ort
    Ehningen
    Alter
    50
    Beiträge
    35
    Hei Sternthaler,

    an die Geschichte will ich ja auch noch 'rangehen. Habe bislang nix codiert, nur gedacht:
    wenn der Funktion "Senden" nur ein Zeiger auf den Sendetext übergeben wird, und die Funktion selbst nur ein Feld mit Zeigern verwaltet (z. B. Platz für fünf Zeiger), dann müsste der Speicherbedarf überschaubar klein bleiben (die Sendetexte sind ja eh' schon vorhanden im Speicher, keine zusätzliche Belastung also, und je char* sollten nur zwei Byte belegt werden, bei fünf Pointern also ca 10 Byte - geht, oder?).

    Auch ich würde zunächst nur die Sendefunktion modifizieren.

    Wie wärs, wenn wir uns mit der Bearbeitung abstimmen, z. B. Schnittstellendef., Kompatibilität mit vorhandener Funktion etc.?

    Egal wie, guten Rutsch,

    Rakke

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Hallo Rakke,
    die Idee mit dem Zeiger gefällt mir nicht so recht.

    Wenn das Hauptprogramm also den Speicher zur Verfügung stellt, und z.B. eine Variable mit den zu sendenen Daten nutzt, und nur die Adresse/den Zeiger an die Interrupt-Funktion gibt, dann kann das Hauptprogramm ja schliesslich weitermachen und neue Daten in diese Variable schreiben.
    Jetzt kommt die 'langsame' sendende Interruptfunktion und liest die vom 'schnellen' Hauptprogramm schon wieder geänderten Daten.
    Somit ist der erste Inhalt dieser Variablen noch gar nicht komplett gesendet worden.

    Wenn du, wie du vorschlägst, mehrere Zeiger in der Interruptfunktion verwalten möchtest, dann muss auch das Hauptprogramm 'wissen' wann diese Zeiger wieder benutzt werden dürfen, nachdem die dort hinterlegten Daten komplett gesendet wurden. Ich glaube, dass damit die Verwaltung im Hauptprogramm wieder zu groß wird. (Glauben heist aber nicht wissen.)

    Zur Abstimmung bei der Bearbeitung:
    Ich möchte den in der originalen asuro.c-Library angegeben Funktionsaufruf exakt weiter so benutzten.
    Zum einen ist die Funktion ja schon bei allen ASURO-Freaks im Einsatz, und zum anderen habe ich mir überlegt, dass es keinen Sinn macht z.B. die lenght-Variable wegzulassen und nur Strings als data-Variable in die Funktion zu geben. Möglich wäre es, wenn wir immer nur Daten mit dem in C notwendigen '\0' als Endekennung eines Strings hätten.
    Ich selbst nutze die Sendefunktion aber auch um 'pure' Daten zu senden. Also z.B. einzelne Messwerte der Sensoren, die ich dann mit einem kleine Programm am PC empfange und auswerte.

    Wenn hier aber andere Ideen kommen, z.B. doch ein Ansatz mit den Zeigern, dann immer her damit.

    Viele Grüße vom Sternthaler

    Nicht mehr lang, und wir rutschen.

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    31.07.2005
    Ort
    Ehningen
    Alter
    50
    Beiträge
    35
    Guten Abend zusammen,

    erstmal frohes neues Jahr allerseits!

    @Sternthaler: leider kenne ich mich mit dem tiefsten inneren von einem C-Programm nicht sooo genau aus. Ich hatte das immer so verstanden: wenn ich irgendeinen String senden möchte, muss der irgendwo im Flash abgelegt sein und entsprechend kann man einen Pointer übergeben. Da im Flash, kann nix nicht überschrieben werden. Dabei habe ich nicht mit "echten" Variablenwerten gerechnet, und funktioniert auch bei lokalen (automatischen) Variablen ganz schlecht.
    Hm, bleibt nur die übliche Vorgehensweise mit einem Puffer, in den die Daten geschrieben werden und damit vor Veränderungen sicher sind. Das kostet aber wieder Bytes...

    Du sprichst noch einen anderen Punkt an: die zeitliche Zuordnung zwischen UART-Ausgabe und Hauptprogramm geht bei Interruptnutzung flöten. Heute wartet das Hauptprogramm mit der weiteren Arbeit, bis die Daten versendet sind. Fürs debugging ist das sicherlich einfacher als wenn ("in Zukunft") die Daten zwar zeitnah, aber nicht notwendigerweise synchron verschickt werden. Außerdem könnte das Hauptprogramm soviel Fahrt haben, dass es Sendedaten schneller in einen Puffer schreibt, als gesendet werden kann - noch so etwas, worauf man heute nicht achten muss.

    Die Sendefunktion sollte also auf jeden Fall einen Rückgabewert besitzen wie "Puffer voll"; vielleicht wäre auch eine "Prüfen ob Puffer voll"-Funktion nicht schlecht. Mit der ließe sich dann die zeitliche Kopplung wieder herstellen: einfach warten, bis der Puffer leer ist, dann schreiben und weitermachen.
    Auf diese Weise lässt sich die Interruptgeschichte dann flexibel nutzen: wenn nötig, wird auf die serielle Schnittstelle gewartet, wenn nicht erforderlich, nicht.

    Mal weiter drüber nachdenken...

    Gruß

    Rakke

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

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

12V Akku bauen