GÖMÜLÜ YAZILIM MANTIĞINI ANLAMAK

Ahmet

S38>S85
Katılım
31 Mayıs 2021
Mesajlar
6,047
Çalıştığım işletmede çoğu zaman ufak çaplı tartışmalara sebep olan 'gömülü' mantığını pekiştirmek benim için sorun olmaya başladı.

İşletmenin benimsetmeye çalıştığı gömülü yazılım mantığı tam olarak şöyle;
3 farklı marka denetleyici üreten marka ile çalışıyoruz ve yazdığımız software çok az zaman kaybederek yapılacak düzenleme ile bu 3 marka içinde çalışır hale gelmeli yani şöyle;

Analog okuma yapacağız bu her denetleyici için kalıp aynı kalacak biz sadece o üreticiye ait ham komutları alıp kalanını aynı bırakacağız

C++:
void adc_read(int64_t adc_val){
 adc_val = analogRead(adc_pin);//sadece bu satır değişip başka mcu'ya uyumlu olacak
 .
 .
 .
}
Gömülü mantığı tam olarak bu mu?
 
Birçok farklı MCU ile çalışacak firmware geliştirmeyi aşağıdaki başlıklarla ele alabiliriz.

1) MCU'dan bağımsız olarak çalışan program kodu.
2) Her MCU için ayrı olarak yazılması gereken program kodu.
3) 1 ve 2 arasındaki programlama arabirimi (veya API)

İyi bir firmware tasarımında, MCU'dan bağımsız çalışan kodu mümkün olduğunca fazla, MCU ya özgü kodu da mümkün olduğunca aza indirmeye çalışmamız lazım.

Bunun dışında, bu iki bileşen arasında olabildiğince basit ve etkili bir programlama arabirimi (veya API) tasarımı yapabilmeliyiz. İşin bu bölümü aslında bir sanattır ve uzun yılların tecrübesi ile iyi bir seviyeye gelinebilir.
 
Mesela senin örnekten gidecek olursak, ADC'den okuma yapması gereken bir firmware'de nasıl bir API tasarımı yapabiliriz? Değişik MCU larda değişik sayıda ADC bulunabiliyor. Bu ADC'lerin de bazılarında girişte bir multiplexer olabiliyor. Bazı MCU'larda ADC bit sayısı yapılandırılabiliyor. Tüm bu senaryoları kapsamak istiyoruz. Ayrıca API fonksiyonlarında başarı veya hata durumunu da ifade etmek istiyoruz. Buna göre aşağıdaki gibi bir API yapsak nasıl olur?

C++:
int adc_init();
int adc_device_count(unsigned int* count);
int adc_get_config(int device, ADC_CONFIG* config);
int adc_set_config(int device, const ADC_CONFIG* config);
unsigned int adc_read(int device, int channel = 0);

Bu API da adc_read dışında her fonksiyon bir sonuç kodu döndürüyor. Sonuç başarılı ise 0, başarısız ise negatif bir hata kodu dönüyor. adc_read ise doğrudan ADC verisini döndürüyor.

adc_init: MCU daki ADC donanımlarını yapılandırıyor ve başlatıyor.
adc_device_count: Kaç tane ADC olduğunu öğrenmeye yarıyor.
adc_get_config: ADC ile ilgili ayrıntıları öğreniyoruz. Kaç bitlik? Referans voltajı ne? MUX var mı girişinde? Varsa kaç kanallı?
adc_set_config: ADC yapılandırıyor. Bit sayısı vs.
adc_read: ADC den okuma yapıyor. Hangi ADC den okuduğumuzu, ve MUX varsa hangi kanaldan okunacağını belirtiyoruz.

Şimdi böyle bir API tanımladıktan sonra, MCU dan bağımsız kod bu API ile çalışacak ve her türlü MCU da doğru çalışacak. MCU ya bağımlı kod ise, bu fonksiyonları her MCU için ayrı ayrı gerçekleştirilmesinden ibaret olacak.

Bu API değişik ihtiyaçlara göre daha da geliştirilebilir. Mesela arka planda DMA ile sürekli veri okunuyorsa, belli sayıda veri okununca kesme gelmesi sağlanabilir.
 
Diyelim şu anda bizim firmware üç tane MCU tipini destekliyor, stm32, Renesas, Nuvoton. Eğer firmware bu mimarilerden sadece birisi seçilecek ve onun için derlenecekse, aşağıdaki gibi bir yapı kullanılabilir:

// MCU ya özgü kodlar
adc_stm32.cpp
adc_renesas.cpp
adc_nuvoton.cpp

