Como funciona o endereçamento de E / S mapeado pela memória?


29

Como funciona o endereçamento de E / S mapeado pela memória?

Estou tentando entender um exemplo fornecido I2S: Alguém conseguiu rodar? .

Configurando relógios:

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

Primeiro mapeia o código da seguinte maneira ...

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

Então faz alguma coisa ...

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

E quando é referenciada, existem esses acréscimos ímpares de 0x26 e 0x27, o que é isso?

 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;

Olhando para a folha de dados, posso ver onde eles obtiveram alguns desses valores, como o endereço base, mas estou lutando para entender os outros. Onde isso é CLOCK_BASEdeterminado e o que está acontecendo?


1
Provavelmente, isso é mais adequado para o StackOverflow. Embora esteja relacionado ao RPi, é mais provável que você obtenha respostas para as perguntas de programação lá.
Jivings

4
Talvez, mas acho que é uma questão mais geral relacionada à programação Pi, combinando a interpretação da folha de dados e do hardware Pi. vamos ver se obtém alguma informação boa.
Dog Orelhas

OK. Vamos ver como ele vai :)
Jivings

1
Eu não acho que isso se sairia muito bem no Stack Overflow - é bem especialista e provavelmente chamaria mais atenção aqui.
Flexo

Respostas:


18

Em um computador, você grava em um 'endereço de memória' especificado. Este endereço é reconhecido pelo sistema como um endereço de hardware e o hardware apropriado recebe ou envia o valor apropriado.

A maioria dos sistemas de hardware possui muitos registros diferentes que podem ser configurados ou lidos. Alguns podem ter alguns, alguns podem ter muitos. Esses registros serão agrupados em uma faixa contínua. Um ponteiro base aponta para o primeiro no intervalo e você grava, por exemplo, a segunda porta com base_pointer + 1. Você não precisa, pode escrever diretamente para um ponteiro, mas usar um deslocamento facilita o trabalho das coisas.

O Raspberry Pi reconhece uma enorme variedade de registros de hardware no endereço 0x20000000. Uma variedade de registradores que controlam sistemas de relógio são acessados ​​a partir de BCM2708_PERI_BASE + 0x101000. Os registradores que controlam o relógio I2S são os registradores 38 e 39 desse bloco, gravados usando BCM2708_PERI_BASE + 0x101000 + 0x26 e 0x27

Você não pode simplesmente alterar os valores do relógio, porém, você deve desativar o relógio, alterar os valores e reiniciá-lo.

Se esta resposta é muito básica, minhas desculpas. Nesse caso, sua pergunta é realmente grave, boa sorte. Você pode achar este link útil

Atualização: Por que usar o mmap e não gravar diretamente na memória?

Quando um programa está executando os endereços de memória que acha que não são endereços reais, eles são mapeados para endereços reais pelo gerenciador de memória. Isso impede que um programa possa afetar outro. Dois processos podem ler e gravar em seu próprio endereço 1234 perfeitamente felizes, e o gerenciador de memória manterá os dois locais completamente separados.

As portas de hardware, no entanto, estão em endereços físicos absolutos. Mas você não pode escrever diretamente para eles, porque o gerenciador de memória pega seu endereço e o mapeia para sua área de memória pessoal.

No Linux / dev / mem, há um ' arquivo de dispositivo de caractere que é uma imagem da memória principal do computador '

Se você abrir isso como um arquivo, poderá ler e gravar nele como um arquivo. No exemplo fornecido, mem_fd é um identificador de arquivo resultante da abertura de / dev / mem

Outro sistema que pode facilitar muito a vida é a capacidade de mapear um arquivo na memória e gravá-lo como memória. Portanto, se você possui um arquivo no qual deseja ler ou gravar diferentes bits específicos, em vez de mover o ponteiro do arquivo para trás e para frente, é possível mapeá-lo para um local na memória e gravá-lo diretamente como se fosse memória.

Portanto, neste exemplo, o código está criando um identificador para a memória física, como se fosse um arquivo em disco, e depois pedindo ao sistema para tratá-lo como se fosse memória. Um pouco complicado, mas necessário para contornar o gerenciador de memória virtual e gravar em um endereço físico real. O valor 0x20000000, ao que parece, é um pouco de um arenque vermelho. O código está propondo esse endereço como uma dica, o sistema não precisa mapear / dev / mem aqui, embora provavelmente o faça. Normalmente, o valor nulo seria passado e o sistema mapearia o identificador do arquivo para qualquer endereço que considerasse melhor.

Agora a memória física é mapeada para a memória virtual dos processos, e as leituras e gravações vão para onde você espera.

Referências:

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


Ainda tenho algumas perguntas: Por que eles mmap? Por que não apenas acessar a memória diretamente?
Alex Chamberlain

@AlexChamberlain Como o código é executado no Linux, você não pode acessar a memória diretamente, pois cada processo obtém seu próprio espaço de memória virtual. No entanto, pode-se abrir e mmap / dev / mem para obter acesso direto à memória física

1

@AlexChamberlain, isso se deve à estrutura do sistema operacional. Você pode ficar sem, mmapmas a paginação é declarada, portanto, nenhum acesso direto. No modo kernel, você pode ficar sem mmap, por exemplo, inserir seu driver como módulo do kernel sem necessidade mmap. Além disso, no caso mais simples do sistema operacional, em que nenhuma memória da tabela de páginas é usada, você pode acessar sem mmap, por exemplo. acesso direto ao endereço físico.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.