Fórum témák
» Több friss téma |
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:
a fordítása a 3. sornak:
A hozzászólás módosítva: 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
Hű, most teljesen új dolgot mondtál. Mi az a trap és mire jó? Hol kell módosítani?
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:
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). 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.
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
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.
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
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?
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.
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!
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.
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:
És így áll össze a file név:
É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.
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.
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.
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.
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.
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.
Ha jól tudom a memcpy megvizsgálja, hogy tud-e 16 bites másolást csinálni, mert úgy gyorsabb: Bővebben: Link
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.
Akkor így végkép nem értem mi lehet a baj! :S
Azt tudod, hogy pontosan melyik muvelet okozza az address error-t?
Ha debugolás közben nézem az assembly utasításokat, akkor ennél a sornál:
Hat, ez nem sokat mond. A kerdes az, a C kodban hol akad el. Ezt biztosan nem a memcpy() csinalja.
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?
|
Bejelentkezés
Hirdetés |