// MCU dan bağımsız, yukarıdaki fonksiyon prototiplerini içeren header
adc.h

// MCU dan bağımsız ana program kodu
main.cpp

Firmware build edilirken, bir yapılandırma değişkeni ile hangi adc_xxx.cpp dosyasının build'e dahil edileceği belirlenecek.
 
Bir diğer senaryo da, MCU mimarisi değişmiyor, ama MCU'ya değişik tipte harici ADC'ler bağlı. Ve MCU'ya aynı anda birden fazla, değişik tipte ADC bağlı olabiliyor. Bu senaryoda bize en güzel, en elegant çözümü C++ ın nesneye yönelik programlama özellikleri sağlıyor. Ama bu tek mesajda açıklanabilecek bir konu değil, bir örnek program ile ve örnek devre üzerinden anlatılması daha uygun.
 
Ben işe başlarken işletmenin bir fan boy olacağını tahmin ederdim mesela stm32 fanboyu ve stmden başka kullanmıyorlar vs.

Fakat içeri girdikten sonra sadece bu satın alma ile ilgilenen 2 kişi olduğunu gördüm her projenin istenen kriterleri vermişler(analog kanal sayısı, minimum ekran boyutu vs.)
Bunları kıyas edip devamlı ürün arayışındalar uygun dsPIC, stm32, avr ailesinden birisi hiç fark etmiyor alıyorlar hemen fiyat olarak normalden 5-10 cent ucuzsaa almak için yeterli bi sebep.
Birde kara listemiz var o listedekiler bedava da olsa alınmıyor pic12 serisi, attiny serisi, stcler, espler, rpiler kesinlikle satın alınmıyor.

Sonra iş başa düşüyor bu alınan mcuşar için hali hazırdaki softwareleri uygulamak.
Burada gömülü yazılımcılık başlıyor.

@taydin teşekkür ederim aydınlatıcı bir yazı oldu :)
 
Aslında iş MCU'ya filan bağlı değil. İhaleye bağlı. Özellikle devlet veya devlete bağlı olan ihalelerin şartnamelerinde şu cihaz, bu sistem, bu scada diye şart koşarlar. Bu şartnameleri hazırlayanlar işin uzmanı değildir. Genelde şartnameyi hazırlayan devlet memuru mühendistir. tecrübesi yoktur. İşi yapmaz, yaptırır konumda olduğundan bildiği gibi hazırlar. Veya bu şartnameyi hazırlamak için bir bilirkişi firma tutarlar. O firmalar iş yapan değil ihale paslayan firmalardır. O şartnameyi öyle bir hazırlarlarki iş direk hedef firmaya verilmek durumunda olur. Bunun bedelini üretimi/işi yapanlar öder.

Yani aslında sistem seçimi avantajına, fiyatına göre filan olmaz. İşi yapacak bilen adamın lafı dinlenmemiş olur.

Ama yinede günün sonunda @taydin dediği gibi bu iş tecrübeyle oluyor. 2-3yıllık yazılım hayatı olup, linkedin'e "Senior Software Developer" yazmakla bu tecrübe kazanılmıyor. Süre, çaba, uğraş, denem ve zamanla oluyor.

Günün sonuda sizin bu kadar farklı sistemde kazandığınız tecrübeyi patron "ona da PORT edelim" diye geçiştiriyor.
Staj yaptığım işletme ne yerli menşeili ne devlet kurumu nede yerli piyasaya ürün veriyor.

Nerdeyse hiç durmayan ar-ge sebebiyle bu kadar çeşitli mcu için geliştiriliyor.

Çoğu zaman tercih dsPIC oluyor sanayide en iyi davranan olduğu için ama diğerlerinin daima masada yeri oluyor.

Yerli ar-ge diye bir kavram yok malesef ucuz olana göre yapılıyor :)
 
dsPIC i ben de iyice öğrenmek istiyorum. Bu MCU da uzman olan çok geniş yelpazede çok etkili ürün geliştirir.
 
dsPIC i ben de iyice öğrenmek istiyorum. Bu MCU da uzman olan çok geniş yelpazede çok etkili ürün geliştirir.
Abi sorma ben alışmışım avr&stm çalışmaya çoğu zaman verilen işi bitirmem için 2 3 kişi bana çeşitli yerlerde destek veriyor.
 
dsPIC gider fsPIC gider. Yıllardır microchip bir sürü ürün çıkardı.Takip etmek mesele. Tam öğrendim dediğinde başka bir şey çıkartacak. O sebeple donanıma bağımlı kalmayacak tecrübeye erişmek hedef olmalı.

