Comprensione dell'indirizzo fisico

3

Sto leggendo questo articolo, Programmazione a basso livello del Raspberry Pi in C , che spiega come accedere al raspberry pi su un livello basso.

Dichiara che l'indirizzo gpio virtuale è 0x7E200000.

Quindi una macro è definita in questo modo

#define BCM2708_PERI_BASE       0x20000000
#define GPIO_BASE               (BCM2708_PERI_BASE + 0x200000)

Come faccio a calcolare l'offset tra la base periferica e la base gpio?

Quindi come si calcola quel 0x20000000 + 0x20000000 = 0x7E200000

Questa è semplicemente un'aritmetica binaria?

    
posta xhallix 26.09.2016 - 23:34
fonte

2 risposte

4

Quale programmazione a basso livello del Raspberry Pi in C dice in realtà è:

So the BCM2708_PERI_BASE macro contains the physical adress value at which the peripheral registers start. This is the adress we will need to use in our program. The virtual address value is 0x7E000000, and it are these virtual adresses that will be found in the datasheet.

There are a lot of different peripherals available on the BCM2835 (Timers, USB, GPIO, I2C, ...), and they will be defined by an offset to this virtual adress! For example, if we are interested in the GPIO peripheral (like in the example code above), we can find in the manual at page 90 that the virtual address is 0x7E200000. This means that the offset to the physical adress will be 0x200000 which explains the GPIO_BASE.

Questo non dice

0x2000 0000 + 0x2000 0000 = 0x7E20 0000

Dice

0x7E00 0000 + 0x0020 0000 = 0x7E20 0000

Dicono solo male, perché esprime

0x00200000 come
0x200000

Qual è lo stesso numero, ma è davvero difficile da vedere perché agli umani non piace contare gli zeri non raggruppati. Sei vittima di un HEX presentato male.

Ho passato un sacco di tempo a trafficare. Ho inviato di nuovo le specifiche per essere riscritto su problemi come questo. Anche quando lavori a un livello basso è importante tenere a mente gli umani.

È per questo che vorrei davvero che tu l'avessi detto in questo modo:

0x7E00 0000 + 
0x0020 0000 
===========
0x7E20 0000

Perché questa roba è importante per avere ragione. In certi negozi lo spazio bianco può letteralmente salvare vite. Non renderlo più difficile di quello che deve essere.

Per quanto riguarda la macro, tieni presente come funziona la mappatura virtuale. In un contesto esiste l'offset, in un altro no. Almeno sembra che non sia così. È lo stesso con l'indicizzazione degli array. someArray[0] esiste dove mai someArray esiste. Quindi someArray [2] non esiste a 2. È dove mai + 2. L'indirizzo virtuale ha un dove mai indirizzo di 0x7E00 0000 .

Guarda dove hai trovato questa macro

#define BCM2708_PERI_BASE       0x20000000
#define GPIO_BASE               (BCM2708_PERI_BASE + 0x200000)

Noterai che il numero 0x7E00 0000 non appare nella macro o persino in nessuno dei codici di questo articolo. Questo perché ottieni quell'offset gratis. Questi programmi stanno affrontando oltre questo offset. Proprio come quando dico someArray[2] non devo sapere dove esiste someArray .

Quindi mi aspetto che alla fine della giornata il GPIO_BASE punti qui:

0x7E00 0000 + 
0x2000 0000 + 
0x0020 0000 
===========
0x9E20 0000

E che il suo valore all'interno del programma dovrebbe essere:

0x2000 0000 +
0x0020 0000 
===========
0x2020 0000

Poiché ottieni 0x7E00 0000 dalla mappatura virtuale della memoria del programma non ti serve nel programma. Questa è una delle cose belle dell'essere virtuali.

    
risposta data 27.09.2016 - 05:50
fonte
2

Physical addresses range from 0x20000000 to 0x20FFFFFF for peripherals. The bus addresses for peripherals are set up to map onto the peripheral bus address range starting at 0x7E000000. Thus a peripheral advertised here at bus address 0x7Ennnnnn is available at physical address 0x20nnnnnn.

     

Quindi la macro BCM2708_PERI_BASE contiene il valore dell'indirizzo fisico al quale iniziano i registri delle periferiche. Questo è l'indirizzo che dovremo usare nel nostro programma. Il valore dell'indirizzo virtuale è 0x7E000000, e sono questi indirizzi virtuali che verranno trovati nel foglio dati.

È solo questione che alcune pubblicazioni popolari stiano utilizzando uno standard di configurazione della scheda e il Pi ne sta usando un'altra. Quindi, esiste una mappatura ben definita tra gli indirizzi Pi di 0x20nnnnnn e quella altra configurazione di scheda nota che utilizza 0x7Ennnnnn per lo stesso intervallo I / O.

Non c'è aritmetica che trasformi 0x20nnnnnnn in 0x7Ennnnnn (ovvero, senza conoscere la mappatura, che ti dà quella costante magica, cioè 0x7E000000 - 0x20000000 == 0x5E000000).

Ci sono molte ragioni per cui una scheda può usare intervalli diversi per qualcosa di simile, come avere un minor numero di linee di indirizzo complesse cablate dal processore, in quanto ciò risparmia denaro e potere sulla scheda, anche se al costo di una memoria meno accessibile. .

    
risposta data 27.09.2016 - 05:37
fonte

Leggi altre domande sui tag