Vai al contenuto
PLC Forum


Crossing Page Boundary -- Ensure Page Bits Are Set.


ziopolly

Messaggi consigliati

Rieccomi con i miei problemi da principiante.

A forza di scrivere ho superato i 2K della prima pagina di RAM ed ho qualche goto e call che mi rimandano nella seconda. Il risultato è il messaggio sopra riportato di MPLAB.

Ho "pasticciato" un po' con PCLATH senza risultati perché non ho ancora capito la/le soluzioni possibili.

Grazie per l'aiuto!

massimo

ps: scrivo in assembler ed assemblo con MPLAB v.7.00

Link al commento
Condividi su altri siti


Scusa ma non si capisce cosa stai facendo, S'intuisce che stai usando un PIC e lo programmi in asm.

Specifica almeno il tipo di PIC anche perchè dei tipi che conosco la RAM non è organizzata a pagine da 2K.

Link al commento
Condividi su altri siti

che brutta bestia l'ignoranza... mi sarò espresso sicuramente male. Chiedo scusa.

Mi riferivo alla Program Memory che è di 8K/14K (così riporta il data sheet)

Grazie ancora una volta Livio

Link al commento
Condividi su altri siti

Volevi dire ROM invece di RAM.

Per cambiare pagina usa l'istruzione pagesel label, per esempio:

pagesel start

goto start

pagesel print

call print.

Ciao.

Link al commento
Condividi su altri siti

Grazie Giacomo ma non mi è ancora chiaro:

nel programma originale ho una serie di istruzioni composte anche da GOTO e CALL che richiamano quanto scritto nella seconda pagina.

Es:

MAIN

bsf PIPPO

goto PLUTO (che si trova nella pag successiva)

PLUTO

clrf PAPERONE

goto MAIN (pagina 0)

che faccio?

Modificato: da ziopolly
Link al commento
Condividi su altri siti

Guarda che tutta la memoria, 8 k parole di 14 bit, può essere indirizzata direttamente dal program counter di 13bits.

Personalmente sono arrivato a scrivere un programma che occupava particamente tutta la memoria senza dover effettuare indirizamenti per pagina.

Infatti l'indirizzamento massimo è 1FFFh, ovvero 8191 che, guarda caso son proprio 13 bits del program counter.

Basta che tu metta le etichette giuste ed eseguire il jump all'etichetta se programmi in assembler.

In "C" si chiamano le funzioni punto e basta.

Non di ci nulla sul linguaggio, ma se è decente non ci dovrebbe essere necessità di cambio pagina.

Link al commento
Condividi su altri siti

" Basta che tu metta le etichette giuste ed eseguire il jump all'etichetta se programmi in assembler"

Cosa intendi per etichette giuste?

e cosa per jump all'etichetta?

il programma, prima di essere ampliato fino al superamento dei 2K ed alla conseguente comparsa del messaggio di MPLAB "Crossing page Boundary..." girava bene!

Link al commento
Condividi su altri siti

Dovresti prima spiegare con che razza di compilatore stai lavorando.

Ho parecchi programmi che son vicini agli 8 kword di memoria e non hanno alcuna necessità di cambio pagina.

Gli unici eventuali problemi si possono avere sulla RAM dove ci sono 4 differenti banchi di memoria.

Link al commento
Condividi su altri siti

Non ho problemi con la selezione dei 4 banchi della RAM.

Il mio problema viene trattato sul data sheet del 16f917 in PCL and PCLATH ed in particolare nel paragrafo "Program Memory Paging dove viene riportato un es:

ORG 500H

BCF PCLATH,4

BSF PCLATH 3

CALL SUB

.

.

ORG 900H

SUB

.

.

.

RETURN

Link al commento
Condividi su altri siti

MPLAB non è un compilatore, ma un ambiente di sviluppo che può integrare alcuni compilatori e naturalmente lo ASM.

Le istruzioni dell'ultimo esempio sono in asm.

Le due "ORG" sono istruzioni che assegnano un indirizzo assoluto di partenza, significano Origin (origine)

BCF PCLATH,4 ----> azzera il bit 4 del buffer della parte alta del program counter

BSF PCLATH 3 ----> mette a 1 il bit 3 del buffer della parte alta del program counter

invece di tutto questo casino basta scrivere

ORG 500H

CALL SUB

.

.

ORG 900H

SUB

.

.

.

RETURN

Da pagina 210 in poi del manuale del 917 sono elenvate e spiegate le istruzioni assembler.

I processori a 14 bit gesticono direttamente i long jump e le long call mentre per i processori a 12 bits è necessario anteporre una L (LCALL e LGOTO) oppure preparare la situazione come segnato nell'esempio

Link al commento
Condividi su altri siti

Sì è vero! Assemblo con MPASM contenuto nel MPLAB... ma non pensavo fosse una precisazione importante. Chiedo nuovamente scusa per la mia pressapocaggine dovuta da una limitata cultura specifica e conseguente scarsa dimestichezza.

