Forum: Mikrocontroller und Digitale Elektronik Interrupts reagieren wärend Schleifen nicht


von Jan S. (spongebob)


Lesenswert?

Moin!
Ich habe das Problem das bei meinem Programm die Interrupts scheinbar 
wärend while- und for-schleifen nicht ausgeführt werden. Ich habe z.B. 
einen AC97-Codec interrupt, in dem ADC-daten in ein arrai geschrieben 
werden. Wenn ich die Interrupts enable, und danach in eine Delay-loop 
springe werden einige werte nicht aufgenommen. Das Problem konnte ich 
umgehen, indem ich die Interrupts einfach als letztes enable. Jetzt 
taucht das Problem auf das ich in einer while-schleife auf ein Event 
warten muss. Vorher aber noch dinge über Ethernet senden will. So nach 
folgenden schema:
1
mod_xn_re_p = (int *)shram_mod_xn_re->addr;
2
for(i=0; i<(SH_MEM_SIZE/2); i++)
3
xn_re_buff1[i] = *(mod_xn_re_p++);
4
p_buffer->payload = xn_re_buff1;
5
transmit(p_buffer, &pc_addr);
6
for(i=0; i<(SH_MEM_SIZE/2); i++)
7
xn_re_buff1[i] = *(mod_xn_re_p++);
8
p_buffer->payload = xn_re_buff1;
9
transmit(p_buffer, &pc_addr);
10
11
12
while(!read_mems);       //Wait for FFT

Jetzt habe ich einen Interrupt handler, das read_mems-flag setzt, wenn 
die FFT fertig in die Shared Memorys geschrieben hat:
1
void FFT_Ready_Read_int_handler(void * baseaddr_p)
2
{
3
read_mems = 1;
4
}
jetzt starte ich aber die FFT nicht, also wird das event auch nicht 
ausgelöst. Jedenfalls werden die Daten jetzt auch nicht mehr gesendet, 
weil sich das Programm in der While befindet. Wenn ich sie lösche, 
funktioniert alles ohne Probleme.

Wie kann es sein das Schleifen interrupts verhindern???
Bin für jede Antwort dankbar!!!

Güße Jan

: Verschoben durch Moderator
von (prx) A. K. (prx)


Lesenswert?

Platz für Code muss nicht unbedingt quadratisch ausgefüllt werden.

von (prx) A. K. (prx)


Lesenswert?

Jan S. schrieb:
> Wie kann es sein das Schleifen interrupts verhindern???

Tun sie nicht. Ursache liegt woanders. "volatile" vergessen?

von Jan S. (spongebob)


Lesenswert?

> Platz für Code muss nicht unbedingt quadratisch ausgefüllt werden.

He? Was soll das? Oder versteh ich den Witz nicht, oder is das kein 
Witz?

> Tun sie nicht. Ursache liegt woanders. "volatile" vergessen?

Also mit volatile habe ich es auch auf zwei Arten versucht:
1. volatile char read_mems=0;
2. char volatile read_mems=0;

Bringt beides nichts. Sonst Vorschläge? Oder hab ich was falsch 
verstanden? Eigentlich sagt man damit doch das die Variable nicht 
wegoptimiert werden soll, oder?

>Zu grobe Körnung des Schleifpapiers?
Man was is denn los heute? is meine Frage wirklich so dämlich oder sind 
manche Leute heut nur komisch drauf. Eigentlich bekommt man in diesem 
Forum sonst immer relativ intelligente Antworten....

Vielleicht bekomm ich ja noch ein paar gute Tipps ;-)

Grüße Jan

von (prx) A. K. (prx)


Lesenswert?

Jan S. schrieb:
> He? Was soll das? Oder versteh ich den Witz nicht, oder is das kein
> Witz?

Doch, ist es. Das war eine Anspielung auf die begrenzte Lesbarkeit 
deines Codes. Ritter Sport kam mir da sofort in den Sinn. Ein paar 
strategisch plazierte Leerzeilen hätten schon Wunder gewirkt.

> Also mit volatile habe ich es auch auf zwei Arten versucht:

Beides identisch.

> Man was is denn los heute? is meine Frage wirklich so dämlich

Nö, aber manchmal hat man grad einen Clown gefrühstückt. Du hast den 
Standardfehler gemacht, nur jenen Teil des Programms zu zeigen, in dem 
du den Fehler vermutest aber nicht findest, aber nicht den Teil, in dem 
er sich tatsächlich befindet. Sowas reizt den erwähnten Clown.

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

such mal nach einem asm"cli"


oder einem fehlenden asm"sei" in der initialisierung ;-)

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

A. K. schrieb:
> Ritter Sport kam mir da sofort in den Sinn.
ist doch praktisch und füllt bei tetris gleich drei halbe reihen ;-)

