Bellek eşlemeli I/O
- C++ kursu
- Uzman
- Ders 32/47
- 5 dk
Bellek eşlemeli I/O ve volatile kullanımını öğrenirsin.
Bellek eşlemeli I/O
Bellek eşlemeli I/O (MMIO), donanım kayıtcılarının bellek adreslerine eşlendiği tekniktir. Belirli bir adrese yazmak donanımı kontrol eder; aynı adresten okumak donanım durumunu verir. Örnek: 0x40021000 adresi bir GPIO kayıtcısı olabilir.
C++'ta bu adreslere volatile std::uint32_t* ile erişilir: volatile std::uint32_t* reg = reinterpret_cast<volatile std::uint32_t*>(0x40021000);. volatile derleyiciye bu erişimi eniyilememesini söyler. *reg = 0x1; ile yazılır, *reg ile okunur.
volatile neden gerekli
Derleyici eniyileyici (optimizer) bir değişkeni art arda okuyorsa bir kez okuyup değeri önbelleğe koyabilir. Ama donanım kayıtcısı her okumada farklı değer döndürebilir (örneğin durum bayrağı). Bu yüzden volatile her okumanın belleğe gitmesini sağlar.
Aynı şekilde art arda yazmalar da eniyileştirilebilir; son yazma kalır diye düşünür. Ama donanıma yapılan her yazma bir yan etkidir; atlamamak gerekir. volatile bu yazmaların da korunmasını sağlar. Bu yüzden MMIO'da volatile zorunludur.
Uygulama MMIO benzetmesi yaz
Global std::uint32_t storage = 0; tanımla. Sonra volatile std::uint32_t* reg = reinterpret_cast<volatile std::uint32_t*>(&storage); yaz. main içinde *reg = 0x1; ve std::cout << *reg; yaz.
Başlangıç kodu
#include <iostream>
#include <cstdint>
// storage değişkenini ve reg işaretçisini buraya tanımla
int main() {
// reg'e 0x1 yaz ve reg'i okuyup yazdır
return 0;
}Örnek çözüm
#include <iostream>
#include <cstdint>
std::uint32_t storage = 0;
volatile std::uint32_t* reg = reinterpret_cast<volatile std::uint32_t*>(&storage);
int main() {
*reg = 0x1;
std::cout << *reg;
return 0;
}Beklenen çıktı
1
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 volatile işaretçiyi tamamla
volatile std::uint32_t* ____ = reinterpret_cast<volatile std::uint32_t*>(0x40021000);
volatile std::uint32_t* reg = reinterpret_cast<volatile std::uint32_t*>(0x40021000);
Açıklama: reg, donanım kayıtçısına işaret eder.
2 volatile neyi engeller?
volatile std::uint32_t* reg = ...;
*reg = 0x1;
*reg = 0x2; // iki kez yazma- Sınıfların oluşumunu
- Bellek sızıntısını
- Çalışma zamanı hatasını
- Derleyicinin okuma/yazma eniyilemesini Doğru cevap
Açıklama: volatile, her okuma ve yazmanın belleğe gitmesini sağlar.
3 Parçayı rolüne eşle
| Kavram | Anlamı |
|---|---|
volatile |
Her erişim belleğe gider |
MMIO |
Donanım belleğe eşle |
reinterpret_cast |
Adresi işaretçiye çevir |
0x40021000 |
Donanım kayıt adresi |