Il "casino" a cui ti riferisci è stato copiato da pagina 40 del data sheet 917 pubblicato da Microchip

Sono al corrente che le due ORG sono "DIRETTIVE" che indicano un indirizzo come ad esempio quello del Interrupt Vector 4h o 0h che coincide con lo Start Vector .

Quello che non capisco è:

1) cos'è il manuale del PICF917 (Perché se intendi il data sheet, non ho trovato quello che dici tu da pag 210 in poi)

Se per elenco istruzioni assembler intendi quelle pubblicate da pag242 a 249 del data sheet del micro in questione devo informarti che nonostante la mia ignoranza non è possibile scrivere un programmino funzionante di 2Kbits.

Pertanto il secondo punto che non capisco è:

2) perché mi informi della presenza dell'elenco sopra menzionato?

3) perché ORG 500H e non 100h o 0h?

Se questa parte di firmware è scritta sulla pag 0 e la capacità della pagina è di 2K perché ORG500H?

4) Stessa cosa per 900h: perché non 800h che corrisponde a 2.048 bites

Veniamo infine al mio problema iniziale che è in definitiva molto semplice:

Io ho dei GOTO E CALL che rimandano il programma oltre i primi 2K bits.

Cosa devo scrivere prima dei GOTO E CALL?

Cosa devo scrivere per ritornare alla Pag 0?

Se qualche anima gentile mi risponde semplicemente e senza salire in cattedra lo ringrazio anticipatamente

Grazie anche a te Livio per l'impegno, ma probabilmente il tuo livello è troppo elevato per me e il tuo aiuto non mi è servito a niente.

Massimo

Link al commento
Condividi su altri siti

La pseudo istruzione pagesel calcola la pagina dell'indirizzo fornito nella label ed imposta di conseguenza il registro PCLATH invece di doverlo fare a mano.

L'esempio che hai scritto tu va bene solo non capisco a cosa serve clrf PAPERONE a meno che non sia una istruzione messa a caso.

Ciao.

Link al commento
Condividi su altri siti

Si Giacomo! Paperone era lì per fare compagnia a pluto e pippo.

Peccato che PAGSEL xxx mi renda la call irriconoscibile dal compilatore: mi dà errore per ILLEGAL OPCODE

Preciso che senza PAGSEL non ho errori

Link al commento
Condividi su altri siti

Se per elenco istruzioni assembler intendi quelle pubblicate da pag242 a 249

Il numero di pagina dipende dalla revisione del manuale. Comunque le istruzioni son quelle e li è spegato charamente come funzionano

Le istruzioni GOTO e CALL non necessitano di selezione di pagina perchè caricano l'indirizzo di 13 bits nel Program counter.

Ci sono 2 modi per dare l'indirizzo :

  1. Scrivi l'indirizzo assoluto di dove è allocata la sub o dove deve essere esguito ils alto.
  2. Metti delle label, non dai nessun indirizzo assoluto, e poi ci pensa il linker a mettere gli indirizzi effettivi.
Il "casino" a cui ti riferisci è stato copiato da pagina 40 del data sheet 917 pubblicato da Microchip

Certo ma è un esempio avulso dal suo contesto, usato solo per mostrare la funzione di un registro speciale.

3) perché ORG 500H e non 100h o 0h?

Se questa parte di firmware è scritta sulla pag 0 e la capacità della pagina è di 2K perché ORG500H?

Perchè sono gli indirizzi del tuo esempio. Puoi usare qualsiasi indirizzo compreso tra 0000h e 1FFFh

Peccato che PAGSEL xxx mi renda la call irriconoscibile dal compilatore: mi dà errore per ILLEGAL OPCODE

Preciso che senza PAGSEL non ho errori

Cosa devo scrivere prima dei GOTO E CALL?

Cosa devo scrivere per ritornare alla Pag 0?

Niente!

Se devi tornare da una subroutine basta usare l'istruzione RETURN e il programma torna esattamente all'istruzione che segue la chiamata a subroutine. L'istruzione CALL è universale e funziona sempre nel medesimo modo: mette in un registro l'indirizzo di ritorno, che è quello che segue l'istruzione di call, poi esegue un salto all'indirizzo specificato. Qunado il programma incontrerà l'istruzione RETURN (o ret secondo il tipo di mnemonico) esegirà un salto all'indirizzo contenuto nel registro specifico per i ritorni. Nei micro di questo tipo c'è un apposito registro, in altri micro si usa lo stack.

Se invece ti muovi con un GOTO basta mettere un'etichetta (Label) al punto in cui vuoi saltare e ci pensa l'assemblatore ed il linker. Se invece vuoi complicarti la vita con gli indirizzi assoluti devi scrive l'indirizzo a cui vuoi saltare, non importa in quale pagina sia.

Se qualche anima gentile mi risponde semplicemente e senza salire in cattedra lo ringrazio anticipatamente

