www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

Nerazumljiv problem v C-ju
Pojdi na stran 1, 2  Naslednja
 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> ARM arhitektura
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
damo
Član
Član



Pridružen-a: Čet 31 Jul 2003 13:45
Prispevkov: 2008
Aktiv.: 8.46
Kraj: Krško

PrispevekObjavljeno: Sre Jan 19, 2011 2:12 pm    Naslov sporočila:  Nerazumljiv problem v C-ju Odgovori s citatom

Ojla,

že par dni se ubadam s problemom, ki mi je nerazumljiv. Namreč, spodnja koda se ne izvede pravilno (ne gre ven z return (1)), kljub temu, da ima hardverske pogoje - torej pulz na IO pinu.

Koda:
int wait_for_pulse()
{
 unsigned int maxtime, count;

 count=0;
 maxtime=40000;    // timeout 29.4ms

 //count=0;               // tukaj moram dodati eno vrstico, da koda deluje

 while (--maxtime)
    {
    if (tst_CAL_CLK) count++;
       else count=0;                  // if CLK goes low, reset counter

    if (count>50) {
                return (1);}         // we got >40us high pulse
   
   }

printf("ERROR: missing start pulse c=%i t=%i \n",count,maxtime);

return (0);                           // 30ms has expired without high pulse
}



Če na začetku dodam nek brezvezen ukaz (npr. še enkrat count=0), stvar deluje ok. Da je zmeda še večja, imam še eno enako funkcijo, ki pa mi ne dela težav:

Koda:
int wait_for_quiet()
{
 unsigned int maxtime, count;

 maxtime=35000;    // timeout 25ms
 count=0;
 
 while (--maxtime)
     {
    if (!tst_CAL_CLK) count++;            // if CLK is low, start counting
       else count=0;                  // if CLK goes high, reset counter

    if (count>66)  {                  // we got 50us
               return (1);
               }          
   }

 printf("wait for quiet failed\n");
 return (0);                           // time expired without quiet pulse

}




Kakšna ideja? Jaz jih nimam več. Sicer bi lahko zadevo rešil, da dam nek brezvezen ukaz, ampak to ni rešitev problema, ampak samo maskiranje....

_________________
Dobrga štromarja samo slab šnops strese!
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
mucek4
Član
Član



Pridružen-a: Sob 18 Jun 2005 20:52
Prispevkov: 2952
Aktiv.: 12.43
Kraj: Tržič - Mesto med gorami

PrispevekObjavljeno: Sre Jan 19, 2011 3:09 pm    Naslov sporočila:   Odgovori s citatom

Ne vemo kater procesor, ampak v prvem primeru najprej nastaviš vrednost in jo takoj odštevaš, v drugem pa izvedeš en ukaz vmes. Poizkusi še v prvem primeru zamenjati count in maxtime. Je pa to definitivno bug v prevajalniku.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
damo
Član
Član



Pridružen-a: Čet 31 Jul 2003 13:45
Prispevkov: 2008
Aktiv.: 8.46
Kraj: Krško

PrispevekObjavljeno: Sre Jan 19, 2011 3:18 pm    Naslov sporočila:   Odgovori s citatom

Procesor je ARM lpc2148.

Tudi če prireditve spremenljivk count in maxtime med seboj zamenjam, zadeva ne deluje, medtem ko v drugem primeru ni problemov.

_________________
Dobrga štromarja samo slab šnops strese!
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
red_mamba
Član
Član



Pridružen-a: Ned 20 Feb 2005 17:56
Prispevkov: 1486
Aktiv.: 6.26
Kraj: Yogyakarta

PrispevekObjavljeno: Sre Jan 19, 2011 3:47 pm    Naslov sporočila:   Odgovori s citatom

a ti enoko ne dela z


while (maxtime--) ?

in

while ( (maxtime--) > 0) ?

_________________
Bad things happen to good people all the time for no reason!
Blog
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Obišči avtorjevo spletno stran
red_mamba
Član
Član



Pridružen-a: Ned 20 Feb 2005 17:56
Prispevkov: 1486
Aktiv.: 6.26
Kraj: Yogyakarta

PrispevekObjavljeno: Sre Jan 19, 2011 3:49 pm    Naslov sporočila:   Odgovori s citatom

poleg tega imaš pogoj da mora biti pulz dovolj dolg da prešteje do 66
in nobenih "glitchev" ne sme biti drugače ti resetira števec.

_________________
Bad things happen to good people all the time for no reason!
Blog
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Obišči avtorjevo spletno stran
damo
Član
Član



