1 Nisan 2020 Çarşamba

Fonksiyon Pointerları ve Soyutlama - Kısa Yazılar 1

Garip dönemlerden geçiyoruz ve yaşadığımız hadisenin çapını pek algılayabilmişiz gibi gelmiyor bana. Belki de ben kötümserimdir. Fakat henüz her şeyin başındaymışız gibi geliyor ve anladığım kadarıyla bir süre sonra bugünkilerden çok daha fazla boş zamanımız olacak gibi. Bende bu evdeki zamanları yeni yazılar yazarak değerlendirmek istedim.

Yazıya başlamadan önce belirtmen gereken bazı noktalar var. Bu yazıda bahsedilen terimleri ya da konseptleri çok iyi bildiğimi iddia etmiyorum. Yazı boyunca kullandığım bazı terminolojiler ya da bilgiler yanlış olabilir. Temel amacım ise diğer mühendis arkadaşlara ulaşabilmek ve sizlerin yanlışlarımı görmemi sağlamanız. Bu yüzden olumlu ya da olumsuz yorum yaparsanız sevinirim. Umarım karşılıklı bir fayda sağlamış oluruz.

Bugün fonksiyon pointerları ve soyutlamadan bahsetmek istiyorum. Benim soyutlamadan anladığım donanım ile yazılımın birbirinden soyutlanması. Yazı boyunca çok basit bir problemden yola çıkarak bu soyutlama işleminin nasıl yapılabileceğini göstermeye çalışacağım.

Örneğin, elimizde bir sıcaklık sensörü bulunuyor ve bu sensör ile I2C üzerinden haberleşiyoruz. Amacımız ise bu sıcaklık sensörü kodlarını, ya da kütüphanesini diyebiliriz, donanımdan soyutlamak. Yani yazdığımız tek bir sıcaklık sensörü kütüphanesi ile istediğimiz herhangi bir işlemci ile hiçbir ekstra düzenleme yapmadan kullanabilmek.

İşte tam bu noktada fonksiyon pointerları hayatımıza girmeye başlıyor ve aşağıdaki şekilde tanımlıyoruz. 

typedef uint32_t (*comm_fptr_t)(uint8_t slave_address, uint8_t *p_data, uint32_t length);
typedef void (*delay_fptr_t)(uint32_t ms);


Daha sonra ise fonksiyon pointerların ve gerekli diğer değişkenlerin olduğu bir structure oluşturuyoruz.

typedef struct shtc3_dev_s {
    /*! Device Id */
    uint8_t dev_id;
    /*! Bus read function pointer */
    comm_fptr_t i2c_read;
    /*! Bus write function pointer */
    comm_fptr_t i2c_write;
    /*! delay function pointer */
    delay_fptr_t delay_us;
} shtc3_dev_t;


Son olarak ise bir initialization fonksiyonu ile tanımlanmalarımızı bitiriyoruz. Artık “_shtc3_dev” yapısını “_shtc3_dev.i2c_write(…)” yapısı ile istediğimiz yerde kullanabiliriz.

shtc3_dev_t _shtc3_dev;
void SHTC3_Init(shtc3_dev_t shtc3_dev){
  _shtc3_dev = shtc3_dev;
}

Main fonksiyonu içerisinde ise “SHTC3_Init(…)” fonksiyonunu tanımlayarak işlemi bitirebiliriz.

// initalize sensor module with the i2c address 0x70
shtc3_dev_t shtc3_dev;
shtc3_dev.dev_id = 0x70;
shtc3_dev.i2c_write = &my_i2c_write;
shtc3_dev.i2c_read = &my_i2c_read;
shtc3_dev.delay_us = &nrfx_coredep_delay_us;
SHTC3_Init(shtc3_dev);

Github sayfasında da görebileceğiniz gibi hazırladığım bu örnekle artık işlemci bağımsız bir kütüphane oluşturabildik. Bu sayede SHTC3 sıcaklık sensörü ile alakalı kodlarımızı donanımdan soyutlamış olduk.


Peki yazıda gördüğünüz hatalar neler, sizin daha iyi olduğunu düşündüğünüz bir yöntem var mı?Bu yazıdaki yöntemin olumlu ya da olumsuz yönleri sizce neler. Yorumlarınızı bekliyorum.

Hiç yorum yok: