Hallo Leute, ich experimentiere immer noch mit dem Ethernet MAC des 2468 herum. Ich habe ein eigenes, einfaches Protokoll erfunden, über das ich mit meinem LPC kommunizieren will. Die passende Windoof-Software dazu habe ich schon erfunden, nun gehts an den LPC. Hier setze ich uCOS ein. Die ankommenden Ethernet-Pakete möchte ich in einer Queue ablegen, sodass ich mittels OSQPend auf das Eintreffen von Paketen warten kann. Dazu habe ich mir folgendes überlegt: Wenn ein Paket eintrifft, soll ein Interrupt aufgerufen werden, der mittels OSMemGet einen Buffer alloziiert, und das gerade eingetroffene Paket in diesen Buffer kopiert. Dann wird mittels OSQPost die Basisadresse des gerade aloziierten Buffers auf die Queue gelegt und der RxConsumeIndex um eins erhöht. Der Task, der die eintreffenden Pakete verarbeiten soll, wartet mittels OSQPend, bis etwas in der Queue ist, und verarbeitet es. Anschliessend wird der aloziierte Buffer mit OSMemPut wieder freigegeben. In der Theorie funktioniert das bestens, nur in der Praxis leider nicht so ganz, denn: Beim Aufruf von OSMemGet stürzt der LPC ab - genauer gesagt geht er in den Prefetch Abort. Warum? Das einzige, was in diesem dummen Interrupt nicht funktioniert, ist OSMemGet. Alles andere würde klappen und zeitlich sogar reichen bis zum Eintreffen des nächsten Frames, aber OSMemGet klappt nicht. Habt ihr vielleicht noch eine andere Idee, wie man das lösen könnte? Ich muss allerdings noch erwähnen, dass in dem Interrupt nicht nur das eingetroffene Paket in die Queue gelegt wird. Vielmehr wird eine spezielle Struktur angelegt, welche noch weitere Infos zu dem Paket enthält - z.B. die Grösse. Wäre froh um den einen oder anderen Tip :-)
Mach dir doch von vornherein einen Puffer mit [soundsoviel] Bytes. Dann ein Zeigerarray, was auf die Anfänge der einzelnen Pakete(Rohdaten) innerhalb des erstgenannten Puffer-Arrays zeigt. Und zwei Zeiger aufs Zeigerarray, der eine auf das erste zu verarbeitende Paket und der zweite auf das zuletzt empfangene Paket. So entsteht ein Ringpuffer mit variabler Paket-Größe. Das mal als dreckiger Workaround. Wie schnell trudeln denn die einzelnen Pakete ein? Schneller als sie verarbeitet werden können? Kannst du das anständig debuggen, notfalls mit einem Logicanalyzer an ein paar Portpins? mfg mf
Hallo, die Pakete trudeln natürlich im ungünstigsten Fall schneller ein, als sie verarbeitet werden können. Deshalb muss ja dieser Handstand mit der Queue gemacht werden :( Das wär so ne elegante Lösung gewesen mit diesem dynamischen Memory! lwip macht das ja auch so ähnlich. Debuggen kann ich zwar recht ordentlich, da ich einen J-Link von Segger besitze, aber einen LA habe ich nicht. Mich würde aber noch interessieren, warum OSMemGet gerade beim Rx-Interrupt NICHT funktioniert. Im uCOS-Buch heisst es explizit, dass man diese Funktion in ISRs verwenden darf. Testweise habe ich sie mal aus einem Timer-Interrupt heraus aufgerufen, und dort funktioniert es :O
Bin ich der Einzige, der mit solchen Problemen zu kämpfen hat? :o benutzt sonst keiner die Interrupts sondern polling?
Wenn du TCP verwendest kannst du wenigstens die Geschwindigkeit der Datenströme regulieren. Alle anderen Pakete kannst du einfach droppen ;-)
Schon; aber das nützt alles nichts, wenn der LPC sporadisch abstürzt wenn ein Paket eintrifft. Ich habe mittlerweile festgestellt: greift man auf den Speicherbereich, wo die ankommenden Pakete gespeichert werden, zu, während ein neues Paket eintrifft, dann tritt wohl irgend ein Zugriffsfehler auf und der LPC verabschiedet sich in den data abort. Ich kann dazu im Datenblatt aber nichts finden! Ich habe auch schon mit den AHBCFG1 und AHBCFG2 Registern herumgespielt, ohne Ergebnis. Meine Descriptoren liegen im EMAC-RAM (0x7FE00000), sowie die Paket Buffer auch. Jeder Buffer umfasst 1536 Bytes, sodass garantiert ist, dass immer ein ganzer Frame in einen Descriptor rein passt. Was mache ich falsch, dass dieser dumme Prozessor abstürzt? Es ist zum Haare ausraufen. Egal was ich versuche - nach ein, zwei Paketen gibt das Ding den Geist auf. Und ich habe noch nicht mal irgend ein Protokoll implementiert, nur schon der blosse Empfang der Pakete klappt nicht richtig. Hier ist mein Code:
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 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 | |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | |
166 | |
167 | |
168 | |
169 | |
170 | |
171 | |
172 | |
173 | |
174 | |
175 | |
176 | |
177 | |
178 | |
179 | |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | |
186 | |
187 | |
188 | |
189 | |
190 | |
191 | |
192 | |
193 | |
194 | |
195 | |
196 | |
197 | |
198 | |
199 | |
200 | |
201 | |
202 | |
203 | |
204 | |
205 | |
206 | |
207 | |
208 | |
209 | |
210 | |
211 | |
212 | |
213 | |
214 | |
215 | |
216 | |
217 | |
218 | |
219 | |
220 | |
221 | |
222 | |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | |
229 | |
230 | |
231 | |
232 | |
233 | |
234 | |
235 | |
236 | |
237 | |
238 | |
239 | |
240 | |
241 | |
242 | |
243 | |
244 | |
245 | |
246 | |
247 | |
248 | |
249 | |
250 | |
251 | |
252 | |
253 | |
254 | |
255 | |
256 | |
257 | |
258 | |
259 | |
260 | |
261 | |
262 | |
263 | |
264 | |
265 | |
266 | |
267 | |
268 | |
269 | |
270 | |
271 | |
272 | |
273 | |
274 | |
275 | |
276 | |
277 | |
278 | |
279 | |
280 | |
281 | |
282 | |
283 | |
284 | |
285 | |
286 | |
287 | |
288 | |
289 | |
290 | |
291 | |
292 | |
293 | |
294 | |
295 | |
296 | |
297 | |
298 | |
299 | |
300 | |
301 | |
302 | |
So falsch ist das doch nicht, Keil macht das in den Beispielen jedenfalls nicht anders.
Hallo, nun sind einige Monate vergangen, und ich hab den Kram mit dem MAC für eine Weile ruhen lassen. Nun möchte ich doch endlich wieder mal was damit machen. Und stehe natürlich immernoch vor diesem Problem! Zwar habe ich zwischenzeitlich meinen Code um einiges verbessert. Er läuft jetzt auch stabiler: treffen die Pakete in einigem Abstand voneinander ein, also wenn ich z.B. von einem einzelnen PC aus ein Ping versende, dann klappt alles bestens. Wenn aber zwei oder mehr Pakete in sehr kurzer zeitlicher Abfolge eintreffen, dann stürzt der Rechner ab. Mittlerweile glaube ich auch, herausgefunden zu haben, warum: in der RxDescriptor-Tabelle steht überall nur noch 0xFFFFFFFF drin! Aber warum? wer schreibt mir da rein? Eine Analyse mit Lint zeigte, dass zumindest der Code für meinen MAC-Driver in Ordnung ist. Könnte es evtl. daran liegen, dass der DMA-Bus, der die Daten vom PHY ins RAM schaufeln muss, langsamer ist, als die Pakete eintreffen? Interessant ist: Schalte ich den RxDone-Interrupt aus, dann stürzt der Rechner nie ab. Ich kann 10000 Pakete direkt nacheinander senden oder von beliebig vielen PCs aus, das macht keinen Unterschied. Hat in der Zwischenzeit vielleicht jemand ein ähnliches Verhalten beobachten können oder hat eine Idee?
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.