Forum: Mikrocontroller und Digitale Elektronik Netzwerkstack und Multitasking


von Björn (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.