Pridružen-a: Čet 31 Jul 2003 13:45
Prispevkov: 2008
Aktiv.: 8.46
Kraj: Krško

PrispevekObjavljeno: Sre Jan 19, 2011 4:24 pm    Naslov sporočila:   Odgovori s citatom

ja, enako dela z --maxtime in maxtime--.

In ja, program "lovi" pulz, ki je širši od neke dolžine.

Ampak hardware je hardware, deluje enako, če dam v kodi en ukaz več ali manj. Koda pa ne deluje.

Vglavnem, deluje, če dodam še en kakršenkoli ukaz.

_________________
Dobrga štromarja samo slab šnops strese!
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Gklemen
Član
Član



Pridružen-a: Sob 29 Nov 2008 0:06
Prispevkov: 112
Aktiv.: 0.55
Kraj: Rogatec

PrispevekObjavljeno: Sre Jan 19, 2011 6:33 pm    Naslov sporočila:   Odgovori s citatom

kaj pa je s tem:
enkrat imaš
Citiram:
if (tst_CAL_CLK)
, drugič pa
Citiram:
if (!tst_CAL_CLK)
?
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
damo
Član
Član



Pridružen-a: Čet 31 Jul 2003 13:45
Prispevkov: 2008
Aktiv.: 8.46
Kraj: Krško

PrispevekObjavljeno: Sre Jan 19, 2011 6:51 pm    Naslov sporočila:   Odgovori s citatom

Ja, v eni funkciji čakam na nizki impulz (stanje quiet), v drugi pa na startni pulz, tako da tisti klicaj je kar ok.


no, na začetku imam še:


#define CAL_CLK (1U << 7)
#define tst_CAL_CLK !(IOPIN0 & CAL_CLK) // active low!


Problem bi kvečjemu pričakoval pri !tst_CAL_CLK, ki pomeni

! ! (IOPIN0 & (1U << 7)), očitno se klicaja brez problemov okrajšata

_________________
Dobrga štromarja samo slab šnops strese!
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Benjamin
Član
Član



Pridružen-a: Tor 10 Jul 2007 11:23
Prispevkov: 116
Aktiv.: 0.53
Kraj: Trebnje, Ljubljana

PrispevekObjavljeno: Sre Jan 19, 2011 7:52 pm    Naslov sporočila:   Odgovori s citatom

Zivjo!

Poskusi se z volatile:
Koda:
volatile unsigned int maxtime, count;

_________________
Cessna 152: "Flight Level Three Thousand, Seven Hundred"
Controller: "Roger, contact Houston Space Center"
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Umnik
Član
Član



Pridružen-a: Čet 16 Sep 2004 17:52
Prispevkov: 958
Aktiv.: 4.03
Kraj: Novo mesto

PrispevekObjavljeno: Čet Jan 20, 2011 12:25 am    Naslov sporočila:   Odgovori s citatom

Project -> Options for target -> Listing -> C Compiler Listing (check) -> OK (click)
Project -> Rebuild all target files.

Potem, klikni na ime modula v zavihku Project, desna tipka -> Open list file.

Potem vsebino za funkcijo ki dela težave kopiraj assembler kodo in prilepi sem.

Prepričan sem da:
1. Vstavljanje brezveznega ukaza nima vpliva.
2. 99.999% ni compiler bug.
3. Zamenjava vrstnega reda spremenljivk je nesmisel.
4. Definiranje z volatile je nesmisel.

Vem pa, da branje IO pina 40000 krat v loopu ni dobra reč. Vem tudi, da je IOPIN periferija počasna (uporabljaj rajši FIOPIN periferijo in poišči kaj pomeni vpis v register SCS = 1) in lahko bi bile težave v tem.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
damo
Član
Član



Pridružen-a: Čet 31 Jul 2003 13:45
Prispevkov: 2008
Aktiv.: 8.46
Kraj: Krško

PrispevekObjavljeno: Čet Jan 20, 2011 9:22 am    Naslov sporočila:   Odgovori s citatom

takole.... Opazim razlike, kam se spravi maxtime, kar očitno pomeni problem pri pravilnem delovanju.....



orig. koda (ki ne deluje pravilno):


Koda:
                  wait_for_pulse PROC
