Baca Tulis Memory

Tulisan ini berawal dari pertanyaan seorang junior beberapa waktu yang lalu. Bagaimana cara mengakses sebuah alamat yang diketahui secara langsung. Awal pertanyaan ini adalah dari keinginan adik kelas tersebut untuk menggunakan PORTB di sistem AVR 16 bit-nya sebagai argumen dari sebuah fungsi.

Pada dasarnya, pengaksesan pada memori dapat dilakukan dengan deklarasi pointer ke alamat tersebut. Pada kasus di atas, PORTB di AVR 16 bit memiliki alamat 0x38, maka deklarasi pointer yang akan kita gunakan adalah sebagai berikut.

char * address = 0x38;

Kode di atas secara langsung menunjuk alamat 0x38 dapat diakses lewat pointer *address. Operasi selanjutnya sangat mudah. Misalkan kita ingin menuliskan sebuah nilai (8 bit) ke alamat 0x38, kita tinggal gunakan sintaks berikut:

*address = val; // val adalah nilai 8 bit

Untuk membaca nilai yang berada di alamat tersebut:

ret = *address;

Catatan: DDR harus diset dengan tepat untuk menggunakan PORT sebagai input/output.

Kemudian pertanyaan berlanjut, bagaimana cara menggunakan PORT sebagai argumen sebuah fungsi? Jawabannya sederhana, PORT di sini adalah sebuah pointer dengan alamat yang pasti yang didefiniskan pada file <avr/io.h>, kurang lebih sama dengan deklarasi pointer *address di atas.

Maka, tugas kita adalah membuat sebuah fungsi dengan argumen pointer to char yang nantinya akan kita gunakan.

void manipulasi_port(volatile uint8_t *port);

Dengan kode lebih lengkap:

void manipulasi_port(volatile uint8_t *port, int bit_to_set)
{
    *port |= (1 << bit_to_set); /* set bit */
}

int main(void)
{
    manipulasi_port(&PORTB, 4); /* kita akan set bit ke-4 */
    return 0;
}

Catatan: Penulis pernah melakukan eksperimen sederhana berikut yang hendaknya tidak ditiru karena tidak akan pernah berhasil, meskipun secara teori dan penjelasan di atas adalah mungkin.

Seperti kita tahu, permainan pointer sebagai berikut:

int *a;
int b = 8;

a = &b;      /* dereference a ke b */
*a = 1000;   /* isi b dengan 1000 */

Secara teori, operasi dereferencing pointer adalah mengarahkan sebuah pointer ke alamat tertentu (menggunakan notasi `&’ – ampresand). Pada kode di atas, alamat yang ditunjuk oleh *a adalah sama dengan alamat b. Seharusnya dengan sedikit hack untuk memperoleh alamat b saat runtime (sangat tergantung runtime itu sendiri, akan tetapi akan persistent dalam sistem modern – Mac OSX, GNU/Linux), kita _seharusnya_ dapat menggunakan alamat `b’.

Mari perhatikan kode berikut:

printf("%x", &b); /*  0x5fbffa70 */

Secara teori, kita dapat membaca/tulis alamat tersebut dengan metode yang sama pada kasus AVR di atas.

*(uint32_t * const) (0x5fbffa70) = 1000;

Anda penasaran dengan hasilnya? Silahkan coba😉

HINT: Virtual memory, user space, kernel space, protected

Pos ini dipublikasikan di Embedded dan tag , , , , , . Tandai permalink.

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s