Hallo, hab mich grad mal mit freeRTOS eingearbeitet. Momentan scheint es so, dass dieses OS einen relativ großen Overhead besitzt, so dass bei einem AT91SAM9263 die Ethernet Packete nicht mehr in der passenden Zeit abgearbeitet werden können. Bei einer Datenrate von 6MBit/s läuft alles gut, aber bei einer Datenrate von 20MBit/s bekomm ich Buffer-Not-Available Interrupts. Diese Fehlermeldungen treten bereits nach sehr kurzer Zeit auf (< 1s). Der Task wird genau wie in den Beispielanwendungen über eine Semaphore informiert, dass ein neues Pkt angekommen ist. Beim Aufruf (xSemaphoreGiveFromISR) in der ISR hab ich auch sehr viele Anfragen, die angeben, dass die Queue bereits voll ist. Auch varriert die Anzahl der Aufrufe der ISR von den Aufrufen des eigentlichen Tasks (hier sind es nämlich einige weniger, was auch die BNA-Fehler erklärt). Die ankommenden Pakete werden zur Zeit nur gesucht und anschlíeßend sofort wieder gelöscht, so dass die DMA wieder Zugriff darauf hat. Es finden also keine TCP/IP Stack Operationen statt. Ohne RTOS läuft dieser Code einwandfrei. Als ganz minimalistisches Beispiel hab ich einfach mal im Ethernet-Task bei jedem ankommenden Pkt alle zur Verfügung stehenden Buffer gelöscht... dann bekomm ich zwar keine Buffer-Not-Available Fehlermeldungen, aber die Queue (xSemaphoreGiveFromISR) wird trotzdem ab und zu als voll angezeigt. Hat hier jmd schon andere (bessere) Erfahrungen sammeln können mit freeRTOS? Gibt es andere RTOS die schneller sind? Gruß Bernd
Gast
#1502023
Der Kern wird schon laufen, ich denke ungesehen der Treiber ist zu lahm und eigentlich auch nicht Teil des Kerns. Ich würde mal sagen: Treiber optimieren ;-)
mit Treiber meinst du wahrscheinlich meinen hinzugefügten Code: Hier ist die komplette Task low_level_input() function:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
Diese Funktion wird wie in den mitgelieferten Beispieln aufgerufen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
Gruß Bernd
Gast
#1502083
Aha, kannst du mal dein xSemaphoreGive( xRxSemaphore ); entfernen ? Das wäre dann schon der erste Fehler. Wer blockt denn in der Task den Emac_RxBufDesc vor dem Interrupt ? Ich kenn den Aufbau jetzt nicht, sieht aber nach einem Ringbuffer aus der vom Interrupt/DMA geschrieben und von der Task gelesen werden soll !?
in der Task wird hier auf das Semaphore gewartet:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
In der ISR dazu wird, falls ein Pkt received worden ist, dem Task signalisiert, dass es was zum arbeiten gibt
1 | |
>kannst du mal dein xSemaphoreGive( xRxSemaphore ); entfernen ? Das wäre >dann schon der erste Fehler. ich dachte für den Zugriff auf den Emac holt man sich zuerst eine Semaphore und am Schluss gibt man diese wieder zurück, damit diese Ressource wieder vorhanden ist. In der Init für den Emac gibt man der DMA den ersten Buffer bekannt.
1 | |
2 | |
3 | |
4 | |
5 | |
Der letzte Buffer im "Buffer-Array" besitzt ein ein Flag, welches angibt, dass jetzt weider im ersten Buffer gespeichert werden muss, falls dieser frei ist für die DMA. Gruß Bernd
Gast
#1502138
Du lässt dir über xSemaphore vom Interrupt den Empfang signalisieren ? Rufst du nach xSwitchRequired = xSemaphoreGiveFromISR( xSemaphore, pdFALSE ); Auch diese yieldWasWeissIch Funktion auf ? > ich dachte für den Zugriff auf den Emac holt man sich zuerst eine > Semaphore und am Schluss gibt man diese wieder zurück, damit diese > Ressource wieder vorhanden ist. Wo wird denn xRxSemaphore abgefragt/geblockt ? Die DMA sollte ja einfach in den Speicher blasen ohne auf sowas zu achten !? Dann hättest du Probleme mit Overflows und wenn du die DMA blockst dann mit Underflows, wenn die Task zu lahm ist.
>Auch diese yieldWasWeissIch Funktion auf ?
das müsste diese sein, die ganz zum schluss von der isr aufgerufen wird.1 | |
2 | |
3 | |
4 | |
>Wo wird denn xRxSemaphore abgefragt/geblockt
hab mir gad nochmal ein anderes beispiel angeschaut, und die haben diese
xRxSemaphoren-Geschichte auch nicht dabei; hab es jetzt komplett
weggelassen, leider aber noch ohne Erfolg.
Gast
#1502281
Vergrößer einfach mal das EMAC_RX_N_BUFS !?
momentan ist EMAC_RX_N_BUFS = 150 -> jeder dieser Buffer beinhaltet 128Byte (entspricht einem DMA-Transport). Nachdem der Fehler sehr schnell kommt (weniger als 1sec), wird eine Vergrößerung nichts bringen; zumal ohne RTOS es ja einwandfrei läuft. Gruß Bernd
ich glaub nicht, dass es an meinem Code liegt, sondern eher, dass bei der Portierung von einem SAM7 (beispieldateien von freeRTOS) auf einen SAM9 irgendetwas innerhalb des Kernels verändert werden muss. Beim Durchsuchen der portable.h und portmacro.h sind mir aber keine großartigen Eingriffe die verschieden wären, aufgefallen. Der Instruction-Cache ist auch enabled und funktioniert (hab es ohne diesem probiert, und der Prozessor arbeitet um einiges langsamer...). Gruß Bernd
Gast
#1506122
> ich dachte für den Zugriff auf den Emac holt man sich > zuerst eine Semaphore und am Schluss gibt man diese > wieder zurück, damit diese Ressource wieder vorhanden ist. Das ist eine Möglichkeit, ein Semaphor zu verwenden. Eine andere ist, einer Task ein Signal zu geben, dass es eine Aufgabe zu erledigen gibt. Wird gerne eingesetzt, wenn der Signalgeber eine Interrupt-Serviceroutine ist, die schnell das Allernötigste erledigt und die längere Auswertung einer Task überlässt. Das "Verriegeln" des Emac gegen konkurrierende Zugriffe kann trotzdem erforderlich sein. Es kann dann aber nicht mit demselben Semaphor erledigt werden. Näheres über Semaphore hier: http://de.wikipedia.org/wiki/Semaphor_(Informatik) Übrigens heißt es "der" oder "das Semaphor". > ich glaub nicht, dass es an meinem Code liegt, sondern eher, > dass bei der Portierung von einem SAM7 (beispieldateien von > freeRTOS) auf einen SAM9 irgendetwas innerhalb des Kernels > verändert werden muss. Dann bau doch erst mal ein einfacheres FreeRTOS-Beispiel, das dir zeigt, ob der Kernel prinzipiell läuft. Damit kannst du dann auch die Semaphor-Mechanismen studieren.
>Eine andere ist, einer Task ein Signal zu geben, dass es eine Aufgabe zu >erledigen gibt. Wird gerne eingesetzt, wenn der Signalgeber eine >Interrupt-Serviceroutine ist, die schnell das Allernötigste erledigt und >die längere Auswertung einer Task überlässt. unter welchem Begriff / Namen fällt diese Art einem Task zu signalisieren, dass es eine Aufgabe gibt? >Dann bau doch erst mal ein einfacheres FreeRTOS-Beispiel, das dir zeigt, >ob der Kernel prinzipiell läuft. Damit kannst du dann auch die >Semaphor-Mechanismen studieren. Das RTOS funktioniert ja prinzipiell - auch die Übergabe mit der Semaphore - allerdings ist beides zu langsam... Hab auch gelesen, dass man das Semaphor bei einer ISR nicht mehr zurückgeben muss... Gruß Bernd
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.