I files .HEX nei PIC
Il file .hex viene generato dall' assembler in funzione della lista
sorgente.
- Il suo contenuto è la sequenza di codici che saranno scritti
nella memoria programma e che il processore dovrà
eseguire.
- Questi sono scritti come valori esadecimali in modo
da poter essere passati ad un dispositivo di programmazione per la loro
scrittura nel chip.
- Il file è un semplice formato testo ASCII per rendere facilmente portabile il file
stesso.
-
Il testo è formattato secondo uno standard stabilito, il che consente di usarlo su
dispositivi di programmazione di diversi produttori.
In effetti non esiste un solo standard (e ci mancherebbe che ci si decida a
fare qualcosa di standard...), ma diversi "standard" studiati da vari
produttori: in particolare per i PIC si usano correntemente gli
"standard" della Intel, ovvero dei file con estensione hex.
Formato standard |
Menmonico |
Estensione file |
Impiego |
Intel Hex Format |
INHX8M |
.hex |
dispositivi a 8 bit |
Intel Hex 32 Format |
INHX32 |
.hex |
dispositivi a16 bit |
Intel Split Hex Format |
INHX8S |
.hxl, .hxh |
altri |
Quello utilizzato principalmente è l' Intel Hex Format, con estensione .hex, anche se
teoricamente è possibile usare altri "standard".
Anzi, gli assemblatori o i compilatori spesso hanno la possibilità di
scegliere diversi formati, per potersi adattare a diversi sistemi di
programmazione.
Cosa c'è dentro un file .HEX
Andando a leggere con un qualsiasi editor questo file .hex (è un file di testo), si troverà un pacchetto di
caratteri del genere :
:020000040000FA
:0400000000000828CC
:0400080000000900EB
:1000100083018B018C0186018316BF308100003083
:0600200086008312861524
:02400E00B93FB8
:00000001FF
in cui ogni riga è del tipo :
:LLAAAATTDDDD...
.DDCC
i cui elementi sono
- : un due punti (o column in inglese) iniziale
- LL due cifre esadecimali che rappresentano il numero di byte
presenti nella riga. Il massimo di dati in una riga è 16, quindi il valore
massimo applicabile a questi due byte è 10H
- AAAA quattro cifre hex che indicano la posizione di inizio in cui
scrivere i byte.
Poichè una istruzione è lunga due byte.In effetti si
tratta, per i PIC 16F, di 14 bit, per cui i primi due bit più significativi
saranno sempre 0. L' indirizzo di programmazione in memoria
è shiftato a sinistra di uno. Quindi per indicare l' indirizzo 0004h si
troverà scritto 0008h.
- TT due cifre che indicano il tipo di
record :
00 - data record
01 - end-of-file record
02 - extended segment address record (non usato per il PIC)
03 - start segment address record (non usato per il PIC)
04 - extended linear address records (non usato per il PIC)
05 - Start linear address record (non usato per il PIC)
Quindi nella prima riga e nelle seguenti conterranno 00, mentre nell' ultima 01.
Gli altri valori sono stati inseriti da Intel in relazione alle CPU a 16, 32
e 64 bit ed ovviamente non sono usati nei PIC a 8 bit.
- DD: due cifre hex che contengono il valore dei byte nella forma byte basso/ byte alto (gli
opcode PIC sono da due bytes); come detto prima si può arrivare ad
un massimo di 16 dati su una sola riga
- CC: due cifre hex del checksum della riga (complemento a due della
somma di tutti i bytes precedenti della stessa riga). Serve al dispositivo
di programmazione per verificare la correttezza dei dati ricevuti.
L' ultima riga è l' end-of-file record, tipicamente con questa forma :
:00000001FF
dove :
- 00 è il numero dei dati nella riga, che, essendo la chiusura,
non ne contiene
- 0000 è il valore attribuito all' indirizzo, che, in questa riga,
non ha significato.
- 01 è il valore che indica che la riga è l' end-of-record
- FF è il checksum calcolato (qui deriva da 01h + NOT(00h + 00h + 00h
+ 01h) che fa FFh).
Per le altre righe vediamo qualche esempio. Nel listato qui sopra la seconda
riga contiene :
:0400000000000828CC
indica che ci sono
04 byte che saranno scritti a partire da
0000. Il valore
di questo indirizzo è specificato da uno statement (ORG
00H) nella lista
sorgente visibile più avanti.
La sequenza degli opcode è : 00000828
e il checksum è
CC (esadecimale).
La riga successiva :
:0400080000000900EB
indica che ci sono 04 byte che saranno scritti a partire da
0004 (0008 è
0004 shiftato a sinistra di 1). Anche qui, l' indirizzo è specificato da uno
statement del sorgente (ORG 04H).
La sequenza degli opcode è : 00000900
e il checksum è EB (esadecimale).
Quindi, a partire dalla locazione 0000, la sequenza da inserire è
000002808, poi si passa a 0004 dove va inserita la sequenza
00000009 : abbiamo detto che i byte si trovano nella disposizione
basso/alto, ovvero in questo caso 00000828 00000900, e per
"interpretarli" li devo scambiare di posizione.
Per chi volesse fare del reverse engeneering:
locazione opcode
mnemonico
PIC
0000
0000 nop
0001
2808 goto 08h
0004
0000 nop
0005
0009 retfie
e così via. Ed in effetti l' hex in esempio è derivato dall' assemblaggio del seguente
sorgente :
;*************************************************
; Prova
; (c) 2005, AF
; rev. 1.0 23-02-2005
;*************************************************
PROCESSOR
16F876
INCLUDE
"P16F876.INC"
RADIX
DEC
__config _XT_OSC & _WDT_OFF &
_PWRTE_ON & _CP_OFF
&
_LVP_OFF & _BODEN_OFF
;***************************************************
;Reset Vector
ORG 00H
Reset nop
goto Main
;Interrupt vector
ORG 04H
ISR nop
retfie
;===================================================
ORG
08H
Main: ;Power_ON reset
clrf STATUS
;do initializaion (bank 0)
clrf INTCON
;disable all IRQ
clrf PIE1
clrf PORTB
bsf STATUS, RP0 ;
bank1
movlw b'10111111' ;
no RBPU
movwf OPTION_REG
movlw
0x00
movwf TRISB ; PB as out
bcf STATUS,RP0 ;
bank0
bsf PORTB,
3 ; PB 3 = 1
goto
$ ; locked loop
END
|
Da osservare che:
- la maggior parte del testo sono commenti (evidenziati in
verde), che non finiscono
in alcun modo nel file .hex;
- anche gli statement (PROCESSOR, INCLUDE,
RADIX, ORG, END) non finiscono direttamente nel file .hex, ma servono all' Assembler per
organizzare correttamente i codici in uscita.
Ad esempio, la penultima riga del file .hex contiene il record :
:02400E00B93FB8
Questa riga riporta il valore assegnato al Registro di
Configurazione del processore dallo statement __config e
dalla successiva lunga stringa di mnemonici, il cui corrispondente esadecimale compilato è il numero
3FB9h.
Il registro di configurazione
per il processore specificato dagli statement PROCESSOR e INCLUDE,
ovvero il 16F876, si
trova alla locazione 2007h (che,
scritto shiftato a sinistra di una posizione, diventa 400Eh).
Per chi non ci credesse :
2007h --> 0010 0000 0000 0111b
2 0 0 7 h
che, shiftato a sinistra di una posizione diventa :
0100 0000 0000 1110b
--> 400Eh
4 0 0 E h
Per curiosità, la linea __config
si trova
normalmente all' inizio del testo del sorgente, dopo la definizione del
processore, in quanto essa è stabilisce strettamente a come si
comporterà quel determinato processore, fissando alcune caratteristiche del
suo funzionamento hardware; nel file .hex, invece, finirà sul fondo perchè
l' indirizzo interno del registro del PIC in cui verranno scritti i 4 byte ha
un valore molto più alto di tutti gli altri registri accessibili. Quindi,
essendo la lista .hex organizzata grosso modo in ordine ascendente per quello
che riguarda gli indirizzi, il valore di __config finirà tipicamente nella
penultima riga.
Alcune note non secondarie
-
ll file .hex di Intel è accettato da tutti i
dispositivi di programmazione e quindi rende la scelta di questo indipendente
sia dal processore che dall'assembler usato.
Come informazione generale va detto che non tutti i dispositivi di
programmazione accettano tutti i possibili formati "standard"
per i file .hex.
Quindi, prima di procedere all' acquisto di un
programmatore o all' auto costruzione, verificate se il software di
gestione prevede il formato o i formati che intendete utilizzare.
-
Il file .hex di un PIC16 o di un PIC18 o
di un ARM o di un ST6 saranno esattamente uguali per quanto riguarda la STRUTTURA.
Ma completamente diversi per quanto riguarda il contenuto HEX dei codici
di istruzione.
Questo perchè lo standard Intel definisce COME debba essere
strutturato il file di scambio esadecimale, ma non COSA debba
contenere, il che dipende dalle caratteristiche del processore.
-
Quindi, Assembler per processori diversi produrranno file
.hex con le
caratteristiche generali qui spiegate, ma per ogni processore ci sarà una
diversa relazione opcode - valore del byte scritto.
Quindi, un .hex, pure scritto con la massima aderenza a questo standard, sarà
adeguato alla programmazione solo ed esclusivamente del dispositivo per cui è
stato compilato e non sarà utilizzabile in alcun modo per altri processori.
Al limite, un file .hex per un certo processore può essere usato per un
altro all' interno della stessa famiglia solo ed esclusivamente se le
risorse dei due processori sono identiche; se ci sono differenze anche
minime e la compilazione non ne tiene, programmare un chip con l' .hex
previsto per un' altro non darà alcun risultato utile.
Sul sito di Intel è possibile recuperare un
.pdf dal titolo "Hexadecimal
Object File Format Specification" che contiene tutte le informazioni a
riguardo del suo formato hex.
Per conoscenza, esistono anche editor specifici per il trattamento dei file
.hex
e programmi di conversione dal formato .hex al binario, reperibili in rete.
Esistono
anche dei disassembler, ovvero programmi per risalire dal file .hex
alla sequenza di opcode. Ovviamente un disassembler deve essere adatto ad uno
specifico processore, in quanto ogni processore ha la sua equivalenza tra
set di istruzioni e codici binari.
In particolare, i file .hex generati compilando sorgenti scritti con
linguaggi ad alto livello saranno particolarmente complessi e una loro
"decodifica" manuale diventa una impresa al di sopra delle
normali possibilità.
|
Queste informazioni riguardo al file .HEX
possono parere superflue, ma può capitare il caso in cui sia necessario
andare a vedere cosa sta scritto in una certa locazione e quindi ci si trova a
confrontarsi con il file .HEX. Per cui, meglio sapere come è fatto.
Dato che questo file è una lista di testo
ASCII, non occorre alcun editor particolare per vederlo o modificarlo.
Chiaramente si consigliano editor per programmazione, mentre word processor
non sono l' ideale, perchè tendono a dare formattazione ad un testo che deve
restare così come sta senza alcuna variazione indotta dal sistema di
consultazione (dato che sono la lista delle istruzioni che andrà inserita
nella memoria programma del processore).
Quindi, niente Word, Wordpad o simili. Meglio
Programmer's Notepad, Notepad++, TextEdit, Textpad, ecc.
ATTENZIONE:
Il file .HEX è una lista di testo che può essere modificata come
un qualsiasi testo.
MA NON E' un qualsiasi testo !
Quindi, anche la più piccola modifica manuale" a questo file
può essere fatta solamente a ragion veduta.
Altrimenti il file verrà rifiutato dal sistema di programmazione se i
checksum non sono corretti e, se fosse accettato, ma le istruzioni
modificate in modo arbitrario, il programma non funzionerebbe.
Quindi, potete editare il file .hex per visionarlo, ma se lo
modificate, fatelo su una copia, in modo da non danneggiare l'
originale che, in pratica, potrà essere prodotto correttamente o
modificato correttamente solo attraverso la compilazione del sorgente.
|
|