 |
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
damo Član


Pridružen-a: Čet 31 Jul 2003 13:45 Prispevkov: 2008 Aktiv.: 8.46 Kraj: Krško
|
Objavljeno: Sre Jan 19, 2011 2:12 pm Naslov sporočila: Nerazumljiv problem v C-ju |
|
|
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 |
|
 |
mucek4 Član


Pridružen-a: Sob 18 Jun 2005 20:52 Prispevkov: 2952 Aktiv.: 12.43 Kraj: Tržič - Mesto med gorami
|
Objavljeno: Sre Jan 19, 2011 3:09 pm Naslov sporočila: |
|
|
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 |
|
 |
damo Član


Pridružen-a: Čet 31 Jul 2003 13:45 Prispevkov: 2008 Aktiv.: 8.46 Kraj: Krško
|
Objavljeno: Sre Jan 19, 2011 3:18 pm Naslov sporočila: |
|
|
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 |
|
 |
red_mamba Član


Pridružen-a: Ned 20 Feb 2005 17:56 Prispevkov: 1486 Aktiv.: 6.26 Kraj: Yogyakarta
|
Objavljeno: Sre Jan 19, 2011 3:47 pm Naslov sporočila: |
|
|
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 |
|
 |
red_mamba Član


Pridružen-a: Ned 20 Feb 2005 17:56 Prispevkov: 1486 Aktiv.: 6.26 Kraj: Yogyakarta
|
Objavljeno: Sre Jan 19, 2011 3:49 pm Naslov sporočila: |
|
|
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 |
|
 |
damo Član


Pridružen-a: Čet 31 Jul 2003 13:45 Prispevkov: 2008 Aktiv.: 8.46 Kraj: Krško
|
Objavljeno: Sre Jan 19, 2011 4:24 pm Naslov sporočila: |
|
|
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 |
|
 |
Gklemen Član


Pridružen-a: Sob 29 Nov 2008 0:06 Prispevkov: 112 Aktiv.: 0.55 Kraj: Rogatec
|
Objavljeno: Sre Jan 19, 2011 6:33 pm Naslov sporočila: |
|
|
kaj pa je s tem:
enkrat imaš
Citiram: |
if (tst_CAL_CLK) |
, drugič pa
Citiram: |
if (!tst_CAL_CLK) |
? |
|
Nazaj na vrh |
|
 |
damo Član


Pridružen-a: Čet 31 Jul 2003 13:45 Prispevkov: 2008 Aktiv.: 8.46 Kraj: Krško
|
Objavljeno: Sre Jan 19, 2011 6:51 pm Naslov sporočila: |
|
|
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 |
|
 |
Benjamin Član

Pridružen-a: Tor 10 Jul 2007 11:23 Prispevkov: 116 Aktiv.: 0.53 Kraj: Trebnje, Ljubljana
|
Objavljeno: Sre Jan 19, 2011 7:52 pm Naslov sporočila: |
|
|
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 |
|
 |
Umnik Član

Pridružen-a: Čet 16 Sep 2004 17:52 Prispevkov: 958 Aktiv.: 4.03 Kraj: Novo mesto
|
Objavljeno: Čet Jan 20, 2011 12:25 am Naslov sporočila: |
|
|
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 |
|
 |
damo Član


Pridružen-a: Čet 31 Jul 2003 13:45 Prispevkov: 2008 Aktiv.: 8.46 Kraj: Krško
|
Objavljeno: Čet Jan 20, 2011 9:22 am Naslov sporočila: |
|
|
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 |
|
 |
Umnik Član

Pridružen-a: Čet 16 Sep 2004 17:52 Prispevkov: 958 Aktiv.: 4.03 Kraj: Novo mesto
|
Objavljeno: Pet Jan 21, 2011 11:52 pm Naslov sporočila: |
|
|
Č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č Č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.
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
Tvoje težave so drugje. Kje? Iz tega izseka se ne da ugotoviti. |
|
Nazaj na vrh |
|
 |
damo Član


Pridružen-a: Čet 31 Jul 2003 13:45 Prispevkov: 2008 Aktiv.: 8.46 Kraj: Krško
|
Objavljeno: Sob Jan 22, 2011 9:22 am Naslov sporočila: |
|
|
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 |
|
 |
kastaneda Član


Pridružen-a: Pet 23 Okt 2009 11:18 Prispevkov: 459 Aktiv.: 2.40
|
Objavljeno: Sob Jan 22, 2011 10:54 am Naslov sporočila: |
|
|
Poskusi namesto:
if (count>50)
z:
if (count>=50) _________________ LP
Srečko |
|
Nazaj na vrh |
|
 |
Umnik Član

Pridružen-a: Čet 16 Sep 2004 17:52 Prispevkov: 958 Aktiv.: 4.03 Kraj: Novo mesto
|
Objavljeno: Sob Jan 22, 2011 12:18 pm Naslov sporočila: |
|
|
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 |
|
 |
|
|
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
|