Lapozási hiba PIC módra

Azt mondják a PIC programozás olyan mint a biciklizés: Ha egyszer megtanulta az ember, akkor mindig tudni fogja.
Ennek ellenére most sikerült esnem egy szépet, pofára, ahogy kell. Mentségemre legyen mondva, két éve nyúltam utoljára PIC-hez, de akkor is ciki.
Épp egy soros mérés-adatgyűjtőt reszelek, ahol egy trigerre a PIC két ADjének az értékét, nyersen köpködi ki a soros portra. Ez ugye elég alap dolog, nulláról egy óra alatt megírható. Hogy csavar legyen benne kell mind a 10bites felbontás, csak mert egyszer él az ember.
A kód ahogy kell, AD beállítás, AD bekapcsolás, beállási várakozás, GO/-DONE bit ellenőrzés loop, AD felső 8 bitjének másolása regiszterbe, AD alsó 8 bitjének másolása regiszterbe, aztán az adat összetákolása stringé és pofozás kifelé szoftuart-al.
A kód lefordult, elindul, kiküldi a "hello world"-öt, aztán vár a triggerre. Pontosabban, semmit nem csinál.
Elkezdem debugolni a kódot, szépen kilövöm a blokkokat belőle ezzel sikerült leszűkíteni a hibát az AD-re. Arra gyanakodtam, hogy az AD initnél elütöttem valamit a IO beállításoknál, de ezt is sikerült kizárnom. Soronként beszúrok egy karakter küldés függvényt, hátha az AD áll be végtelen ciklusba GO/-DONE ellenőrzésnél. Nem, itt sincs hiba, viszont az AD felső 8 bit másolása után, megáll a kód mint a faék. Mi is történik? Lássuk mit is ír az adatlap példakódja?


   BANKSEL ADRESH ;
   MOVF ADRESH,W ;Read upper 2 bits
   MOVWF RESULTHI ;Store in GPR space
   BANKSEL ADRESL ;
   MOVF ADRESL,W ;Read lower 8 bits
   MOVWF RESULTLO ;Store in GPR space

A PIC faék egyszerűségű felépítésébe tettek egy kis csavart a tervezők, mert a különféle regisztereket két BANK-ba rendezték, melyben 020h-tól terjedő 96 byte és 0A0h-tól 32 byte SRAM terület található. Egyetlen probléma, hogy hiába definiálja az ember a kódja elején az általa használt regiszterek címeit, a kód futásakor csak akkor lehet műveletet végezni, ha a BANKSEL az adott regiszter BANK-jára mutat.
Esetemben a RESULTHI és RESULTLO-nak megfelelő regiszterek a BANK0-ban voltak, ahogy az összes többi is. Mivel az ADRESH BANK-ja is a BANK0 a kód tökéletesen futott a MOVWF RESULTLO sorig, aztán dobott egy hátast.
A javítás egy BANKSEL RESULTLO sor beszúrása volt a MOVWF RESULTLO elé. Csak épp kellett hozzá két és fél óra.
Ilyenkor visszasírom az egy címtérrel rendelkező processzorokat...

Hozzászólások

A példakód ettől még akár jó is lehet, ha feltételezzük, hogy RESULTHI és RESULTLO azon a többnyire 16 byte-os címtartományon van, amely sohasem lapozódik el. Mondjuk erre az értékes területre nem teszünk olyan változót, amely máshol is lehet.

A cím megtévesztő, mert arra utal, mintha a PIC-nek lenne lapozási hibája, holott Te voltál figyelmetlen.

Egyébként én sohasem írok le makrót, úgy értem, a BANKSEL-t le nem írnám saját kódban! Vagy MOVLB, vagy a STATUS regiszter piszkálása, attól függően, milyen PIC-ről van szó. És hogy miért? Lássam, mi történik, az hány gépi ciklus. Van, ahol számít ez, mi több, van, ahol a számtalan elágazás minden ágán hajszál pontosan ugyanakkora futásidő kell legyen.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A példa jó, ha ugyanabban a BANK-ban van a RESULTLO megadva. Elég triviális programozási hiba ez, viszont benézve csupa móka és kacagás tud lenni. Főleg olyan architektúráknál, ahol a memória és a speciális regiszterek ugyanazt a címtartományt használják csak másik lapon.

Mivel nem időzítéskritikus az alkalmazás a makró nem ördögtől való.
--
"Maradt még 2 kB-om. Teszek bele egy TCP-IP stacket és egy bootlogót. "

Ezért használok c-t (CCS) pic programozásra, amikor meg fontos az időzítés, csak akkor nyúlok asm-hoz, de ha lehet, ott is beágyazva

// Happy debugging, suckers
#define true (rand() > 10)

Mostanság nem nagyon érdemes már szerintem 16F (és alatti) szériákkal foglalkozni, főleg, ha nem 10 millió darab készül az eszközből. A 24-es széria elég olcsó és van hozzá ingyenes C fordító is.

Illetve az MPLAB X nagyon szépen működik Linux alatt is. (Bár ha jól tudom a PK2-t már nem támogatja.)

Szegény ember vízzel főz. Egyfelől jobban szeretek assembly-ben programozni, mert mikrokontrolleren gyakran időkritikus a művelet, trükközni érdemes, hogy memóriában, futásidőben hatékony legyen a kód, itt nincsenek megabyte-os memória allokációk. Másfelől nekem szempont, hogy a PICkit2-met tudjam használni, a fejlesztést Linuxon el tudjam végezni.

Aztán a bitekkel, regiszterekkel való bíbelődésre nekem kézenfekvőbb, olvasmányosabb, érthetőbb az assembly kód, mint a C, még akkor is, ha ez első olvasatra meredeknek tűnik.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Erre már inkább processzor kell. Magam részéről munkához is, hobbiként is olyan dolgokat csináltam PIC-kel, amely feladatok valóban hardware közeliek, vezérlés jellegűek, s nem kellett előbb sok tíz, sok száz oldalnyi RFC-t olvasni.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Hosszú távon szerintem át kell állni ARM-re és C-re. Elképesztő, hogy ugyan azon az áron mennyivel erősebb hardvert kapsz (Cortex M0/M3/M4). Csak az a szívás, hogy ahány gyártó, annyiszor kell újra tanulni a perifériák használatát, meg a datasheetek szokásait. Ennyiből jó pl az Atmel, ők elég "seamless" átállást kínálnak, de nekik meg elég drága a hardverük.