Bana kalsa tüm bunlar yerine Fpga, Verilog, System Verilog önü daha açık bir alan... Ama Türkiye'de VhDL geçerli garip bir şekilde..
Biraz gerçekçi bakmak lazım.
İş ilanlarına baktığında 2 tane fpga için ilan görürken 20 tane gömülü yazılımcı ilanı görüyorsun.

aralarında maaş olarak net x2 var ama bence Türkiye şartlarında derinlemesine öğrenmek şart değil. Bilsen yeter.
 
abi bu senaryoyu dongle sız frekans işinde kullanabilirmiyim ?

Sen en iyisi bir RTL SDR al ve onu kurcalamaya başla. PC'de özel hardware olmadan RF sinyal alıp işleyemezsin.
 
  • Üzgün
Reactions: nt
#if defined(stm)
stm();
#elif defined(avr)
avr();
#else
error();

@taydin hocam yukarıda ki mantıkla donanıma bağımlı olan kısımları ayırıp, header dosyasından işlemci seçen bir parametre ile kodları işlemciye göre derlemek mantıklı olur mu bu konuda?
 
Mümkün olduğunca yukarıda belirttiğim gibi linker ile ayırmak daha mantıklı. Ama bu her zaman olmuyor tabi ve hardware'i tanımlayan ifdef'ler atmak gerekiyor.
 
Çalıştığım işletmede çoğu zaman ufak çaplı tartışmalara sebep olan 'gömülü' mantığını pekiştirmek benim için sorun olmaya başladı.

İşletmenin benimsetmeye çalıştığı gömülü yazılım mantığı tam olarak şöyle;
3 farklı marka denetleyici üreten marka ile çalışıyoruz ve yazdığımız software çok az zaman kaybederek yapılacak düzenleme ile bu 3 marka içinde çalışır hale gelmeli yani şöyle;

Analog okuma yapacağız bu her denetleyici için kalıp aynı kalacak biz sadece o üreticiye ait ham komutları alıp kalanını aynı bırakacağız

C++:
void adc_read(int64_t adc_val){
 adc_val = analogRead(adc_pin);//sadece bu satır değişip başka mcu'ya uyumlu olacak
 .
 .
 .
}
Gömülü mantığı tam olarak bu mu?
MicroPython.
 
tabi yapılabilir ama işlemci seçimini satın alma ekibine bırakmak çok kötü bir yönetim stratejisi. işlemci belki 0.1 usd daha ucuz ama o kodu geliştirirken ve ardından sahada hata ayıklarken harcanan zamanın bedeli bunu aşacaktır.
 
micro da olsa gomulude cok hantal kalır fark edilecek şekilde
C++ ile derlenmis bir program Python'dan ortalama 4 kat hizli calisiyor. Ama Python ile program gelistirmek C++'tan 4 kat daha hizli. Ustelik gercekten "mobil" oluyor. Python yuklu olan herhangi bir sistemde nerede ise hic bir degisiklik yapmadan calistirabiliyorsun. Bir yerden alirken bir yerden veriyorsun iste.
 

Çevrimiçi personel

Forum istatistikleri

Konular
5,656
Mesajlar
97,304
Üyeler
2,438
Son üye
İbrahimSönmez

Son kaynaklar

Son profil mesajları

cemalettin keçeci wrote on HaydarBaris's profile.
barış kardeşim bende bu sene akıllı denizaltı projesine girdim ve sensörleri arastırıyorum tam olarak hangi sensör ve markaları kullandınız yardımcı olabilir misin?
m.white wrote on Altair's profile.
İyi akşamlar.Arabanız ne marka ve sorunu nedir.Ben araba tamircisi değilim ama tamirden anlarım.
* En mühim ve feyizli vazifelerimiz millî eğitim işleridir. Millî eğitim işlerinde mutlaka muzaffer olmak lâzımdır. Bir milletin hakikî kurtuluşu ancak bu suretle olur. (1922)
Kesici/Spindle hızı hesaplamak için SpreadSheet UDF'leri kullanın, hesap makinesi çok eski kalan bir yöntem :)
Dr. Bülent Başaran,
Elektrik ve Elektronik Mühendisi
Yonga Tasarım Özdevinimcisi
Üç güzel "çocuk" babası
Ortahisar/Ürgüp/Konya/Ankara/Pittsburgh/San Francisco/Atlanta/Alaçatı/Taşucu...

Back
Top