Fórum témák
» Több friss téma |
Fórum » PIC - Miértek, hogyanok haladóknak
A pontos típust nem adtad meg, és feltételezem, hogy C-ben írod a programot.
Ott a leggyakoribb eshetőség, hogy valamilyen buffer túlírása történik, és ezzel a stack felülírása. A stackben lévő visszatérési címek átírása pedig okozhat ilyen jelenséget. A fordítók általában az adatmemória végére teszik a stack-et, ezért lehet ezt viszonylag könnyen elérni. Megnézném az string műveleteket, Ha eddig nem így csináltad, akkor kerülni kell a nem limitáltakat. strcpy, strcat, strtok, sprintf, etc. Ha ezeket nem használod, akkor még mindig van sok lehetőség a buffer túlírásra, például a cast nem megfelelő használatával, stb. A másik lehetőség, ami szokatlan újrainduláshoz vezethet, ha túl kicsi a stack, de ha jól sejtem akkor a _StackError trap ennek figyelésére van, szóval itt az - ha minden igaz - nem játszik, de nem vagyok erről teljesen meggyőzve, legalábbis egy dspic adatlap alapján amit néztem, ezért is kellene a pontos típus. Az INTCON2, SWTRAP-et 1-be állítottad?
Igen, ez is egy lehetséges ok tud lenni ilyenkor!
Viszont mivel ez a jelenség ugyanazon a hardveren, egyetlen egy üzemmódjában fordult eddig elő úgy, hogy közben a hardveres körülmények nem változtak, így inkább kizárnám az ilyen jellegű okot! Én azt gondolom tisztán szoftveres eredetű jelen esetben a probléma. Azt viszont nagyon nem zárom ki, hogy a fordító a ludas(vagy az én hiányos tudásom a C nyelv speciális rejtelmeit illetően)
dsPIC33EP32GS504 a konkrét típusa a mikrovezérlőnek! Igen, teljesen C-ben írta a program, sehol sincs asm betét benne, így pl a W regisztereket sem birizgálom közvetlenül.
Idézet: „Ott a leggyakoribb eshetőség, hogy valamilyen buffer túlírása történik, és ezzel a stack felülírása” Ez...benne van a pakliban! Van erre lehetőség, hogy módosítsuk a stack elhelyezkedését? Mondjuk, már a méret módosítása is lehet erre hatással, azt könnyen ki tudom próbálni majd... Nem használom az általad megadott függvényeket, minden string művelet gyakorlatilag abban merül ki, hogy string-re mutató tömbökből jelenítek meg szövegeket. Semmi manipuláció velük nincs... Idézet: „Az INTCON2, SWTRAP-et 1-be állítottad?” Nem, tegnap óta nem volt időm foglalkozni ezzel, most ültem le először gép elé ) Gyakorlatilag még azt sem néztem meg, hogy a feljebb jelzett megszakítások működtek e?! Ez alapján gondolom nem... ) Kösz, hogy felhívtad rá külön a figyelmem...!
Akkor teszteléssel, logolással be kell szűkíteni a hiba előfordulását és utána a kód elemzésével, debuggolásával meg kell találni.
Ez zajlik most! De roppant nehéz leszűkíteni a kört, amikor csak annyi infóm van, hogy a hiba keletkezése kb milyen üzemmódnál van?! Mert hogy nagyjából ugyanazokat a függvényeket használom mindenhol...!
Ez a legnagyobb bajom, hogy nem tudom, hogy lehetne elkapni azt a pillanatot, amikor keletkezik a hiba, hogy debugeren megnézhessem, hol, mi száll el, vagy kap olyan értéket, amit nem kellene... Az ilyen típusú hiba nem egy normál hiba, amit általában simán ki debugol az ember fia..., max csak némi fantázia és türelem kell hozzá, ilyennel még nem volt dolgom..., pedig már több mint 20 éve programozok mikrovezérlőket...
dsPIC esetén az adatlap mellett érdemes a Reference manual-okat is átolvasni, mert sokkal részletesebb infókat ad. Például az RCON bitjeit mi állítja be és mi törli, ebben le van írva részletesen: Bővebben: Link 8.3 fejezet
És az is, hogy milyen eseményre állítódik be a IOPUWR a PCON-ban. A másik a Trap-ekről: Bővebben: Link 3.1.1 fejezet Ha a stack error trap bekövetkezik, akkor a handler-ben a W15 és a SPLIM regiszterek tartalmát érdemes megnézni, lementeni későbbi vizsgálatra. De ha jól értem az SPLIM-et egyszer írni kell a program elején, hogy a stack túlcsordulás ellenőrzés működjön. Ahogy látom a stacket az xc16 automatikusan a felhasznált adatterület után és a memória végéig teszi a fordító. Esetleg a stack elé lehet fixen lehet tenni x byte-ot, amit fix mintával, pl 0xDEADBEAF feltöltesz, és ha reset után az felülíródik akkor az van amit írtam.
Szabad lábakra ledeket rakni, programba befűzni, így is szűkíthető a hiba keletkezési köre...A program meg "ne induljon" automatikusan, hanem pl gombnyomásra várjon, itt esetleges újraindulásnál meg tudod állítani debuggerrel, és megnézni a memóriát/regisztereket, már amiket az esetleges reset nem töröl
A hozzászólás módosítva: Márc 4, 2023
Nincs szabad láb! Mind a 44 foglalt...
Az a gond, újraindulásnál a debug folyamat is meg fog szakadni, így minden ilyen maga után vonja a legtöbb hadveres regiszter törlődését is. Abban igazad van, hogy a ram tartalma megmarad, de elég sok adatot kellene végig mazsolázgatnom ahhoz, hogy bármit is kezdjek vele. Nem túl reális ez...a leges legvégső esetre tartogatnám csak.
Tegnap tesztelgettem a programot..., elsősorban a stack beállításokra voltam kíváncsi, ad e valami változást?!
Igen, a doksik alapján a fennmaradó ram-ot felhasználta a stackre a fordító alapban, minusz az eseteges heap méret... A stack-et legkönnyebben a heapon keresztül tudtam módosítani..., de a méret változáson kívül nem okozott javulást. Vagy csak még jobban romlott a helyzet... Majd arra gondoltam, talán kevés lehet a fennmaradó kb ~160byte ram a megfelelő méretű stack igényhez?! Megváltoztattam az egyik nagy puffer által lefoglalt méretet úgy, hogy kb 60byte plusz ram szabadult így fel, a stack számára. Meglepetésre, az így lefordított program hibátlanul fut, egész éjszaka futott, és nem volt egy reset sem! Szerintem ez is azt mutatja, valójában itt egy nem létező program hibát kergettem, ahol is nem a forráskód volt kivételesen a ludas, hanem inkább a fordító okozott valamit, amit nem kellett volna, de legalábbis ha kevés a stack, azt valahogy jobban meghatározni, és figyelmeztetni a programozót... Amit korábban írtam, hogy ugyanaz a program(fordítás), de debug módban futtatva a készüléket, sem produkálta már a hibát. Ez is számomra azt mutatta, feltehetően nem konkrétan a kódban van itt a kutya elásva...
A probléma úgy tűnik, megoldódott, mindenkinek köszönöm az agyalást és segítséget!
Jól megszaladt az a ceruza, ami az árat leírta.
Én a ICD4-t még 60eFt alatt vettem kb. 2 éve, lassan a Pickit5 ára lesz ennyi.
47L04 EERAM-al kapcsolatban kérdezném (aki már használt ilyet). Elvileg ugye ha elfogy a tápja, és aktív az automatikus mentés, akkor menti az SRAM tartalmát az EEPROM-ba, bekapcsoláskor pedig visszatölti.
Hogyan kezeli, ill mi történik ha mondjuk éppen egy 32 bites változót, vagy egy nagyobb struktúrát frissítek, és közben fogy el a táp? Tehát ilyenkor lehetnek félig megírt adatok, és ezt tudni kell kezelni szoftverből, avagy ezt is kezeli valahogyan? Tehát mi történik ilyenkor (pufferel, kihagyja a mentést ha éppen írás közben fogy el a táp, vagy egy korábbi, az aktuális írás előtti állapot mentődik)?
Én 47C16-os variánssal játszottam, nekem sikerült szándékosan többször is kommunikáció közben kikapcsolni a rendszert, vegyes eredmények születtek. Nekem is eszembe jutott a kérdésed, éppen ezért inzultáltam alaposan a kapcsolást. Két példányban mentettem az adatokat, ellenőrzőösszeggel. Volt, amikor mindkét adat hibás lett. A tévedés jogát fenntartom, miszerint valamit alaposan elbaltáztam és ami történt, "normális".
Azóta inkább diódás, kondenzátoros puffert kapnak azok a kontrollerek, amelyeket ilyen igényű mentéssel akarok felruházni. Kell egy extra láb hozzá, de az eddig még sosem hibázott. Bekapcsoláskor a láb analóg bemenet. Addig nem lép tovább a program, amíg a figyelt lábon el nem éri a feszültség a biztonságos szintet. Ezután a lábat átkapcsolom egy komparátor bemenetére, megszakítást kapcsolok rá. Ha az jelez, menti az adatokat az EEPOM-ba, majd RESET. 2200 µF-dal még újra elindul a program, de a figyelt lábon (ami a kondenzátor és a dióda elé van kötve) nincs feszültség, csak a homokórázás megy, amíg elfogy a kondenzátorból az energia. Egy-két megfonolandó dologról ebben a kérdésben itt már írtam: Bővebben: Link.
Arra gondoltam, hogy két különböző helyre mentem az adatokat, de felváltva. Így ha elszáll az utolsó memória írás közben, akkor az utolsó előtti adat mentése (ami jóval korábban történt) még jó lehet. De lehet, hogy hibás az elméletem...
Az adatlapon nézem, hogy a 47x16-hoz nagyobb kondit javasol, mint a 04-hez. Esetleg próbáltad ezt a kondit kicsit túlméretezni? Ha az automatikus eeprom mentés aktív az IC-ben, akkor az MCU-ban nem lenne elegendő az I2C-hez való hozzányúlást tiltani, amikor elfogy a táp? (hogy ilyenkor már ne akarja írni az SRAM-ot)
Ha menteni kellett adatot, azonnal két helyre mentettem, nem felváltva. Sokáig nem játszottam vele, mert lelohadt a lelkesedésem több hiba után. Próbáltam nagyobb kondenzátorokat is (éppen milyen volt itthon), nem sok eredménnyel.
Ha akkor lőttem le a tápfeszültséget (kontroller és EERAM egy tápvonalon), amikor folyamatban volt az írás, nagy valószínűséggel hibázott valami. Lehet, hogy az azonnali I2C tiltás segített volna, eddig nem jutottam el. Könnyen lehet, hogy a kontroller "zavarta össze" az EERAM-ot, nem analizáltam a hibát, a való életben nem tudom biztosítani hogy akkor legyen áramszünet, amikor éppen nincs mentés. Nem lebeszélni akarlak róla, csak megosztom a rövid tapasztalatom az EERAM-mal. Mielőtt éles bevetésre küldöd, teszteld erősen.
Én a 64kB-os SPI verziót (48L640) használom több, mint egy éve több helyen is. A leírás szerint a sikeresen átküldött adat bekerül a RAM-ba majd onnan már ez mentődik el az EEROM-ba, ahol megszakadt a kiírás az az adat már természetesen nem kerül be a RAM-ba, így kiírásra sem (adatlap 2.3.1 WRITE OPERATION pont).
Én úgy használom, hogy a PIC észleli a táp megszűnését és ha van aktív EERAM írás, akkor a PIC az éppen aktív adattömb kiküldését az EERAM-nak még befejezi. A PIC és az EERAM egy 330µF kondin "lógnak" és ez elegendő, hogy mindkettő még működjön addig, míg az összes adatot ki nem írja, majd a PIC-et elküldöm aludni. Én csak egy helyre írok ki, de van mellette 2 helyen CRC az egyes adattömbökre. Ebben a felállásban még soha nem volt hibás adatkiírásom, vagy adatvesztésem táp megszűnés esetén sem (ezt is teszteltem logikai analyzátort használva).
Az SRAM mentését az EEPROM-ba a szoftvered indítja, vagy az EERAM automatikus mentése intézi a tápfesz csökkenésekor? A 47L04-nek van egy lába amin kezdeményezni lehet az SRAM mentését az EEPROM-be, tehát ehhez hasonló módon használod?
Máshol is érdeklődtem a témában, és az a tippet kaptam, hogy miért nem FRAM-ot használok inkább?
Tehát FRAM-ot használ valaki? Idézet, egy TME-s adatlapból: Idézet: „FM24CL16B 16-Kbit (2 K × 8) Serial (I2C) F-RAM Document Number: 001-84456 Rev. *I Revised August 6, 2015 16-Kbit (2 K × 8) Serial (I2C) F-RAM Features ■ 16-Kbit ferroelectric random access memory (F-RAM) logically organized as 2 K × 8 ❐ High-endurance 100 trillion (1014 ) read/writes ❐ 151-year data retention (See the Data Retention and Endurance table) ❐ NoDelay™ writes ❐ Advanced high-reliability ferroelectric process ■ Fast 2-wire Serial interface (I2C) ❐ Up to 1-MHz frequency ❐ Direct hardware replacement for serial (I2C) EEPROM ❐ Supports legacy timings for 100 kHz and 400 kHz ■ Low power consumption ❐ 100 µA active current at 100 kHz ❐ 3 µA (typ) standby current ■ Voltage operation: VDD = 2.7 V to 3.65 V ■ Industrial temperature: –40°C to +85°C ■ Packages ❐ 8-pin small outline integrated circuit (SOIC) package ❐ 8-pin dual flat no leads (DFN) package ■ Restriction of hazardous substances (RoHS) compliant”
A lényegen nem változtat, valahogy figyelni kell a tápfeszültséget és biztosítani energiát arra az időre, amíg befelyeződik az írás. helektro kolléga így oldotta meg, nagy valószínűséggel ezért nincs hibás mentése. Naívan azt hittem, mindegy, mikor van lámpaoltás.
Régi cuomnál analóg táp volt, és a pufferkondi feszültségét figyeltem, ami magasabb a tápfesztől, így jóval több idő áll rendelkezésre a szabályos megállásra. Ha kapcsi táp van, akkor csak a normál tápfeszt lehet figyelni, nehezebb a működési fesztartományon belül detektálni, lezárni a folyamatokat
Pont a tápfesz figyelést akarom elkerülni, ha tudom , hogy elmegy a táp akkor akár a flash-be is menthetek, csak pufferméret kérdése lenne. Egy adott készüléken kisebb hardver módosítás, ha csak az EEPROM-ot cserélem le egy másik típusra... ami történetesen már nem is EEPROM
FRAM esetén is menthetnék 2 (vagy több) példányban, CRC-vel stb... és ot nincvs háttér mentés, csak egyszerűen nem felejt a RAM, ráadásul sok nagyságrenddel több írást visel el. A hozzászólás módosítva: Júl 23, 2023
Próba szerencse. Nekem az jött le a kísérleteimből, hogy az EERAM hibázik, én is a tápfesz figyelést akartam elkerülni.
Ha már játszottál FRAM-mal, ereményekért várjuk vissza.
Az, hogy FRAM vagy EERAM amibe az adatot mented, tök mindegy. A probléma ott kezdődik, amikor épp írásod van folyamatban és közben elmegy a táp. Ebben az esetben mindkét memória ugynaúgy fog viselkedni, a még sikeresen kiküldött adat megmarad, a tápfesz megszűnés miatt félbemaradt írás pedig el fog veszni. Azt, hogy a tápfesz megszűnése után hogy tárolódik az adat memóriában az adott memória típusnál, az az adatkonzisztenciára nincs hatással.
Az EERAM-nak annyi hátránya leheta FRAM-al szemben, hogy indulásnál az EERAM esetén kell x ms-ot várni, míg az EEROM-ból a RAM-ba betölti az adatokat (pontos késleltetési idő benne van a specóban).
Igen, de ezt a problémát több példányban (különböző címre) mentéssel elvileg ki lehet küszöbölni nem?
Viszont Bakman írta, hogy neki előfordult, hogy mindkét mentett blokk sérült. Azon gondolkozom, hogy ez hogyan történhetett meg, és FRAM esetén megtörténhet-e, hogy olyan terület is sérül, amit éppen nem írok?
Nekem az SPI-s verzióval még soha nem volt hibás adatom normál működés során (debug-nál előfordul, de az egy másik történet). Ha hibázna maga a chip akkor azt nem lehetne használni semmire, cégek se használnák, pedig sok millió darabot eladott belőle a microchip.
A hozzászólás módosítva: Júl 23, 2023
Szia!
A mostani melómnál én is EEramot használok, most megy a tesztelése ,ami eddig hiba nélkül megy. Az én megoldásom ,hogy a beírt adat legvégén van sorszám ,amit írás után növelem ,és ami nálam a legbiztosabb, hogy beírás után egyből ellenőrzöm, hogy jó e az amit beírt. Újraindítás után nézem a sorszámot, és az utolsót visszaolvasom. Itt csak a lényeg, hogy 2 vagy több helyre kell menteni. Én 3 helyre mentek,így min. 2 szám követi egymást. 2 mentésnél nem biztos, hogy a jót találod meg . De még megoldás lehet, ha valami crc-t dobsz rá, bár akkor is meg kell tudni állapítani, hogy melyik volt az utolsó mentés. |
Bejelentkezés
Hirdetés |