ok, aber selbst wenn ich sähe, dass es funktioniert, dann wüsste ich dennoch nicht, wie ich das in meinen Code reinbringen soll.
Danke aber auf jeden Fall für die Mühe!
Druckbare Version
ok, aber selbst wenn ich sähe, dass es funktioniert, dann wüsste ich dennoch nicht, wie ich das in meinen Code reinbringen soll.
Danke aber auf jeden Fall für die Mühe!
@HaWe: Das hier ist der komplette Code der Laufen soll?
https://www.roboternetz.de/community...l=1#post652711
Das bedeutet du hast nur das Protokoll zum AVR und einen Keyboard Thread und einen UART Thread. Richtig? Das ganze soll dann "irgendwie verheiratet werden" was aber noch nicht da ist.
Das schaut dann so aus:
Dazu soll dann noch vermutlich IO vom PI?Code:Aktueller Stand
+---------+ +-------------+ +--------+
| AVR |+---->ttyACM0----->| UART Thread |+---->| Logik |
+---------+<-----------------++-------------+<----+| |
| |
| |
+---------+ +-------------+ | |
| Keybrd |+----------------->| Kbrd Thread |+---->| |
+---------+<-----------------++-------------+<----+| |
| |
| |
| |
| |
+--------+
Hier kann man ASCII malen ;)
http://stable.ascii-flow.appspot.com
hallo,
das ist erst die Basis, die tokens werden dann ausgewertet und als Sensorwerte verarbeitet oder die entsprechenden GPIOs geschaltet.
Dadurch stehen dann dem Raspi zusätzlich z.B. die 16 ADCs und die 54 digital GPIOS des Mega zur Verfügung plus die Peripherie, die am Mega angeschlossen ist.
Es kommen dann weitere threads hinzu, z.B. für Encder lesen, Navigation aus Odometrie und IMU+GPS, Fernsteuerung, Bildschirmanzeige, PID-Regler, autonome Aktionen wie Wegefindung u/o SLAM.
PS,
ich bin an einer Sache dran, kritische threads asynchron zu starten und mit pthread_cancel ggf. zu stoppen...
Da du pthread_cancel ansprichts, hier gibt es etwas zu lesen für dich:
https://lwn.net/Articles/683118/
Das Problem das ich hier eben sehe, das mein Design mit den Prozessen nicht hat, sind nicht frei gegebene Betriebsystemresourcen wie bsp der offene Filedescriptor für ttyACM0. Da dein Projekt ja der RB6 ist und er recht lange laufen soll, könnte es passieren dass deinem Prozess die Filedescriptoren aus gehen, wenn diese nicht frei gegeben werden. Den Wert kann man erhöhen. Standardmäßig ist er glaub 1024, aber er kann nicht beliebig hoch gesetzt werden wegen begrenzter Resourcen auf dem Zielsystem.
Zur Erklärung ein Beispiel:
Wenn der ttyACM0 vom USB abgezogen wird, während der Thread hier einen Handle hat (auch wiringPi setzt auf dem Kernel auf), ist der FD immer noch offen. Du machst pthread_cancel und restart und du hast 2 offene FD's. Den alten und den neuen FD. Zumindest in der Filedescriptor Tabelle des Prozesses. Das kannst du sehen wenn du ein "ls /proc/${deine PID}/fd" ansiehst.
Da das Projekt auf dem Pi noch recht am Anfang steht, würde ich das versuchen zu beachten. Wenn du sagst, das ist für dich kein Thema, dann ok :)
hallo,
danke für die Infos!
den int fd bekomme ich über wiringSerial: ich öffne ja UART per fd=serialOpen("/dev/ttyACM0", clock);
und wenn ich den Thread abbrechen musste, hänge ich sicherheitshalber noch ein serialClose(fd) hinten dran - dann müsste ja der fd wieder gelöscht/freigegeben sein, oder?
(erst danach öffne ich dann per fd=serialOpen("/dev/ttyACM0", clock) erneut.)
edited
Das könnte klappen... :)
Du musst dich aber um alle Resourcen kümmern. Am besten alles im Heap halten dann bei Close(fd) auch freigeben. std::string und co jegen große Sachen aber auch im Heap ab. Damit wird der Speicher voll und voller...
Edit: Heap: Frei Speicher.
beim FreigebenCode:std::string* buffer = new std::string;
Code:Close(fd);
delete buffer;
...
abere signore, isch 'abe doche gare keine std::threade :p
Das ist egal, auch dein pthread den du mit pthread_cancel abbrichst, muss die Resourcen frei geben.
theoretisch klar, aber ich weiß nicht wie, andererseits: so viel reservierten Speicher gibt es ja gar nicht.
Ich kann auch einige Variablen sicherheitshalber global deklarieren.
Das ist ein grundsätzliches Problem. Am Anfang glaubt man, man kann sich die Interprozesskommunikation sparen, wenn man Threads statt Tasks benutzt. Man kann einfach globale Variable verwenden. Dazu kommt noch die verbreitete Meinung, Taskwechsel verschenken Zeit gegenüber Threadwechseln. Irgendwann, wenn das System unübersichtlich geworden ist und sich z.B. die ersten Memoryleaks oder Deadlocks eingeschlichen haben, fängt man an, eine Thread- und Speicherüberwachung zu programmieren. Zum Schluß stellt man dann fest, daß man ein eigenes Betriebssystem programmiert hat, das aber längst auf dem System vorhanden ist. Das eigene ist auch nicht einfacher als das vorhandene, dafür ist es nur von einem selbst getestet und es fehlen hunderte Seiten man-Pages. Wer schreibt schon sowas zum eigenen Code? Wegen der Threadüberwachung ist es sogar langsamer als ein System, das auf Tasks basiert.
Daher sollte man am Anfang des Systemdesigns gut überlegen, ob es Sinn macht, ein eigenes Tasking-System (genauso wie eigene Kommunikationsprotokolle oder eine eigene Datenserialiesung) zu erfinden. Am Ende lauert immer das komplette Fiasko.
MfG Klebwax