Come funziona l'indirizzamento degli I / O mappati in memoria?


29

Come funziona l'indirizzamento degli I / O mappati in memoria?

Sto cercando di capire un esempio di I2S fornito : qualcuno l'ha fatto funzionare? .

Configurazione degli orologi:

#define BCM2708_PERI_BASE        0x20000000
#define CLOCK_BASE               (BCM2708_PERI_BASE + 0x101000) /* Clocks */

Prima mappa il codice in questo modo ...

clk_map = (unsigned char *)mmap(
      (caddr_t)clk_mem,
      MAP_BLOCK_SIZE,
      PROT_READ|PROT_WRITE,
      MAP_SHARED|MAP_FIXED,
      mem_fd,
      CLOCK_BASE
   );

Quindi fa qualcosa ...

 // Always use volatile pointer!
   clk = (volatile unsigned *)clk_map;

E quando si fa riferimento ci sono queste strane aggiunte di 0x26 e 0x27, di cosa si tratta?

 printf("Disabling I2S clock\n");
 *(clk+0x26) = 0x5A000000;
 *(clk+0x27) = 0x5A000000;

 usleep(10);

 printf("Confiure I2S clock\n");
 *(clk+0x26) = 0x5A000001;
 *(clk+0x27) = 0x5A000000 | 3<<12 | 1<<9; // divider: 3.125==0b11.001

 usleep(10);
 printf("Enabling I2S clock\n");
 *(clk+0x26) = 0x5A000011;

Guardando il foglio dati, posso vedere dove hanno alcuni di questi valori, come l'indirizzo di base, ma faccio fatica a capire gli altri. Dove viene CLOCK_BASEdeterminato e cosa sta succedendo?


1
Questo è probabilmente il più adatto per StackOverflow. Anche se si riferisce all'RPi, avrai maggiori probabilità di ottenere risposte alle domande di programmazione lì.
Jivings,

4
Forse, ma ritengo sia una domanda più generale relativa alla programmazione Pi che combina l'interpretazione del foglio dati e dell'hardware Pi. vediamo se ottiene qualche buona informazione.
Orecchie da cane,

Va bene. Vediamo come va :)
Jivings,

1
Non penso che questo farebbe troppo bene su Stack Overflow - è piuttosto specialistico e probabilmente otterrebbe maggiore attenzione da parte degli esperti qui.
Flexo,

Risposte:


18

Su un computer scrivi a un 'indirizzo di memoria' specificato. Questo indirizzo è riconosciuto dal sistema come indirizzo hardware e l'hardware appropriato riceve o invia il valore appropriato.

La maggior parte dei sistemi hardware ha molti registri diversi che possono essere impostati o letti. Alcuni potrebbero averne alcuni, altri potrebbero averne molti. Questi registri saranno raggruppati in un intervallo continuo. Un puntatore di base punta al primo nell'intervallo e si scrive, ad esempio, alla seconda porta con base_pointer + 1. Non è necessario, potresti scrivere direttamente su un puntatore, ma l'uso di un offset semplifica il lavoro.

Raspberry Pi riconosce una vasta gamma di registri hardware all'indirizzo 0x20000000. È possibile accedere a una gamma di registri che controllano i sistemi di clock da BCM2708_PERI_BASE + 0x101000. I registri che controllano l'orologio I2S sono il 38 ° e il 39 ° registro in quel blocco, scritti usando BCM2708_PERI_BASE + 0x101000 + 0x26 e 0x27

Non puoi semplicemente cambiare i valori dell'orologio, devi disabilitare l'orologio, cambiare i valori e riavviarlo.

Se questa risposta è troppo semplice, mi scuso. Nel qual caso la tua domanda è davvero hardcore, buona fortuna. Questo link potrebbe essere utile

Aggiornamento: Perché usare mmap e non scrivere direttamente in memoria?

Quando un programma sta eseguendo gli indirizzi di memoria pensa che non abbia indirizzi reali, essi sono mappati su indirizzi reali dal gestore della memoria. Ciò impedisce a un programma di essere in grado di influenzarne un altro. Due processi possono leggere e scrivere al proprio indirizzo 1234 in modo perfettamente felice, e il gestore della memoria manterrà le due posizioni completamente separate.

Le porte hardware, tuttavia, si trovano su indirizzi fisici assoluti. Ma non puoi scrivere direttamente a loro perché il gestore della memoria prenderà il tuo indirizzo e lo mapperà sulla tua area di memoria personale.

Su Linux / dev / mem è un ' file dispositivo dispositivo che è un'immagine della memoria principale del computer '

Se lo apri come un file, puoi leggerlo e scriverlo come un file. Nell'esempio fornito mem_fd è un handle di file risultante dall'apertura di / dev / mem

Un altro sistema che può rendere la vita molto più semplice è la possibilità di mappare un file in memoria e scriverlo come memoria. Pertanto, se si dispone di un file in cui si desidera leggere o scrivere diversi bit specifici, anziché spostare il puntatore del file avanti e indietro, è possibile mapparlo su una posizione in memoria e quindi scriverlo direttamente come se fosse memoria.

Quindi in questo esempio il codice crea un handle per la memoria fisica, come se fosse un file su disco, e quindi chiede al sistema di trattarlo come se fosse memoria. Un po 'contorto, ma necessario per aggirare il gestore della memoria virtuale e scrivere su un vero indirizzo fisico. Il valore 0x20000000, a quanto pare, è un po 'un'aringa rossa. Il codice propone questo indirizzo come suggerimento, il sistema non deve mappare / dev / mem qui, anche se probabilmente lo fa. Normalmente il valore null verrebbe passato e il sistema mapperebbe l'handle del file su qualunque indirizzo ritenesse migliore.

Ora la memoria fisica è mappata sulla memoria virtuale dei processi e le letture e le scritture vanno dove previsto.

Riferimenti:

http://www.kernel.org/doc/man-pages/online/pages/man2/mmap.2.html

http://www.raspberrypi.org/phpBB3/viewtopic.php?f=44&t=8496&p=104359

https://superuser.com/questions/71389/what-is-dev-mem


Ho ancora un paio di domande: perché hanno mmap? Perché non semplicemente accedere direttamente alla memoria?
Alex Chamberlain,

@AlexChamberlain Perché il codice viene eseguito su Linux, quindi non è possibile accedere direttamente alla memoria poiché ogni processo ottiene il proprio spazio di memoria virtuale. Tuttavia si può aprire e mmap / dev / mem per ottenere l'accesso diretto alla memoria fisica
nn

1

@AlexChamberlain questo è dovuto alla struttura del sistema operativo. Puoi andare senza mmapma il paging è dichiarato, quindi nessun accesso diretto. In modalità kernel puoi andare senza mmap, ad esempio, inserire il tuo driver come modulo kernel senza necessità mmap. Inoltre, nel caso del sistema operativo più semplice, in cui non viene utilizzata la memoria della tabella delle pagine, è possibile accedervi senza mmap, per esempio. accesso diretto all'indirizzo fisico.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.