Hallo, ich bin seit längerem dabei, einen Netzwerkstack der speziell für ARM Mikrocontroller optimiert ist zu entwerfen. Zudem soll der Stack mit einem RTOS wie uC/OS oder FreeRTOS arbeiten und Sachen wie Mailboxen, Queues und Timer, die das OS zur Verfügung stellt, effektiv nutzen. Das heisst auch, dass der Stack mit mehreren Tasks zurecht kommen muss. Bisheriger Stand: Ethernet, IP, UDP, DNS, DHCP und ICMP habe ich vollständig und funktionierend implementiert. Dokumentiert habe ich auch alles (möchte es nachher der Allgemeinheit zur Verfügung stellen falls Interesse besteht). TCP bin ich dabei zu implementieren, zu 50% läuft es schon. Die oben genannten Dienste (DNS, DHCP, ICMP) sind direkt im Stack selbst integriert, das ist für den User alles völlig transparent und man muss sich um gar nix kümmern. Wie gesagt funktioniert es sehr gut. Was mir jetzt allerdings Kopfzerbrechen bereitet: nehmen wir an, der Netzwerkstack läuft im Task A. Jetzt möchte Task B auf einem bnestimmten UDP-Port lauschen. Sobald der Task die udp_listen()-Funktion ausführt, wird er suspendiert und erst wieder aufgeweckt, wenn auch effektiv ein UDP-Paket eintrifft. Das habe ich folgendermassen gelöst: führt man die udp_listen()-Funktion aus, dann wird intern im Netzwerkstack gespeichert, welcher Task die Funktion aufgerufen hat. Sobald dann UDP-Pakete eintreffen, werden Pointer auf diese als Messages in die Mailbox des genannten Tasks gesandt - und dieser kann schön brav auf der Mailbox warten, bis was kommt. Eigentlich funktioniert das auch ganz gut, immerhin konnte ich gestern erfolgreich den Text "Hello world" mehrmals per UDP übers LAN an meine Software senden ;) Die Netzwerkpakete werden intern im Stack als dynamisch alloziierte Memory-Blöcke verwaltet. So muss ich niemals Daten herum kopieren, sondern kann lediglich mit den Pointern arbeiten. Das wirft aber ein Problem auf: - Soll ich beispielsweise beim Empfang von UDP-Daten direkt den Pointer auf das dynamische Memory dem aufrufenden Task senden? Wer gibt das Memory nachher wieder frei? - Soll ich besser die Daten in einen Puffer kopieren, den der aufrufende Task dann selber verwalten muss? Wie wird das wohl in professionellen Stacks gehandhabt? Zweite Frage. Muss ein Task gleichzeitig auf mehreren Verbindungen lauschen können? In meiner Gegenwärtigen Implementation ist das ja nicht möglich, denn der Task wird ja suspendiert, sobald er einen Port aufmacht und auf Pakete wartet. Im Moment stehe ich ein wenig auf dem Schlauch, aber ihr habt mir sicher ein paar Vorschläge ;)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.