- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 10 von 29

Thema: Senden und empfangen auf dem UART mit ISR kompatibel zur bisherigen RP6lib

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414
    Ich versuche hier mal laut zu denken...
    Es gibt ja die stdio Funktionen, welche man evtl. aus anderen Projekten kennt. Leider führen diese Funktionen zu einer doch recht relevanten code Vergrößerung von ca. üblichen 40 byte RAM und 1400 byte Code, allerdings bieten die auch genormte, erprobte, einheitliche Schnittstellen. Wenn man um jedes Byte Platz in der CPU kämpft, sollte man sie vielleicht vermeiden. Klar! Als einfache "Hallo Welt" Write Funktionen reichen die internen aus der RP6 Lib allemal.
    Entschlackt man aber die Programme und wirft die RP6 Funktionen raus, spart man auch wieder Platz. Die reale Codegröße im Projekt ist also kleiner als die stdio Funktionen auf den ersten Blick brauchen. Ich schätze mal vielleicht 1000 Byte. Nimmt man noch mal den vorhandenen Aufwand für bisher extra schreib/lese Funktionen bei TWI, LCD und File_IO auf SD und EEPROM in der RP6 lib, verkleinert sich der Platzbedarf letztlich noch mal gegenüber der bisher genutzten Write Geschichten. Man braucht ja letztlich nur eine lese/schreib funktion per "device" und den rest erledigt printf/scanf. Allerdings ist man dann an die Möglichkeiten dieser Funktionen auch zunächst gebunden. Viele größere Projekte bauen allerdings auf die stdio auf.

    Eine Ausgabe auf RS232 und alternativ TWI sähe dann so aus:
    Code:
    // Filehandle erstellen
        static FILE uart_io = FDEV_SETUP_STREAM (uart_putchar, uart_getchar, _FDEV_SETUP_RW);
        static FILE twi_io = FDEV_SETUP_STREAM (twi_putchar, twi_getchar, _FDEV_SETUP_RW);
    
    //Zuweisung von Standardkanälen, kann alles mögliche an devices sein
        stdin = stdout = &uart_io;
    //Ausgabe auf Standardkanal
        printf     ("Hello, world!\n");
    //Ausgabe auf TWI-Kanal
        fprintf (twi_io,"Hello, world!\n");
    //jetzt wird TWI-Kanal als Standard Kanal getauscht
        stdin = stdout = &twi_io;
    //Ausgabe auf UART-Kanal
        fprintf (uart_io,"Hello, world!\n");
    //Ausgabe auf twi als Standardkanal
        printf     ("Hello, world!\n");
    Das würde natürllich auch mit scanf, also formatierter Eingabe gehen... und es ständen eben alle Funktionen aus der stdio zur Verfügung.
    Das Ganze hat neben dem Platzbedarf einen großen Nachteil für Anfänger und die Demo-Programme.
    Man müsste entweder die Write Funktionen auf das stio umschreiben was wieder Platz kostet...
    oder man müsste die Demos auf stdio umschreiben was viel Arbeit ist.
    Die stdio Funktionen bieten auch die Formatierungen der rp6 Write Funktionen und mehr... incl. WriteLong und WriteFloat und ähnlichem Krempel.

    Der Nutzen von stdio wächst mit der Komplexität von Ein/Ausgaben, ein Projekt was jedoch nur ab und zu eine debug Meldung absetzt und ansonsten nur als Statemachine Sensoren abfragt, profitiert weniger davon. Aber wenn es auf geregelte Kommunikation ankommt... also bei Funkmodulen, diverse UARTs, I2C zwischen Prozessorboards, Filesystemen usw., ist sie von Vorteil.

    Ich hab ein bischen versucht, die Vor und Nachteile abzuwägen.. nun meine Fragen an euch: Würdet ihr auf stdio umsteigen? Besteht Bedarf für eine angepasste Lib? Wie seht ihr das?

    Gruß
    Geändert von RolfD (23.04.2014 um 13:28 Uhr)
    Sind Sie auch ambivalent?

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hi RolfD,

    prinzipiell finde ich deinen Vorschlag gut, allerdings habe ich Verständnis-Fragen dazu:

    1. Der Hauptzweck mobiler Roboter besteht ja sicher eher nicht darin, Messwerte und Daten in großer Menge ANZUZEIGEN, sondern ihr Verhalten daran auszurichten. Das heißt nicht, dass das Anzeigen von Daten nicht wichtig wäre: Im Gegenteil kann man das gut zur Kontrolle der eigenen Programmierung nutzen. Frage: Braucht man also optimierte Ausgabefunktionen unter der genannten Einschränkung?

    2. Durch die Aufteilung der Prozessoren im RP6-System (Base, M32, M128, M256 WiFi) auf jeweils eigene autonome Systeme müßte man ja im Prinzip die printf/scanf Funktionen für jede dieser Plattformen zur Verfügung stellen (das ist ja bei den jetzigen Funktionen auch so). Macht das Sinn?

    3. Die printf/scanf Funktionen haben ja ihre Hauptvorteile neben den standardisierten Formatierungen in der einfachen Wählbarkeit des Ein-/Ausgabekanals. Das finde ich natürlich auch reizvoll. Aber: Nicht alle "Kanäle" (I2C, UART, SPI, Filezugriff auf SD, int./ext. EEPROM ...) sind auf allen Plattformen verfügbar. D.h. man würde nicht den Zugriff auf alle Kanäle auf jeder Plattform brauchen. Einverstanden?

    4. Reizvoll wäre auch, wenn die verschiedenen Kanäle über das komplette RP6-System von allen Plattformen hinweg angesprochen werden könnten. Das scheitert allerdings daran, dass als alleinige Verbindung zwischen den Plattformen der I2C-Bus vorgesehen ist. Dazu kommen dann nur noch je nach Hardwareausstattung wenige Ein-Ausgabekanäle auf der jeweiligen Plattform. Und: Zur kabelgebundenen Verbindung zum PC wird ausschließlich der UART verwendet, eine Kommunikation ist aber davon abhängig, ob das Interface gerade an die jeweilige Plattform angeschlossen ist. Welche Vorteile könnten printf/scanf Funktionen bei dieser vorliegenden Hardware bringen?

    5. Was meinst du mit "Entschlackt man aber die Programme und wirft die RP6 Funktionen raus, spart man auch wieder Platz."? Die meisten Funktionen in den RP6 Libs sind ja nicht Ein-/Ausgabefunktionen. Was sollte man da rauswerfen (ok, die bisherigen Ein-/Ausgabefunktionen ja auf jeden Fall,- die würden ja durch neue Funktionen ersetzt...), ohne dass Funktionalität fehlt?

    6. Was schätzt du, wie hoch der Aufwand ist, die Ein-/Ausgabefunktionen und ggf. die Demos neu zu schreiben? Würdest du das unter best. Bedingungen angehen?

    7. Würdest du mal eine "Musterfunktion" oder Demo zum Testen hier zeigen?
    Gruß
    Dirk

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    40
    Beiträge
    1.516
    Nett wäre es auf jeden Fall als Alternative. Wirklich vermisst habe ichs aber bislang auch nicht
    Ich hatte das damals absichtlich nicht verwendet - hast ja auch schon gesagt warum (Speicherplatz).

    Alle Beispielprogramme umändern halte ich für nicht sinnvoll.
    Einfach ein zwei neue besser dazu passende (wo man die Vorteile sieht) würde doch reichen.
    Wenn Du das tatsächlich umsetzt, mach evtl. #defines in den Code damit man zwischen beiden Varianten
    wählen kann - oder beides verwenden kann - auf der M256 hat man ja z.B. eh Platz ohne Ende da ist das egal.


    MfG,
    SlyD

  4. #4
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414
    Hallo Dirk & Slyd
    zunächst auf Dirks Fragen bezogen:
    Der Hauptzweck...
    Also das muss jeder für sich entscheiden... was Hauptzweck ist. Ich glaube aber, das man mit dem RP6 mehr unternehmen kann als Linienfolger oder Bumpergesteuerte Rempelbots zu bauen. Je mehr Vernetzung, um so komplexer die Kommunikation.
    Durch die Aufteilung der Prozessoren...
    Richtig. Für die M256 sehe ich da auf Grund von ausreichendem Platz auch kein Problem, bei M32 und Base wirds etwas enger aber auch da nutzt das Slave Programm noch nicht 100% des Platzes, folglich ist auch da noch Platz für solche Änderungen vorhanden. Einzig mit der M128 und ihrem InterpreterC wirds kompliziert aber auch da denke ich, wäre sowas machbar. Ich hab zumindest selbst eine M128 und würde mich dann auch mal daran setzen wollen.
    Einverstanden?
    Richtig. Aber: Man braucht z.B. auf der M32 kein stdio Kanal für die Motorkontrolle aber trotzdem kann man mit Slave und Master von einer m32 aus die Motorgeschwindigkeit regeln.. woran liegt das? Abstrahiere das mal... weil ein Hardware Protokol (i2c) zur Übertragung von Informationen zwischen m32 und Base vorhanden ist! Dazu gehört weiterhin ein Treiberendstück welches auf der Base liegt.. also quasi der i2c-slave .. und der Master.. also quasi der Treiberkopf... betrachtet man nun slave, I2C und master als eine Einheit, so steuert die m32 durchaus den Motor. Ok, Jetzt noch mal zur Frage ob die m32 ein stdio kanal für die Motorsteuerung braucht... die Frage ist eher.. muss es unbedingt so kompliziert laufen wie bisher wenn man was von einem Board aufs andere kriegen will!
    Reizvoll wäre auch
    Habe ich mit dem vorherigen Punkt eigentlich schon angesprochen. Ja es wäre möglich, in einer 2.ten Ausbaustufe Datenströme als * File auch über die Boardgrenzen hinweg bereitstellen zu können weil es die Printf Funktion nicht interessiert ob da einfach nur "while (!(UCSRA & (1<<UDRE))); UDR = (uint8_t)ch;" oder ein ganzes i2c-master/slave System hinter der "putchar" steckt.
    Was meinst du mit ...
    Du hast dir ein Teil des Punktes bereits selbst beantwortet. Überleg aber mal wie eine Ausgabe von Infos als Tabelle bisher ausschaut:

    * writeString_P("Toggle Bit:");
    * writeChar(rc5data.toggle_bit + '0');
    * writeString_P(" | Device Address:");
    * writeInteger(rc5data.device, DEC);
    * writeString_P(" | Key Code:");
    * writeInteger(rc5data.key_code, DEC);
    * writeChar('\n');


    7 Writes... das lässt sich mit printf in einer einzigen Zeile ausgeben! Das meine ich mit entschlacken.
    Was schätzt du...
    Also ich baue grade für mich die UART Lib dementsprechend um. Die UART Lib ist ja zumindest für die Base und M32 gleich.
    Ich werde die Demos sicher nicht anpassen aber ich bin auch dabei, die bisherigen Writes über Kapselfunktionen an printf zu leiten.
    Das sieht dann z.B. so aus:
    Code:
    void writeNStringP(const char *pstring)
    {
        printf_P(pstring);
    }
    void writeInteger(int16_t number, uint8_t base)
    {
        char str[17];
        printf("%s", itoa(number, str, base));
    }
    Ich möchte zunächst die UART LIB fertig bekommen bevor ich mich dann an die M32 LCD Funktionen setze.
    Weitere Ein/Ausgabe Ziele habe ich für mich noch nicht geplant, ich denke aber das es mit der Zeit auch mehr wird. Großes Fernziel ist tatsächlich aber auch die angesprochene Nutzung von Geräten anderer Boards per io Stream. Dazu muss ich aber auch noch mal den I2C Treiber überarbeiten und von registerbasierter Übertragung auf Stream umstellen.
    Für mich stellt sich eigentlich nur die Frage... mach ich das im stillen Kämmerlein so wie meine freeRTOS Geschichten (die übrigends klasse laufen) oder gibts da Interesse auch von anderen die IO Funktionen bezüglich.

    Übrigends ist die SendeISR aus dem Quellcode oben noch verbesserbar.
    Sie wird nach Ende der Übertragung noch ein mal angesprungen nur um die ISR abzuschalten.
    Ich hab sie jetzt so umgebaut, das mit dem letzten Zeichen im Buffer auch direkt die ISR abgeschaltet wird.
    Code:
    ISR(USART_UDRE_vect, ISR_BLOCK) { // wir werden angesprungen, also ist ein char im buffer
    	UDR = tx_buff.ring[tx_buff.tail]; // char aus buffer auf UDR schreiben
    	tx_buff.tail = (tx_buff.tail + 1) % UART_SEND_BUFFER_SIZE; // tail um eins hochzählen
    	if (tx_buff.head == tx_buff.tail) UCSRB &= ~(1 << UDRIE); // sendebuffer leer, isr aus schalten
    }
    Ein paar Kommentare sind auch noch hinzu gekommen.

    Gruß
    Geändert von RolfD (26.04.2014 um 10:23 Uhr)
    Sind Sie auch ambivalent?

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hi RolfD,

    Ich werde die Demos sicher nicht anpassen aber ich bin auch dabei, die bisherigen Writes über Kapselfunktionen an printf zu leiten.
    Das finde ich eine gute Idee. Dann könnten die Demos und bisherige eigene Programme und Libs unverändert bleiben.

    Wenn du dich da dran machst und das hier komplett öffentlich machen willst, bin ich gern dabei.

    Die (Komplett-)Aufgabe wäre dann:

    1. RP6Base:
    RP6BaseLib -> IRCOMM, int. EEPROM

    2. RP6 CONTROL M32:
    RP6ControlLib -> LCD, SPI, int. EEPROM
    RP6Control_I2CMasterLib -> unverändert (wenn übergeordnete I2C-Funktionen unveränderte Funktion bieten)

    3. RP6Base UND M32 (TWI auch für M256):
    RP6uart -> UART
    RP6I2CmasterTWI -> I2C
    RP6I2CslaveTWI -> I2C

    3. RP6 M256 WiFi:
    RP6M256Lib -> LCD, SPI, int. EEPROM
    RP6M256uart -> UART
    RP6M256_WIFIlib -> WIFI UART
    SDC-Library -> SD-In-/Output (eigene Kapsel-Lib?)
    RP6M256_I2CMasterLib -> unverändert (wenn übergeordnete I2C-Funktionen unveränderte Funktion bieten)

    4. RP6 CCPRO M128:
    RP6CClib.cc, RP6CClib.cbas -> nicht möglich (Code-Interpreter)
    Gruß
    Dirk

  6. #6
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414
    Hallo,
    also falls jemand Lust hat da mit rein zu gucken... kommt ja nen Feiertag und Regenwetter Ich poste mal mein aktuellen stand der Lib. Es hat sich bischen was getan.

    Die uart.c incl. grober Beschreibung im Dateikopf:
    Code:
    --- entfernt da neue Version ---
    und die dazu gehörende uart.h
    Code:
    --- entfernt da neue Version ---
    Das ist keine endgültige Fassung, es ist noch nicht alles geprüft und es sind noch Baustellen/Todos und vermutlich Fehler drin.
    Zum Testen und Probieren langts aber schon.
    @Dirk vielen Dank für die Aufstellung... scheint ein größeres Vorhaben zu werden

    Verbesserungen und Anregungen gern hier ins Forum...
    Wer z.B. Lust hat, eine Ein- und Ausgabe Funktin a la uart_getchar / uart_putchar für ein anderes Device als die UART zu schreiben .. immer her damit.
    Ich hab zwar keine M256 aber ich denke, das kriegen wir auch so angepasst.
    Möglich wäre z.B. ein Soundausgabe Treiber (sound_putchar) für den Lautsprecher, welcher Ton Ascii Sequenzen wie "c4,500,g3,200" an den Speaker ausgibt.
    Oder als HEX... Im Format will ich aber nicht vorgreifen... Nur so mal als Denkanstoß... keine Ahnung ob sowas schon existiert.

    Mit der Vorhandenen Lib wäre es dann per stdio möglich, direkt Töne von einem Terminal über den UART an den Lautsprecher aus zu geben.
    Quasi sowas wie ein "Proof of Concept".

    Nachtrag: https://www.roboternetz.de/community...l=1#post453225
    Die Kombination aus der uart_2 lib von void enterString(void) und uint8_t getInputLine(void) entspricht übrigends fast dem Ansatz mit meiner Ascii line editor Eingabezeile... also dem ASCII Modus bei getchar, nur fehlt dort die Reaktion auf \b was aber nachrüstbar wäre. Also ein Beispiel wie man eine ASCII Eingabezeile auf Anwendungsebene realisiert. Und schon 4 Jahre alt... Ist mir grade so aufgefallen als ich den code durchgesehen habe
    Gruß
    Geändert von RolfD (05.05.2014 um 03:15 Uhr) Grund: neue Version der lib im Folgebeitrag
    Sind Sie auch ambivalent?

  7. #7
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414
    Es gibt Neuigkeiten. z.B. xon/xoff im Ascii mode.. und vieles mehr. Diverse Bugs sind auch behoben.
    Ich hab versucht, das ganze im File zu beschreiben und zu kommentieren. Für erfahrene Hasen hab
    ich viel zu viel geschrieben, für Newbies viel zu wenig. Die Lib ist noch nicht fertig bis aufs letzte
    Byte getestet aber sie tut es schon mal ganz gut. Leider meckert das Forum über zu große Dateien,
    ich werde die neuen Versionen einfach als File anhängen. Es sieht erst mal nach viel Programmcode
    aus aber es ist garnicht so viel. Der eigentliche UART Code incl. der stio dürfte bei 2-3 kb sein.
    Dafür kann der Treiber aber auch was...

    Program Memory Usage : 4606 bytes 14,1 % Full
    Data Memory Usage : 308 bytes 15,0 % Full

    Das sind aktuelle Daten aus meinem Testprojekt mit xon/xoff, mit ASCII Edit mode und allem drum
    und dran sinds vielleicht noch 500 oder 1000 Byte mehr.

    Der Remotrol M32 Master (nicht auf alles stdio umgeschrieben, nur Init eingetragen) braucht mit der Lib:

    Program Memory Usage : 13104 bytes 40,0 % Full
    Data Memory Usage : 614 bytes 30,0 % Full

    Die Lib ist also "abwärtskompatibel" zur originalen RP6 UART Lib...

    RP6uart.c RP6uart.h
    Gruß
    Geändert von RolfD (05.05.2014 um 04:13 Uhr)
    Sind Sie auch ambivalent?

Ähnliche Themen

  1. IR Senden und Empfangen mit ATtiny
    Von bnitram im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 03.03.2012, 12:32
  2. Problem mit dem senden von Zeichen per UART
    Von KingTobi im Forum C - Programmierung (GCC u.a.)
    Antworten: 14
    Letzter Beitrag: 30.10.2008, 20:29
  3. Atmega32/STK500 -UART senden/empfangen klappt nicht
    Von Leuchtturm im Forum C - Programmierung (GCC u.a.)
    Antworten: 12
    Letzter Beitrag: 16.01.2007, 14:02
  4. Uart senden empfangen Interrups
    Von ronald im Forum AVR Hardwarethemen
    Antworten: 15
    Letzter Beitrag: 06.03.2006, 20:24
  5. UART ermöglicht Senden, aber kann nicht Empfangen
    Von batti112 im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 18.09.2004, 15:05

Berechtigungen

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

Labornetzteil AliExpress