;;;169    //---------------------------------------------------------------------------------//
;;;170    int wait_for_pulse()
00024c  e92d4070          PUSH     {r4-r6,lr}
;;;171    {
;;;172     unsigned int maxtime, count;
;;;173   
;;;174     maxtime=40000;    // timeout 29.4ms
000250  e59f50a0          LDR      r5,|L1.760|
;;;175     count=0;
000254  e3a04000          MOV      r4,#0
;;;176   
;;;177     while (maxtime--)
000258  ea00000b          B        |L1.652|
                  |L1.604|
;;;178        {
;;;179        if (tst_CAL_CLK) count++;
00025c  e59f004c          LDR      r0,|L1.688|
000260  e5900000          LDR      r0,[r0,#0]
000264  e3100080          TST      r0,#0x80
000268  1a000001          BNE      |L1.628|
00026c  e2844001          ADD      r4,r4,#1
000270  ea000000          B        |L1.632|
                  |L1.628|
;;;180           else count=0;                  // if CLK goes low, reset counter
000274  e3a04000          MOV      r4,#0
                  |L1.632|
;;;181   
;;;182        if (count>50) {
000278  e3540032          CMP      r4,#0x32
00027c  9a000002          BLS      |L1.652|
;;;183                    return (1);}         // we got >40us high pulse
000280  e3a00001          MOV      r0,#1
                  |L1.644|
000284  e8bd4070          POP      {r4-r6,lr}
;;;184       
;;;185       }
;;;186   
;;;187    printf("ERROR: missing start pulse c=%i t=%i \n",count,maxtime);
;;;188   
;;;189    return (0);                           // 30ms has expired without high pulse
;;;190    }
000288  e12fff1e          BX       lr
                  |L1.652|
00028c  e1b00005          MOVS     r0,r5                 ;177
000290  e2455001          SUB      r5,r5,#1              ;177
000294  1afffff0          BNE      |L1.604|
000298  e1a02005          MOV      r2,r5                 ;187
00029c  e1a01004          MOV      r1,r4                 ;187
0002a0  e28f0054          ADR      r0,|L1.764|
0002a4  ebfffffe          [slovenščina je zame španska vas]       __2printf
0002a8  e3a00000          MOV      r0,#0                 ;189
0002ac  eafffff4          B        |L1.644|
                  |L1.688|
                          DCD      0xe0028000
                  |L1.692|
                          DCD      0x00001388
                  |L1.696|

...


varianta z volatile (deluje ok):

Koda:
                  wait_for_pulse PROC
;;;169    //---------------------------------------------------------------------------------//
;;;170    int wait_for_pulse()
00024c  e92d4070          PUSH     {r4-r6,lr}
;;;171    {
;;;172     volatile unsigned int maxtime, count;
;;;173   
;;;174     maxtime=40000;    // timeout 29.4ms
000250  e59f40a0          LDR      r4,|L1.760|
;;;175     count=0;
000254  e3a05000          MOV      r5,#0
;;;176   
;;;177     while (maxtime--)
000258  ea00000b          B        |L1.652|
                  |L1.604|
;;;178        {
;;;179        if (tst_CAL_CLK) count++;
00025c  e59f004c          LDR      r0,|L1.688|
000260  e5900000          LDR      r0,[r0,#0]
000264  e3100080          TST      r0,#0x80
000268  1a000001          BNE      |L1.628|
00026c  e2855001          ADD      r5,r5,#1
000270  ea000000          B        |L1.632|
                  |L1.628|
;;;180           else count=0;                  // if CLK goes low, reset counter
000274  e3a05000          MOV      r5,#0
                  |L1.632|
;;;181   
;;;182        if (count>50) {
000278  e3550032          CMP      r5,#0x32
00027c  9a000002          BLS      |L1.652|
;;;183                    return (1);}         // we got >40us high pulse
000280  e3a00001          MOV      r0,#1
                  |L1.644|
000284  e8bd4070          POP      {r4-r6,lr}
;;;184       
;;;185       }
;;;186   
;;;187    printf("ERROR: missing start pulse c=%i t=%i \n",count,maxtime);
;;;188   
;;;189    return (0);                           // 30ms has expired without high pulse
;;;190    }
000288  e12fff1e          BX       lr
                  |L1.652|
00028c  e1b00004          MOVS     r0,r4                 ;177
000290  e2444001          SUB      r4,r4,#1              ;177
000294  1afffff0          BNE      |L1.604|
000298  e1a02004          MOV      r2,r4                 ;187
00029c  e1a01005          MOV      r1,r5                 ;187
0002a0  e28f0054          ADR      r0,|L1.764|
0002a4  ebfffffe          [slovenščina je zame španska vas]       __2printf
0002a8  e3a00000          MOV      r0,#0                 ;189
0002ac  eafffff4          B        |L1.644|
                  |L1.688|
                          DCD      0xe0028000
                  |L1.692|
                          DCD      0x00001388
                  |L1.696|




varianta, kjer 2x deklariram maxtime: (deluje ok)

Koda:
                  wait_for_pulse PROC
;;;169    //---------------------------------------------------------------------------------//
;;;170    int wait_for_pulse()
00024c  e92d4070          PUSH     {r4-r6,lr}
;;;171    {
;;;172    unsigned int maxtime, count;
;;;173   
;;;174     maxtime=40000;maxtime=40000;    // timeout 29.4ms
000250  e59f50a4          LDR      r5,|L1.764|
000254  e1a00000          MOV      r0,r0
;;;175     count=0;
000258  e3a04000          MOV      r4,#0
;;;176   
;;;177     while (maxtime--)
00025c  ea00000b          B        |L1.656|
                  |L1.608|
;;;178        {
;;;179        if (tst_CAL_CLK) count++;
000260  e59f004c          LDR      r0,|L1.692|
000264  e5900000          LDR      r0,[r0,#0]
000268  e3100080          TST      r0,#0x80
00026c  1a000001          BNE      |L1.632|
000270  e2844001          ADD      r4,r4,#1
000274  ea000000          B        |L1.636|
                  |L1.632|
;;;180           else count=0;                  // if CLK goes low, reset counter
000278  e3a04000          MOV      r4,#0
                  |L1.636|
;;;181   
;;;182        if (count>50) {
00027c  e3540032          CMP      r4,#0x32
000280  9a000002          BLS      |L1.656|
;;;183                    return (1);}         // we got >40us high pulse
000284  e3a00001          MOV      r0,#1
                  |L1.648|
000288  e8bd4070          POP      {r4-r6,lr}
;;;184       
;;;185       }
;;;186   
;;;187    printf("ERROR: missing start pulse c=%i t=%i \n",count,maxtime);
;;;188   
;;;189    return (0);                           // 30ms has expired without high pulse
;;;190    }
00028c  e12fff1e          BX       lr
                  |L1.656|
000290  e1b00005          MOVS     r0,r5                 ;177
000294  e2455001          SUB      r5,r5,#1              ;177
000298  1afffff0          BNE      |L1.608|
00029c  e1a02005          MOV      r2,r5                 ;187
0002a0  e1a01004          MOV      r1,r4                 ;187
0002a4  e28f0054          ADR      r0,|L1.768|
0002a8  ebfffffe          [slovenščina je zame španska vas]       __2printf
0002ac  e3a00000          MOV      r0,#0                 ;189
0002b0  eafffff4          B        |L1.648|
                  |L1.692|
                          DCD      0xe0028000
                  |L1.696|
                          DCD      0x00001388
                  |L1.700|




Druga funkcija, s katero nimam nobenih problemov:

Koda:
                  wait_for_quiet PROC
;;;138   
;;;139    int wait_for_quiet()
0001f0  e92d4070          PUSH     {r4-r6,lr}
;;;140    {
;;;141     unsigned int maxtime, count;
;;;142   
;;;143     maxtime=35000;    // timeout 25ms
0001f4  e59f50e4          LDR      r5,|L1.736|
;;;144     count=0;
0001f8  e3a04000          MOV      r4,#0
;;;145     
;;;146     while (maxtime--)
0001fc  ea00000b          B        |L1.560|
                  |L1.512|
;;;147         {
;;;148        if (!tst_CAL_CLK) count++;            // if CLK is low, start counting
000200  e59f00ac          LDR      r0,|L1.692|
000204  e5900000          LDR      r0,[r0,#0]
000208  e3100080          TST      r0,#0x80
00020c  0a000001          BEQ      |L1.536|
000210  e2844001          ADD      r4,r4,#1
000214  ea000000          B        |L1.540|
                  |L1.536|
;;;149           else count=0;                  // if CLK goes high, reset counter
000218  e3a04000          MOV      r4,#0
                  |L1.540|
;;;150   
;;;151        if (count>66)  {                  // we got 50us
00021c  e3540042          CMP      r4,#0x42
000220  9a000002          BLS      |L1.560|
;;;152                   return (1);
000224  e3a00001          MOV      r0,#1
                  |L1.552|
000228  e8bd4070          POP      {r4-r6,lr}
;;;153                   }          
;;;154       }
;;;155   
;;;156     printf("wait for quiet failed\n");
;;;157     return (0);                           // time expired without quiet pulse
;;;158   
;;;159    }
00022c  e12fff1e          BX       lr
                  |L1.560|
000230  e1b00005          MOVS     r0,r5                 ;146
000234  e2455001          SUB      r5,r5,#1              ;146
000238  1afffff0          BNE      |L1.512|
00023c  e28f00a0          ADR      r0,|L1.740|
000240  ebfffffe          [slovenščina je zame španska vas]       __2printf
000244  e3a00000          MOV      r0,#0                 ;157
000248  eafffff6          B        |L1.552|
;;;160   
                          ENDP

_________________
Dobrga štromarja samo slab šnops strese!
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Umnik
Član
Član



Pridružen-a: Čet 16 Sep 2004 17:52
Prispevkov: 958
Aktiv.: 4.03
Kraj: Novo mesto

PrispevekObjavljeno: Pet Jan 21, 2011 11:52 pm    Naslov sporočila:   Odgovori s citatom

Če primerjaš orig. kodo in varianto z volatile ugotoviš, da med njima ni funkcionalne razlike, le registra R4 in R5 sta med seboj zamenjana, kar na delovanje nima vpliva.
Koda, glede na asemblerski izpis v obeh primerih deluje povsem pravilno in točno tako kot si napisal v Cju.

Primerjava originalne kode s tisto kjer se maxtime spremenljivki dvakrat zaporedoma določi vrednost vsebuje manjšo zanimivost, za katero si nisem mislil, da se bo zgodila - namreč, register R0 prepiše samega vase, brez da bi updatal kateri koli flag - podobno kot bi vstavil NOP instrukcijo, ki ne naredi nič Very Happy Če bi imel vklopljeno optimizacijo, pa bi compiler ukaz zavrgel.

Sklep? Funkcionalno gledano, so vse tri variante enake, le tista z 2x maxtime je en cikel daljša, ker si pač naredil en redundanten ukaz, ki ga compiler ni vrgel ven. Smile

Zadnja varianta se od prejšnjih treh spet razlikuje samo v vrednostih konstant in pa tisti klicaj upošteva, da veji na drug pogoj.

Enako je. Vse. Moje trditve od 1 do 4 držijo Wink
Tvoje težave so drugje. Kje? Iz tega izseka se ne da ugotoviti.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
damo
Član
Član



Pridružen-a: Čet 31 Jul 2003 13:45
Prispevkov: 2008
Aktiv.: 8.46
Kraj: Krško

PrispevekObjavljeno: Sob Jan 22, 2011 9:22 am    Naslov sporočila:   Odgovori s citatom

Pričakoval sem tak odgovor, ker sem tudi sam šel čez assembly. Vendar pa zadeva deluje ali pa ne, odvisno od primera kode. V vseh primerih je hardwer isti. In celo to, če koda dela, dela b.p., recimo izvedem jo 1000x, pa ne javi "falš" napak... Zato mi zadeva ni ravno jasna...
_________________
Dobrga štromarja samo slab šnops strese!
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
kastaneda
Član
Član



Pridružen-a: Pet 23 Okt 2009 11:18
Prispevkov: 459
Aktiv.: 2.40

PrispevekObjavljeno: Sob Jan 22, 2011 10:54 am    Naslov sporočila:   Odgovori s citatom

Poskusi namesto:
if (count>50)
z:
if (count>=50)

_________________
LP
Srečko
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Umnik
Član
Član



Pridružen-a: Čet 16 Sep 2004 17:52
Prispevkov: 958
Aktiv.: 4.03
Kraj: Novo mesto

PrispevekObjavljeno: Sob Jan 22, 2011 12:18 pm    Naslov sporočila:   Odgovori s citatom

Se pravi
- Imaš LPC2148
- Na pinu P0.7 imaš signal, ki je večino časa na 3.3V
- Ko gre signal na P0.7 za vsaj 40us na 0V, ga hočeš detektirat
- Timeout za detekcijo je 29.4ms

Povej, kakšna je frekvenca LPCja, pa ti tole prekodiram.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> ARM arhitektura Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Pojdi na stran 1, 2  Naslednja
Stran 1 od 2

 
Pojdi na:  
Ne, ne moreš dodajati novih tem v tem forumu
Ne, ne moreš odgovarjati na teme v tem forumu
Ne, ne moreš urejati svojih prispevkov v tem forumu
Ne, ne moreš brisati svojih prispevkov v tem forumu
Ne ne moreš glasovati v anketi v tem forumu
Ne, ne moreš pripeti datotek v tem forumu
Ne, ne moreš povleči datotek v tem forumu

Uptime: 7 dni


Powered by phpBB © 2001, 2005 phpBB Group