- Labornetzteil AliExpress         
Ergebnis 1 bis 8 von 8

Thema: Meine ersten Eindrücke des C Programmierens für den Raspi.

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Hallo peterfido,

    mal vorweg, ich kann deine Probleme und den Frust nachvollziehen, aber ich denke du machst zu Unrecht C dafür verantwortlich.

    Alles was du beschreibst, hat mit C wenig zu tun, sondern resultiert aus dem Zusammenwirken oder auch Gegeneinanderwirken von eigenem Programmcode, C-Library und einem Multiuser/Multitasking Betriebssystem. Dazu kommen dann noch andere Programme, gern Kommandos genannt, die man selbst nicht unter Kontrolle hat, und deren Umfang man machmal nicht ahnt.

    Ich versuche das mal an einem deiner Beispiele zu erläutern:

    Ursprünglich sollte alles ein Programm erledigen. Jedoch habe ich es nicht geschafft, wie im BASH ein Programm im Hintergrund /bzw. unabhängig von meinem aufzufrufen. Im BASH wird einfach ein & am Ende des Aufrufes gehängt. Zur Not noch ein disown hinterher. Alles dies klappt per C-Programm nicht mehr. Selbst, wenn ich eine BASH aufrufe, welches dann das nächste Programm mittels "& disown" startet, wartet mein Programm solange, bis die Kette an Sripten und Programmen dazwischen beendet wurden.
    Um ein Programm zu starten (oder im Filesystem zu lesen und zu schreiben, etc), gibt es Systemcalls, die das Betriebssystem veranlassen das zu tun. Die Mechanismen dazu sind auf jedem System und auf jedem Prozessor andere. Eigentlich will der Programmierer das auch garnicht wissen, daher gibt es fertige Funktionen in der C-Library, die das für ihn erledigen (Das gilt natürlich nur, wenn es ein Betriebssystem und/oder ein Filesystem überhaupt gibt). Ein Programm unter Unix zu starten, geht (vereinfacht) so: zuerst wird eine identische Kopie des startenden Programms mit fork() erzeugt. Dann überlädt das erzeugte Programm seinen Code mit dem neuen Programm und setzt möglicherweise noch argv[] auf. Manchmal ist auch noch mehr zu tun. Wenn du das genauer wissen willst, schau dir die man-page von fork() an, und lies dann weiter was unter "SEE ALSO" kommt. Das ganze ist aber nicht Teil von C sondern UNIX, und wird auf einem anderen Betriebssystem anders aussehen.

    Da nicht jeder ein Programm schreiben und kompilieren will, nur um den Inhalt einer Datei zu lesen oder ein Programm zu starten, hat sich im Laufe der Zeit ein ganzer Zoo von Utilities und Hilsprogrammen entwickelt. Dies geht los mit so einfachen Dingen wie echo oder cat und endet bei sed oder der Commandshell (von denen die bash nur eine von vielen ist), die dann nicht nur durch Parameter sondern auch durch Textfiles gesteuert werden können. Alles dies sind aber auch nur Anwenderprogramme, die auf der gleichen Ebene funktionieren, wie dein eigenes Programm.

    Wenn in einem Steuerfile für die Shell an der richtigen Stelle ein & steht, wird also mittels der oben beschriebenen Systemcalls das Programm geforkt, ... und beide laufen nebeneiander weiter. So haben sich die Shell-Erfinder das ausgedacht. Wenn im richtigen Kontext ein | steht, werden die Programme links und rechts vom | gestartet (wie gehabt) und der Output des linken wird auf den Input des rechten geleitet. Ob ein anderes Programm als die Shell das & oder das | gleich verwendet, ist nicht gesagt.

    Für C ist & der "binary and" und | der "binary or" Operator (und innerhalb eines char Arrays, auch gerne String genannt, ist es ein 38 oder 124 und damit nicht mehr als ein gültiger Wert, d.h. 0 <= 38 <= 255).

    Dann sollen vom AVR ankommende Parameter in einer Datei gespeichert werden, damit der php-Code des WebIf diese auslesen kann. Konnte es natürlich nicht. Die Rechte der vom C-Programm angelegten Datei waren mal 600 und dann plötzlich mal 140 oder 104. Also nach dem Erstellen der Datei noch ein system("chmod 644 /tmp/webif.farben"); hinterher.
    Hier wird ein Missverständniss deutlich. In C ändert man die Dateirechte durch einen Call von chmod() oder fchmod(), am besten kümmert man sich darum, wenn man die Datei mit open() oder creat() erzeugt. Du rufst dagegen via system() das externe Programm chmod auf, und läßt das die Arbeit tun. Ja, und system() startet eine Shell, die dann die Zeile "chmod 644 /tmp/webif.farben" gegebenenfalls nach Ersetzung von Wildcards ausführt.

    Für die Sprache C sind das aber nur Funktionsaufrufe: Name, rund Klammer auf, Übergabeparameter, rund Klammer zu, Semikolon. Im passenden Headerfile steht das Format der Parameter, damit der Compiler das checken kann, und der Linker muß die Adresse der Funktion auflösen können. Der Inhalt der Parameter interessiert C kein Stück. Bei deinem Beispiel mit system gilt:
    int system(const char *txtptr);
    so stehts im Headerfile. Was an der Stelle steht, wo txtptr hinzeigt und was das Betriebssystem dann daraus macht, ist dessen Sache.

    Der Text ist ja ganz schön lang geworden, ich will mal versuchen einen Abschluß zu finden. Die Steuerung eines Systems durch direkte Library/Systemcalls kann ganz schön komplex werden. Die Beschreibung der libc umfasst einige tausend Seiten und füllt dazu noch eine ganze Bücherei. Ob du dir das antuen willst, weiß ich nicht. Ich würde eher die Hilfe der anderen verwenden, und eine Scriptsprache verwenden. Unter diesen ist aber die Shell/bash die problematischste. Die Syntax ist durch ewiges Anflicken und kryptische Kürzel von tipfaulen Programmierern alles andere als übersichtlich. Ein Syntaxcheck findet nur beim Ausführen der jeweiligen Zeile statt. Scripte, die lange gut laufen, können plötzlich Syntaxfehler bringen, weil ein if jetzt False statt True liefert. Perl oder PHP sind da die bessere Wahl.

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

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    53
    Beiträge
    765
    Hallo,
    danke für die Informationen. auf fork() war ich auch schon gestossen, jedoch habe ich es nicht angewendet, da in der Beschreibung stand, dass mein Programm als Kopie erneut geöffnet wird und auch alle Parameter soweit übernimmt. Da wusste ich dann nicht, ob dann evtl. die ganzen Routinen nochmals ausgeführt werden oder nicht. Meine Motivation es herauszufinden war gleich Null und so habe ich mich für (erstmal) 3 Programme entschieden, welche soweit prima zusammenarbeiten. Oder halt auch mein Programm in drei Teile geteilt, je nachdem, wie man es sehen möchte.

    Wenn bei BASH am Ende das & quasi zu einem fork() macht, dann hätte mir das eh nicht weitergeholfen, da ich ja den Umweg über eine BASH ein Programm mittels & Parameter probiert habe, was das ursprüngliche Programm auch blockiert hat.

    Die vom GCC compilierten Programme benötigen laut TOP etwas weniger CPU Rechenzeit. BASH wäre auch gegangen, aber das Empfangen über die UART hatte Probleme bereitet. Ich wollte ja solange Empfangen, bis ein CR erkannt wird und dann den String auswerten und nebenbei weiterempfangen. Das Problem am Raspi war, dass bei jedem öffnen der UART ein CHR(255) beim AVR ankam. Was für mich eher nach einem unkontrollieren PIN Zustand aussah.

    Durch das C-Programm habe ich das Sympton nicht. Da kommt nur beim allerersten öffnen der ttyAMA0 ein CHR(255) am AVR an und der wird dann einfach ignoriert. Die Dateirechte gleich beim öffnen mit anzugeben, war auch eine meiner Ideen, jedoch die Suche im Netz nach den richtigen Parametern erfolglos. Und da ich bei jeder Suche nach ein paar erfolglosen Treffern keine Motivation zum Fortsetzen dieser habe, breche ich dann irgendwann diese ab, wenn ich schon einen Umweg im Hinterkopf habe.

    Hauptsache es funktioniert so, wie ich es mir vorgestellt habe. Ob am Ende mein Programm gleich die Rechte setzt, oder diese Aufgabe an das System delegiert, ist mir dann egal. Hauptsache das php Script kann darauf zugreifen (und auch überschreiben, was aber nicht nötig ist, da der AVR eh jeweils die Änderung zurückmeldet). Denn wenn ich die Lichtfarbe über Fernbedienung per AVR ändere, soll halt im WebIf des Raspi diese auch tatsächlich angezeigt und natürlich auch geändert werden können.

    Das parsen konnte ich wieder herausnehmen, denn meine Suche hatte ergeben, dass man "text\"text" in einem String verwenden soll, damit die Hochkommas angezeigt werden. Geholfen hatte dann tatsächlich aber "text 'text.

    Hilfetexte und die Möglichkeit eine andere Schnittstelle und Baudrate per Parameter mit zu übergeben hatte ich erst geplant, dann aber wieder herausgenommen. Durch den veröffentlichten Code kann sich dann jeder selbst diese Werte anpassen.

    Wobei der Code durchaus Kritikfähig sein kann, ich diese aber wenn, so wie du es gemacht hast, lieber hier bespreche als in dem Internetradio-Thema. Der dort veröffentlichte Quelltext hat bestimmt auch einige #Includes zuviel, meine Tests haben aber ergeben, dass GCC diese dann einfach nicht mit einbindet, da die fertigen Programme die selbe Größe hatte, wenn ich mal probehalber welche auskommentiert hatte.

    Was wo in welcher Include zu finden ist, ist mir noch nicht so klar. Da bin ich aber schmerzfrei, wenn es am Ende funktioniert. Die von mir veröffentlichten Quellcodes sehe ich da eher als Inspiration an. Ich meine aber, bei meinen Ausflügen zu c++ etwas mehr Komfort gehabt zu haben. Da lassen sich z.B. Strings einfach per + verbinden, wenn ich mich richtig erinnere. Aber deswegen heisst es ja auch C++ und nicht mehr nur C.

    C an sich mache ich nicht dafür verantwortlich. Eher die Vielfalt an doch recht ähnlichen Sprachen, wo ich das dann schon als Dialekt durchgehen lassen würde. Da ist es halt wie überall sonst auch. Jeder hat da seine eigenen Vorstellungen und auch im Programmieren bzw. der Entwicklung der Sprachen dazu ist Bewegung. Was durchaus Sinn macht, denn was ich für einen Webserver an Befehle benötige, brauche ich nicht unbedingt für eine Kaffeemaschine. Hätte ich damals nicht mit C64 Basic(V2), Amiga Basic/V7??), QBasic(V4??) und später Visual Basic (6 ist da mein Favorit) angefangen, sondern gleich mit C und Co, würde ich mich jetzt wohl schwer tun, VB Code an meine Bedürfnisse anzupassen.

    Aber die Programme sind soweit fertig und jetzt geht es erstmal wieder an die Hardware. Die Soundqualität des analogen Anschlusses ist irgendwie nicht 100% HiFi tauglich. Jetzt teste ich erstmal die nächsten Tage über HDMI, wie da der Ton so ist und vor Allem, ob ein Bufferunderrun vorkommt, denn der Alsa Takt scheint minimal zu schnell zu sein, da der Buffer nach einiger Zeit leer läuft. Leider habe ich nirgends herausgefunden, wie ich diesen Takt beeinflussen kann. Selbst ein Underclocking nutzt nichts, da der Soundteil wohl separat getaktet wird und ich an diesen Takt einfach nicht rankomme. Da ist meine Hoffnung, dass digital übertragen der Empfänger für das Takten zuständig ist. Rauschen und die kleinen Knackser sind über HDMI jedenfalls nicht vorhanden. Leider kostet ein einfacher HDMI>Analog Adapter soviel wie der ganze Raspi. Es gibt noch einen für 19 EUR, dieser wird aber per HDMI gespeist, das möchte ich dem Raspi nicht antun.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

Ähnliche Themen

  1. meine ersten 14tage
    Von TrainMen im Forum Robby RP6
    Antworten: 1
    Letzter Beitrag: 03.06.2009, 15:54
  2. Der RP6 ist da- einige erste Eindrücke
    Von Xtreme im Forum Robby RP6
    Antworten: 51
    Letzter Beitrag: 22.05.2009, 09:06
  3. Asuro vs. Handy: Erste Eindrücke
    Von trapperjohn im Forum Asuro
    Antworten: 48
    Letzter Beitrag: 18.11.2008, 09:22
  4. Antworten: 33
    Letzter Beitrag: 05.12.2006, 19:29
  5. Möchte euch meine ersten Roboter vorstellen...
    Von Mehto im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 17
    Letzter Beitrag: 06.03.2005, 19:45

Berechtigungen

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

Labornetzteil AliExpress