Fórum témák

» Több friss téma
Fórum » PIC programozása C nyelven, C-Compiler
Lapozás: OK   102 / 153
(#) Beles válasza icserny hozzászólására (») Aug 1, 2014 /
 
Akkor szerintem a nagy tömbnél maradok!
Pic24EP128mc202-őt használok.
Ezt az utasítást a compliler fordítja le. Bemásolom az egészet.
A c kód:
  1. wchar_t* wszfileName = (wchar_t*)malloc(sizeof(wchar_t)*(lfnEntry.OrdinalField & 0x3F) * 13);
  2. ...
  3. memcpy(&wszfileName[OrdinalField - 13], lfnEntry.FileName, sizeof(lfnEntry.FileName));


a fordítása a 3. sornak:
  1. 005CA  FB801E     ze [0x001c],0x0000
  2.  005CC  400000     add.w 0x0000,0x0000,0x0000
  3.  005CE  780080     mov.w 0x0000,0x0002
  4.  005D0  90001E     mov.w [0x001c+2],0x0000
  5.  005D2  408000     add.w 0x0002,0x0000,0x0000
  6.  005D4  50017A     sub.w 0x0000,#26,0x0004
  7.  005D6  200260     mov.w #0x26,0x0000
  8.  005D8  40000E     add.w 0x0000,0x001c,0x0000
  9.  005DA  E80000     inc.w 0x0000,0x0000
  10.  005DC  780080     mov.w 0x0000,0x0002
  11.  005DE  780002     mov.w 0x0004,0x0000
  12.  005E0  BE0111     mov.d [0x0002],0x0004
  13.  005E2  BE8802     mov.d 0x0004,[0x0000]
  14.  005E4  400064     add.w 0x0000,#4,0x0000
  15.  005E6  4080E4     add.w 0x0002,#4,0x0002
  16.  005E8  BE0111     mov.d [0x0002],0x0004
  17.  005EA  BE8802     mov.d 0x0004,[0x0000]
  18.  005EC  400064     add.w 0x0000,#4,0x0000
  19.  005EE  4080E4     add.w 0x0002,#4,0x0002
  20.  005F0  780811     mov.w [0x0002],[0x0000]
A hozzászólás módosítva: Aug 1, 2014
(#) pipi válasza Beles hozzászólására (») Aug 1, 2014 /
 
Hali!
Trap-okat lekezeled rendesen?
A gyári trap mintát ilyenkor le szoktam módosítani végtelen hurokra, igy debuggerrel megállítva a program futását, látszik mi történt
(#) Beles válasza pipi hozzászólására (») Aug 2, 2014 /
 
Hű, most teljesen új dolgot mondtál. Mi az a trap és mire jó? Hol kell módosítani?
(#) icserny válasza Beles hozzászólására (») Aug 2, 2014 /
 
Az előző beírásomat felejtsd el, mert megtévesztett a disassembly lista félreérthető jelölése! A mov.d 0x0004,[0x0000] utasítás valójában mov.d W4,[W0] típusú, nem pedig MOV.d f,[f] típusú!

A mostani példádban pedig a 78nnnn utasításkódú utasítások mind MOV.w Ws,Wd típusúak (Ws a forrás, Wd a cél regiszter). A szögletes zárójel pedig indirekt címzést jelent (az adatmozgatás a regiszterben tárolt címről/címre történik).

Ha jól értelek, a probléma most a disassembly lista 17. sorában következik be:
  1. mov.d 0x0004,[0x0000]


Ez egy MOV.d W4,[W0] 32 bites adatmozgató utasítás. Az előtte levő pedig egy MOV.d [W2],W4 utasítás. Tehát a memcopy-nál W2 a forrás cím, ahonnan másol, W0 pedig a cél címe, ahová másol. A másolás közvetlenül nem megy, ezért a W4 regiszteren keresztül történik az adatmozgatás.

A W0 és W2 tartalmának ellenőrzésével (az SFR elején lehet, hoyg ezek WREG0 és WREG2 névre hallgatnak) ellenőrizni tudod, hogy a címek jó helyre mutatnak, s hogy érvényesek-e (a cím a 32 bites igazításnak megfelelően néggyel osztható szám).
(#) icserny válasza Beles hozzászólására (») Aug 2, 2014 /
 
Idézet:
„Mi az a trap és mire jó?”

Az 1-5. megszakítási vektorok. Bővebben: Link

Idézet:
„Hol kell módosítani?”

A _DefaultInterrupt() kiszolgáló eljárásban. Ez az alapértelmezett kiszolgáló rutin.
(#) Beles válasza icserny hozzászólására (») Aug 2, 2014 /
 
Köszi a segítséget, nagyon tetszik ez a hibakezelés, nem is tudtam hogy lehetőség van így megoldani! (Sok mindent nem tudok még)
INTTREG = 00001110 00000001, azaz Adress error?
A hozzászólás módosítva: Aug 2, 2014
(#) Beles válasza Beles hozzászólására (») Aug 2, 2014 /
 
Sajnos nem tudom miért lesz adress error, mert annál a lépésnél egy 256 elemű tömb 13 eleméhez történik a másolás 4 darab karakterrel. Nem lépem túl a tömb határait.
(#) AZoli válasza Beles hozzászólására (») Aug 2, 2014 /
 
Nem néztem végig a programodat, de adress trap akkor szokott jönni ha pl. int típusú mutató páratlan címre mutat. Mert ugye 16 bites kontrolleren az int tömb elemei páros memóriacímeken érhetőek el.
A hozzászólás módosítva: Aug 2, 2014
(#) killbill válasza AZoli hozzászólására (») Aug 2, 2014 /
 
address
(#) AZoli válasza killbill hozzászólására (») Aug 2, 2014 /
 
Valóban, bocs.
(#) Beles válasza AZoli hozzászólására (») Aug 2, 2014 /
 
Valóban páratlan az egyik pointer címe :S. Mégpedig a struktúra eleme, az lfnEntry.FileName címe 0x13A3. A baj csak az, hogy a struktúrán nem tudok változtatni, mert __attribute__((aligned(1), packed))-ként van definiálva. Azért így, mert egy char tömbből van feltöltve szintén memcpy utasítással.
Hogyan tudom ezt megoldani? Használjak mást memcpy helyett? Vagy azt kellene elérnem, hogy 8bites másolással csinálja, és akkor lehetnek páratlan pointerek is?
(#) AZoli válasza Beles hozzászólására (») Aug 2, 2014 /
 
Nem teljesen értelek, de akkor lehet páratlan a mutató, ha 8 bites változókat tartalmazó tömbre mutat, és ekként is van definiálva. Pl: char tömbre. Vagyis ekkor nem fog address trap-et okozni.
(#) Beles válasza AZoli hozzászólására (») Aug 2, 2014 /
 
Pont ez a baj, hogy nem 8 bites, mert wchar_t a változók. Amikor feltöltöm a struktúrát, ott char-al töltöm fel, de a bemásolt függvénynél már wchar-t van!
(#) killbill válasza Beles hozzászólására (») Aug 2, 2014 /
 
Mikor kapod az address error-t? Mert szerintem nem akkor, amikor a memcpy (ami nem utasitas, hanem fuggveny) masol bele. A memcpy tetszoleges cimrol masol tetszoleges cimre, annak nem kell aligned legyen semmi.
(#) Beles válasza killbill hozzászólására (») Aug 2, 2014 /
 
Az aligned azért van, mert egy memória kártyáról szeretnék adatokat olvasni. Kiolvasok egy szektort(512 byte-ot), és utána másolom bele a struktúrába az adatot. Ezzel nincs is probléma. A probléma akkor van, mikor a hosszú filenevet akarom megcsinálni, ugyanis a struktúrán belül össze vissza van a string. Így néz ki az lnfEntry:
  1. typedef struct __attribute__((aligned(1), packed))              //Hosszú filenevek
  2. {
  3.         char OrdinalField;
  4.         wchar_t FileName[5];
  5.         int Flag;
  6.         char Reserved;
  7.         wchar_t FileName2[6];
  8.         int Reserved2;
  9.         wchar_t FileName3[2];
  10. }
  11. LFNENTRY, *PLFNENTRY;

És így áll össze a file név:
  1. wchar_t wszfileName[256];
  2. int OrdinalField = (lfnEntry.OrdinalField & 0x3F) * 13;
  3. memcpy(&wszfileName[OrdinalField - 2], lfnEntry.FileName3, sizeof(lfnEntry.FileName3));
  4. memcpy(&wszfileName[OrdinalField - 8], lfnEntry.FileName2, sizeof(lfnEntry.FileName2));
  5. memcpychr(&wszfileName[(OrdinalField - 13)], lfnEntry.FileName, sizeof(lfnEntry.FileName)*2);
(#) AZoli válasza Beles hozzászólására (») Aug 2, 2014 /
 
Én még azt sem értem mi az a wchar_t... egy típus? Netán word-char tehát 16 bites akar lenni?
Ha egy char *mutato -val muszáj 16 bites adatok között kotorászni, akkor mutato*2 . Vagy lehet hogy működik az int muatóvá konvertálás.
(#) Beles válasza AZoli hozzászólására (») Aug 2, 2014 /
 
Igen, word char, 16bites!
(#) killbill válasza Beles hozzászólására (») Aug 2, 2014 /
 
Azt nem ertem, hogy az 5. sorban mi az a memcpychr() (sosem hallottam errol a foggvenyrol, de nem is szabvanyos C konyvtari darab), es miert van a vegen sizeof(..) * 2?

Mondjuk azt sem ertem, hogy miert kell -2, -8 es -13? Az OrdinalField 0, 13, 26, stb. Igy egybol lesz egy negativ index, amikor OrdinalField = 0.
(#) Beles válasza killbill hozzászólására (») Aug 2, 2014 /
 
Bocsi, már én csináltam próbából a memcpychr() függvényt
Nem lesz negatív index, mert az OrdinalField legkisebb értéke 1 lehet.
C++-ban számítógépen működik is a kód, csak PIC-en nem.
(#) killbill válasza Beles hozzászólására (») Aug 2, 2014 /
 
A memcpychr() eseten sem ertem a sizeof(...) * 2-t, ugyanis a sizeof() mindig char-ban adja meg a meretet, azaz a te esetetben byte-ban. Egy 2 elemű uint16_t tomb sizeof()-ja az 4.

Egyebkent meg passz. A memcpy szabvany szerint barhonnan barhova tud masolni. Az nem adhat address error-t. Azt nem tudom, hogy akkor mi van PIC-en, ha 0 cimre hivatkozik valaki, de a C szabvany szerint a 0 cimre valo hivatkozas nem megengedett. Egy ismerosom nemreg szivott ezzel valamilyen PIC-en, hogy 0 cimrol olvasott fel adatot es elszallt a programja.

Biztos, hogy az adott PIC-en is 16 bites a wchar_t? Es 16 bites az int? Mert pl. pic32-n 32 bites. Nem veletlenul vannak az uint16_t, int32_t es tarsaik az stdint.h-ban. Ilyen esetekben erdemes ezeket a tipusokat hasznalni, mert ha kesobb ezt a kodot atviszed mas processzorra, akkor is jo lesz.

Idézet:
„Nem lesz negatív index, mert az OrdinalField legkisebb értéke 1 lehet.”

Elvileg... De a gyakorlatban lehet 0 is. Erdemes az ilyesmire felkeszulni.
(#) Beles válasza killbill hozzászólására (») Aug 2, 2014 /
 
Igazad van, a * 2 az hülyeség!
De korábban írták, hogy nem lehet a mutató páratlan 16bites másolás esetén, nekem meg páratlan lesz a struktúra FileName eleme miatt, és ez lehet a baj.
(#) killbill válasza Beles hozzászólására (») Aug 2, 2014 /
 
Mi az hogy 16 bites masolas?

Mivel a cimet a memcpy()-nak adod at, ami void * mutatokat var, biztos lehetsz benne, hogy nem az a baj.
(#) Beles válasza killbill hozzászólására (») Aug 2, 2014 /
 
Ha jól tudom a memcpy megvizsgálja, hogy tud-e 16 bites másolást csinálni, mert úgy gyorsabb: Bővebben: Link
(#) killbill válasza Beles hozzászólására (») Aug 2, 2014 /
 
Igen megvizsgalja, es csak akkor masol 16 bitesen, ha a cim paros. Sot, az is lehet, hogy az elso byte-ot atmasolja, ha paratlan cimrol indul, es utana mar 16 bitesen masol. 32 bites processoron meg 32 bitesen is masol, mert az meg még gyorsabb. Egy biztos, a memcpy-nak akarmilyen, nullatol kulonbozo cimet adhatsz, az hibatlanul kell masoljon.
(#) Beles válasza killbill hozzászólására (») Aug 2, 2014 /
 
Akkor így végkép nem értem mi lehet a baj! :S
(#) killbill válasza Beles hozzászólására (») Aug 2, 2014 /
 
Azt tudod, hogy pontosan melyik muvelet okozza az address error-t?
(#) Beles válasza killbill hozzászólására (») Aug 2, 2014 /
 
Ha debugolás közben nézem az assembly utasításokat, akkor ennél a sornál:
  1. mov.d 0x0004,[0x0000]
(#) killbill válasza Beles hozzászólására (») Aug 2, 2014 /
 
Hat, ez nem sokat mond. A kerdes az, a C kodban hol akad el. Ezt biztosan nem a memcpy() csinalja.
(#) Beles válasza killbill hozzászólására (») Aug 2, 2014 /
 
De a c kódban a memcpy-nél akad el!
(#) killbill válasza Beles hozzászólására (») Aug 2, 2014 /
 
Akkor hibas a memcpy(), vagy 0 esetleg negativ cimet kap bemenetnek. A fenti assembly sor a W4 erteket leteszi arra a cimre, ami a W0-ban van. Kerdes, hogy mi van a W0-ban?
Következő: »»   102 / 153
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem