Hallo,
Ich habe hier vor mir ein EFM32 DVK liegen.
Aktuell versuch ich den DMA-Controller für ein UART Protokoll zum laufen
zu kriegen. Das ganze läuft in einer RTX Umgebung und demnach in Keil
µVision.
Aufgabe:
Ich schicke ein Startzeichen (0x1F) und starte danach einen DMA Transfer
mit fester Länge (6 Bytes immo) und disable den UART Interupt. In der
Callback-Function, löse ich ein Event aus und der Task verarbeitet die
Daten. Danach aktiviere ich wieder den UART Interrupt und warte auf das
Startzeichen. Funktioniert soweit auch schon.
Mein Problem ist, dass nach dem ersten Telegram:
-der UART Interrupt kommt
-das Startzeichen erkannt wird
-der DMA Transfer gestartet wird
-die Daten im Speicher landen (mit Debugger)
-der DMA_IRQ für vollständigen Transfer ausgelöst wird
-ABER NICHT die Callback-Function angesprungen wird...Die Adresse im
CB-Descriptor ändert sich!
Ich konnte mittels Debugger folgendes feststellen:
aus der efm32_dma.h und dort ein Teil aus dem IRQ Handler
1 | /* Normally, no point in enabling interrupt without callback, but */
|
2 | /* check if callback is defined anyway. Callback info is always */
|
3 | /* located in primary descriptor. */
|
4 | cb = (DMA_CB_TypeDef *)(descr[channel].USER);
|
5 | if (cb)
|
6 | {
|
7 | /* Toggle next-descriptor indicator always prior to invoking */
|
8 | /* callback (in case callback reconfigurs something) */
|
9 | primaryCpy = cb->primary;
|
10 | cb->primary ^= 1;
|
11 | if (cb->cbFunc)
|
12 | {
|
13 | cb->cbFunc(channel, (bool) primaryCpy, cb->userPtr);
|
14 | }
|
15 | }
|
16 | }
|
der CB Descriptor zeigt auf die richtige Adresse:
(beim ersten Aufruf, wo der Sprung zur CallBackfuntion geht)
cb:
-> 0x20001234
cbFunc:
->0x00002011 (Im Treiber im Anhang ist das die DMA_checkByte Routine)
beim zweiten Aufruf wo es nicht mehr geht:
cb:
->0x20001234
cbFunc:
->0x0000182D
Im Speicher kann ich sehen das sich die Adresse beim Sprung in die
Callback Funktion ändert...das heißt wenn ich im Singelstep das Programm
durchlaufe, bewirkt die erste Aktion in der cbFunction eine änderung des
Pointers...obwohl ich sowas natürlich nicht will...
Woran scheiterts?
Ich hoffe es kann mir wer weiterhelfen