Non è salire in cattedra. Programamre non è cosa che si possa fare in modo approssimativo.

E' inutele che tu faccia l'offeso. Se le cose non le sai le devi imparare. E certe cose si possono spiegare solo in un modo: quello corretto.

Esistono solo 2 modi di programamre: il modo corretto ed il modo sbagliato.

Se si usa il modo sbagliato il programam non funziona.

E' tutto qui.

Prima di programmare un micro, spece se si usa un linguaggio a basso livello, è indispensabile conoscere bene come funziona lo Hw del micro stesso.

Peccato che PAGSEL xxx mi renda la call irriconoscibile dal compilatore: mi dà errore per ILLEGAL OPCODE

Preciso che senza PAGSEL non ho errori

Questo dovrebbe farti capire che non puoi fare quello che stai facendo. :smile:

Modificato: da Livio Orsini
Link al commento
Condividi su altri siti

vorrei replicare... ma cadrei nella polemica.

Desidero però informare che la soluzione al mio problema è stata risolta dal Maestro Livio che io ringrazio.

Grazie anche a te Giacomo56

Ma l'insegnamento + importante che ho ricevuto in questa discussione è che LA FORMA E' IMPORTANTE QUANTO IL CONTENUTO

ciao a tutti

massimo

ps: sono curioso di sapere quanti di voi ha capito qual è la soluzione :whistling:

Link al commento
Condividi su altri siti

PAGSEL non esiste è PAGESEL. C'è scritto tutto sul manuale di MPASM.

Le istruzioni goto e call contengono solo 11 bit dell'indirizzo quindi se il salto è in un'altra pagina bisogna prima impostare i valori corretti dei bit 3 e 4 del registro PCLATH e questo lo si fa comodamente con PAGESEL.

Per il ritorno da una call invece non bisogna fare niente come dice Livio.

Ciao.

Modificato: da giacomo56
Link al commento
Condividi su altri siti

Le istruzioni goto e call contengono solo 11 bit

Si possono usare le istruzioni LCALL e LGOTO (long call e log jump) che scrivono diretta mente tutti i 13 bit di indirizzo.

Questo non l'ho scritto subito, ma c'è anche nello short form delle istruzioni asm.

Sitratta delle "12-bit / 14-bit Core Special Instruction" Sono 28 istruzioni che condensano in unico mnemonico 2 o 3 istruzioni base ;)

Modificato: da Livio Orsini
Link al commento
Condividi su altri siti

Oramai son quasi 30 anni che non programmo più in asm, se non per piccole funzioni particolari che richiedono una minimizzazione di codice, però in genere mi riguardo il listato "C" con l'espansione in asm, quindi un po' d'occhio mi è rimasto. ;)

Le CALL e GOTO con limitazione di pagina le han lasciate per poter mantenere la compatibilità con i micro più vecchi.

Link al commento
Condividi su altri siti

Ho avuto modo di testare con calma i 4 sistemi di gestione da me conosciuti grazie a Microchip Data Sheet - Giacomo56 e Livio.

Posso con tutta tranquillità affermare che 3 delle 4 soluzioni funzionano su PIC16F917:

A) soluzione proposta da Microchip -> org 0h ;pag 0

BCF PCLATH,4

BSF PCLATH,3

CALL SUB

org 800h ;pag 1

SUB

NOP

RETURN

soluzione proposta da Giacomo56 -> org 0h

PAGESEL SUB

CALL SUB

org 800h

SUB

NOP

RETURN

C) soluzione di Livio -> org 0h

LCALL SUB

org 800h

SUB

NOP

RETURN

Ovviamente, nel caso di GOTO anziché CALL si dovrà anteporre PAGESEL o "L" al GOTO per ritornare a pag 0

L'unico sistema che non funziona è NON FARE NIENTE e non curarsi dell messaggio di MPASM: Crossing page boundary - ensure page bits are set

Perché ci sono MOLTI modi di programmare, molti modi per raggiungere l'obiettivo

massimo

Link al commento
Condividi su altri siti

Perché ci sono MOLTI modi di programmare,...

No purtroppo, come ti ho scritto prima, c'è solo un modo di programmare: quello corretto.

Tutti gli altri sono sbagliati, anche se il programma sembra girare.

Un programma corretto è ridotto ai minimi termini, è modulare, ed è logico nel suo sviluppo.

Gli indirizzamenti assoluti si usavano 50 anni fa quando non c'era altro modo.

Appena è diventato di uso comune il progamma locatore (linl - locator) si è passati all'uso degli indirizzi simbolici, lasciando che il link-locator allochi i moduli in modo ottimizzato. Oltre a tutto si evita il pericolo di overlappingi di memeoria in caso di aggiunte o modifiche.

soluzione proposta da Microchip ->

No questa non è la soluzione che propone microchip, questo è solo un esempio di uso del registro PCLATH.

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...