Bagaimana cara menangani I / O yang dipetakan pada memori?


29

Bagaimana cara menangani I / O yang dipetakan pada memori?

Saya mencoba memahami sampel yang disediakan I2S: Adakah yang menjalankannya? .

Mengkonfigurasi Jam:

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

Pertama-tama memetakan kode seperti ...

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

Maka ia melakukan sesuatu ...

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

Dan ketika direferensikan ada tambahan aneh 0x26 & 0x27, tentang apa itu?

 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;

Melihat lembar data, saya bisa melihat dari mana mereka mendapatkan beberapa nilai ini, seperti alamat dasar, tapi saya berjuang untuk memahami yang lain. Di mana itu CLOCK_BASEditentukan dan apa yang terjadi?


1
Ini mungkin paling cocok untuk StackOverflow. Meskipun ini berkaitan dengan RPi, Anda akan lebih mungkin mendapatkan jawaban untuk pertanyaan pemrograman di sana.
Jivings

4
Mungkin, tapi saya merasa ini lebih merupakan pertanyaan terkait pemrograman Pi umum yang menggabungkan interpretasi datasheet dan perangkat keras Pi. mari lihat apakah ada info bagus.
Telinga Anjing,

Baik. Mari kita lihat bagaimana kelanjutannya :)
Jivings

1
Saya tidak berpikir ini akan berhasil dengan baik pada Stack Overflow - ini cukup spesialis dan kemungkinan akan mendapatkan lebih banyak perhatian ahli di sini.
Flexo

Jawaban:


18

Di komputer Anda menulis ke 'alamat memori' yang ditentukan. Alamat ini diakui oleh sistem sebagai alamat perangkat keras, dan perangkat keras yang sesuai menerima atau mengirim nilai yang sesuai.

Sebagian besar sistem perangkat keras memiliki banyak register berbeda yang dapat diatur atau dibaca. Beberapa mungkin memiliki beberapa, beberapa mungkin memiliki banyak. Register ini akan dikelompokkan ke dalam rentang berkelanjutan. Pointer basis menunjuk ke yang pertama dalam rentang, dan Anda menulis ke, misalnya, port kedua dengan base_pointer +1. Anda tidak harus, Anda bisa menulis langsung ke sebuah pointer, tetapi menggunakan offset membuat segalanya lebih mudah untuk dikerjakan.

Raspberry Pi mengenali sejumlah besar register perangkat keras di alamat 0x20000000. Berbagai register yang mengontrol sistem jam diakses dari BCM2708_PERI_BASE + 0x101000. Register yang mengontrol jam I2S adalah register 38 dan 39 di blok itu, ditulis untuk menggunakan BCM2708_PERI_BASE + 0x101000 + 0x26 dan 0x27

Anda tidak bisa hanya mengubah nilai jam, Anda harus menonaktifkan jam, mengubah nilai, dan memulai kembali.

Jika jawaban ini terlalu mendasar, saya minta maaf. Dalam hal ini pertanyaan Anda benar-benar hardcore, semoga berhasil. Anda mungkin menemukan tautan ini bermanfaat

Pembaruan: Mengapa menggunakan mmap dan tidak menulis langsung ke memori?

Ketika sebuah program menjalankan alamat memori yang dianggapnya bukan alamat asli, mereka dipetakan ke alamat asli oleh manajer memori. Ini menghentikan satu program untuk dapat mempengaruhi yang lain. Dua proses dapat membaca dan menulis ke alamat mereka sendiri dengan sangat gembira, dan manajer memori akan memisahkan kedua lokasi.

Port perangkat keras, bagaimanapun, berada pada alamat fisik absolut. Tetapi Anda tidak dapat menulis kepada mereka secara langsung karena manajer memori akan mengambil alamat Anda dan memetakannya ke area memori pribadi Anda.

Di Linux / dev / mem adalah ' file perangkat karakter yang merupakan gambar dari memori utama komputer '

Jika Anda membuka ini seperti file maka Anda dapat membaca dan menulis seperti file. Dalam sampel yang disediakan, mem_fd adalah file handle yang dihasilkan dari opening / dev / mem

Sistem lain yang dapat membuat hidup lebih mudah adalah kemampuan untuk memetakan file ke memori dan menulis seperti memori. Jadi jika Anda memiliki file di mana Anda ingin membaca atau menulis bit spesifik yang berbeda daripada memindahkan pointer file ke belakang dan ke depan, Anda dapat memetakannya ke lokasi di memori, dan kemudian menulis ke sana secara langsung seolah-olah itu adalah memori.

Jadi dalam sampel ini kode membuat pegangan ke memori fisik, seolah-olah itu file pada disk, dan kemudian meminta sistem untuk memperlakukannya seolah-olah itu adalah memori. Agak berbelit-belit, tetapi perlu untuk berkeliling manajer memori virtual dan menulis ke alamat fisik yang sebenarnya. Nilai 0x20000000, tampaknya, agak merah. Kode ini mengusulkan alamat ini sebagai petunjuk, sistem tidak harus memetakan / dev / mem di sini, meskipun mungkin. Biasanya nilai nol akan diteruskan, dan sistem akan memetakan pegangan file ke alamat apa pun yang dianggapnya terbaik.

Sekarang memori fisik dipetakan ke proses memori virtual, dan membaca dan menulis pergi ke tempat yang Anda harapkan.

Referensi:

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


Saya masih punya beberapa pertanyaan: Mengapa mereka mmap? Mengapa tidak langsung mengakses memori saja?
Alex Chamberlain

@AlexChamberlain Karena kode ini berjalan di linux, jadi Anda tidak dapat mengakses memori secara langsung karena setiap proses mendapatkan ruang memori virtual mereka sendiri. Namun seseorang dapat membuka dan mmap / dev / mem untuk mendapatkan akses langsung ke memori fisik
nos

1

@AlexChamberlain ini karena struktur OS. Anda dapat pergi tanpa mmaptetapi halaman dinyatakan, karenanya tidak ada akses langsung. Dalam mode kernel Anda dapat pergi tanpa mmap, dengan, misalnya memasukkan driver Anda sebagai modul kernel tanpa perlu mmap. Juga, dalam kasus OS paling sederhana, di mana tidak ada memori tabel halaman digunakan, Anda dapat mengakses tanpa mmapsalah satunya, yaitu akses alamat fisik langsung.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.