von Jan S. (spongebob)


Lesenswert?

Ok, das is schon richtig. Ein paar leerzeilen könnt ich echt mal 
spendieren ;-)
>Beides ok.
Hmm, aber warum funktioniert das senden dann trotzdem nicht. Wenn ich es 
mir mit Wireshark ansehe, fragt mein Board mit einer Broadcast Anfrage 
an, aber sendet dann auf die Antwort hin nicht...

>Du hast den Standardfehler gemacht, nur jenen Teil des Programms zu zeigen,in dem 
du den Fehler vermutest aber nicht findest, aber nicht den Teil, in dem er sich 
tatsächlich befindet.
Aber wie soll ich denn den Teil zeigen wo der Fehler liegt, wenn ich das 
wüsste, hätte ich ja nicht das Problem das ich den Fehler nicht beheben 
kann. Soll ich ma meinen ganzen Code posten? Aber das is ne Menge...

von (prx) A. K. (prx)


Lesenswert?

Jan S. schrieb:
> Aber wie soll ich denn den Teil zeigen wo der Fehler liegt, wenn ich das
> wüsste, hätte ich ja nicht das Problem das ich den Fehler nicht beheben
> kann.

Mit Anspielungen habe ich heute echt kein Glück bei dir. ;-)

Versuch dir mal vorzustellen, wie irgendjemand sonst drauf kommen soll. 
Das ist kein Forum für Magier und solche die es werden wollen, auch wenn 
es von kaputten Glaskugeln nur so wimmelt.

> Soll ich ma meinen ganzen Code posten?

Darauf läuft es raus. Nur eben passend eingedampft. Soll heissen: 
Sukzessive alles aus dem Code rauswerfen, was zum Problem nicht 
beiträgt. Im dem, was dann übrig bleibt, liegt das Problem. Und das muss 
klein genug sein, dass sich hier jemand das anschaut. Ansonsten stehen 
die Chancen schlecht.

PS: Es schadet auch nicht, wenn man verrät, mit welchem Werkzeug und für 
welchen Controller man entwickelt.

von (prx) A. K. (prx)


Lesenswert?

PPS: Und wenn man das dann noch im richtigen Forum unterbringt, und 
nicht bei FPGAs, dann ...

(Mod: Thread nach µC u. dig. Elektr. verschoben)

von Jan S. (spongebob)


Lesenswert?

Moin!
Ich habe jetzt ma meinen Code so eingekürzt das man das denke ich ganz 
gut überblicken kann. Desweiteren habe ich das versucht zu 
ent-Ritter-Sporten ;-)
Falls noch was fehlt oder irgendwas unklar ist bitte fragen. Ich hoffe 
es kann mir jemand helfen. Ich bin nämlich im Moment völlig ratlos.

Hier der Code:
1
unsigned short start_stop  = 0;    //wait for parameters via Ethernet
2
3
/***** send-arrays *****/
4
short *xn_re_buff1, *xn_re_buff2;  //memory allocation in rec_matlab_data(...)
5
short *xk_re_buff1, *xk_re_buff2;
6
short *xk_im_buff1, *xk_im_buff2;
7
8
//FFT-CORE
9
int *xn_re_p, *control_p, *scale_sch_p, *addr_in_p;  //Input
10
volatile char read_flg = 0;
11
volatile char read_mems = 0;
12
13
/*************************** Interrupt handler **********************************/
14
15
void AC97_int_handler(void * baseaddr_p)
16
{
17
static short ac97_ctr = 0;
18
19
*control_p &= (~WE_IN);
20
21
  if(start_stop && (read_flg == 0))
22
  {
23
    *xn_re_p = XAC97_mGetOutFifoData(XPAR_XPS_AC97_0_BASEADDR); // Read FIFO using non blocking read method
24
    *addr_in_p = ac97_ctr;
25
    *control_p |= WE_IN;
26
    ac97_ctr++;
27
28
    if(ac97_ctr == POINT_SIZE)  //if array 0 to 1023 is written
29
    {
30
      read_flg = 1;
31
      ac97_ctr = 0;
32
    }
33
  }
34
}
35
36
void FFT_Ready_Read_int_handler(void * baseaddr_p)
37
{
38
read_mems = 1;
39
}
40
41
/********************************** Main *****************************************/
42
43
int main(void)
44
{
45
  int i;
46
47
  /* start the application UDP_Server*/
48
  start_udp_server();
49
50
  XIntc_RegisterHandler(XPAR_XPS_INTC_0_BASEADDR ,
51
    XPAR_XPS_INTC_0_XPS_AC97_0_INTERRUPT_INTR,
52
    AC97_int_handler, (void *) 0);
53
54
  XIntc_RegisterHandler(XPAR_XPS_INTC_0_BASEADDR,
55
      XPAR_XPS_INTC_0_FFT_V5_PLBW_0_SH_MEM_RDY_INTR,
56
    FFT_Ready_Read_int_handler, (void *) 0);
57
58
    p_buffer = pbuf_alloc(PBUF_TRANSPORT, (PAYLOAD_CELLS * DATASIZE), PBUF_REF);  //1024 bytes = 512 samples á 2 byte or 256 samples á 4 byte
59
60
  alloc_memory(log2pts);  //for xn/xk buffers
61
62
  /* now enable interrupts */
63
  platform_enable_interrupts();
64
65
  /* receive packets */
66
  while (1) {
67
    xemacif_input(netif);
68
69
    if(read_flg)
70
    {
71
      //send time-signal
72
      mod_xn_re_p = (int *)shram_mod_xn_re->addr;
73
      
74
      for(i=0; i<(SH_MEM_SIZE/2); i++)
75
        xn_re_buff1[i] = *(mod_xn_re_p++);  //write data from shared Memory into Buffer
76
      p_buffer->payload = xn_re_buff1;
77
      transmit(p_buffer, &pc_addr);
78
      
79
      for(i=0; i<(SH_MEM_SIZE/2); i++)
80
        xn_re_buff1[i] = *(mod_xn_re_p++);
81
      p_buffer->payload = xn_re_buff1;  //address for sendbuffer
82
      transmit(p_buffer, &pc_addr);
83
84
      while(!read_mems);  //Wait for FFT  (WITHOUT THIS WHILE LOOP EVERYTHING WORKS FINE)
85
86
      read_flg = 0;
87
      read_mems = 0;
88
    }
89
  }
90
91
  return 0;
92
}

