CodeBlanks Logo Icon CodeBlanks

Bellek eşlemeli I/O

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

main.cpp
#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

main.cpp
#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

Soru
volatile std::uint32_t* ____ = reinterpret_cast<volatile std::uint32_t*>(0x40021000);
Cevap
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?

main.cpp
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

Uzman bölümündeki tüm dersler