von (prx) A. K. (prx)


Lesenswert?

A. K. schrieb:
> PS: Es schadet auch nicht, wenn man verrät, mit welchem Werkzeug und für
> welchen Controller man entwickelt.

PUSH

Sieht aber nach nichts aus was ich kenne.

von (prx) A. K. (prx)


Lesenswert?

Wodurch wird der FFT Interrupt denn ausgelöst, bzw. sollte es? Im Code 
ist das für mich nicht ersichtlich.

von Jan S. (spongebob)


Lesenswert?

Ich nutze das Sofware Development Kit (SDK 13.4) von Xilinx und mein 
"Controller" ist ein Virtex 5, welcher auf dem ML507 sitzt.
Das ganze soll ein FFT-Audio-Analyser mit anbindung an Matlab werden. 
Den FFT-Core habe ich mir mit dem Sysgen aus Matlab erzeugt und in XPS 
eingebunden. Und wie gesagt, ohne die while-schleife funktioniert auch 
das senden an Matlab.

Grüße Jan

von Jan S. (spongebob)


Lesenswert?

Der Interrupt wird duch ein Signal des FFT-Cores erzeugt (fallende 
flanke auf eine Data-Valid Ausgang). Also sobalt meine Shared Memorys 
mit Ausgangswerten des FFT-Cores beschrieben sind, kommt ein Interrupt, 
der mir sagt das die Memorys ausgelesen werden können.

PS. Der Interrupt kommt. Das habe ich getestet.

von Uwe (Gast)


Lesenswert?

Tja dann versuch es doch mal mit nem Ausschlußverfahren.
Laß Alles weg außer dem Interupt und die Schleife.
Was passiert ? Wenn es funzt mach nach und nach immer mehr von deinem 
Code hinzu und gucke  wann es aufhört zu funktionieren.
Wenn die Schleife Alleine mit dem Interupt schon nicht funktioniert. Hat 
entweder die Synthese nen Problem, die intruktion der CPU bzw. das 
Interuptsystem der CPU, oder der Compiler.

von Jan S. (spongebob)


Lesenswert?

Selbst wenn ich alles was nicht damit zu tun hat rausnehme, was ja nicht 
viel ist, weil ja das senden und der FFT-Core damit zusammenhängt, tritt 
das Problem immer noch auf. Wie kann ich das denn jetzt weiter 
analysieren bzw. debuggen bzw. irgendwas anderes? Ich brauche ja die 
while schleife, weil ich ja auf den FFT-Core warten muss... Bin echt am 
verzweifeln...

Trotzdem schon mal ein großes Danke für die vielen Antworten!!!

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Der Verdacht richtet sich natürlich auf die transmit() Routine, die 
evtl. Interrupts sperrt, bzw. ausmaskiert. Wenn du nach transmit() 
nochmal explizit den Interrupt freigibst?
Ein Problem bei zeitkritischer Behandlung könnte auch sein, das 
transmit() in der Abarbeitungszeit unvorhersehbar ist ( Bus besetzt 
,Hardware noch busy etc.). Probiers mal ohne transmit().

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.