Gömülü ve Gerçek Zamanlı Tasarım Kalıpları-2. Görev Tasarım Kalıpları

Huseyin Kutluca
Nov 3 · 5 min read
Adam kayalar, Mersin

Gömülü yazılımlarda uygulamayı birden çok görev(task) olarak tasarlamamız gerekebilmektedir. Task kavramı gömülü yazılım dünyasında modern anlamdaki thread ve process gibi yapıları ifade etmek için kullanılır. Ayrıca işletim sisteminin olmadığı (bare-metal) ve gömülü yazılımı geliştiren mühendis tarafından zamanlaması tasarlanan işler de task olarak tanımlanır.

UML dünyasında taskı kenarları çift çizgili nesne olarak gösteriyoruz. Görev kimi zaman aktif obje (active object) olarak da isimlendirilmektedir.

Task yada aktif obje

Uygulamada kaç tane görev olacak, her bir görevin içinde hangi işler yapılacak, görevlerin önceliği ne olacak, nasıl aktive olacak ve bu görevler arası iletişim/koordinasyon nasıl sağlanacak bu kararlar önemli tasarım işleridir.

Öncelikle görevleri nasıl başlatıldığına göre sınıflandırıyoruz. Olay tabanlı görevler dışarıdan interrupt ve benzeri bir itki ile başlayan görevlerdir. Periyodik görevler belirli bir periyotta devamlı yapılması gereken işlerdir. Bunlar genelde bir zamanlayıcı (timer) ile tetiklenir. Son olarak istek tabanlı görevler ise ihtiyaç duyulduğunda başlatılan işler için kullanılır. Örneğin bir dosyaya yazma işi bir başka görevden mesaj geldiğinde başlayabilir.

Girdi/Çıktı Görevleri (Input/Output Tasks)

Gömülü ve gerçek zamanlı sistemlerde öncelikle sistemin etkileştiği sistemler belirlenir ve bu sistemlerden veri okuma ve veri yazma ile ilgili görevler belirlenir. Bu Girdi/Çıktı görevlerini yine başlatılma şekline göre sınıflandırıyoruz.

Olay tabanlı girdi/çıktı görevlerinde dış cihazdaki durum değişikliği bir kesme(interrupt) yada benzeri bir mekanizma tetikler. Bunun sonucu ilgili görev çalıştırılır. Bu iş içinde öncelikle girdi okunur ve çözümlenerek yerel veri formatına çevrilir. Daha sonra bu veri işlenmek üzere başka göreve iletilir. Örneğin kahve makinesinde çalıştır değer değiştirdiğinde (ON-OFF yada OFF-ON) bir interrupt tetiklenerek ilgili tuş için işlemin hemen yapılması sağlanabilir. Ethernet üzerinden bir UDP mesajın gelmesi de olay tabanlı girdi olarak örnek verilebilir.

Periyodik girdi/çıktı görevlerinde ise belirlenen süre geçtiğinde zamanlayıcı (timer) bir sinyal göndererek periyodik işin başlamasını tetikler. Periyodik görevin içinde girdiler okunur ve işlenmek üzere bir sonraki bileşene iletilir. Örneğin kahve makinesinde suyun sıcaklığı saniyede bir okunarak gerekli işlem yapılabilir. Sensör tabanlı endüstriyel sistemlerde ve hareket kontrol tabanlı sistemlerde bu yaklaşım yaygın olarak kullanılmaktadır. Bu durumda periyodik olarak bütün analog ve sayısal girdiler okunup mevcut pozisyon, hız gibi bilgiler değerlendirilir.

İstek tabanlı girdi/çıktı görevlerinde dışarıdan bir tetikleme olmaksızın uygulamanın algoritmasının gerekli okuma yada yazma işlemini gerçekleştirir. Örneğin kahve hazır olduğunda ses çıkartmak üzere ilgili donanım bileşenine çıkış yapılabilir.

Kontrol ve Kullanıcı Etkileşimi Görevleri

Durum makinesi bağımlı kontrol görevi (State dependent task) gömülü sistemlerde en kritik görevlerden birisidir. Bu görev durum makinesi (state chart) çalıştırarak durum değişiklikleri olaylara göre gerçekleştirilir ve ilgili durumda yapılması gereken işlemler yapılır. Durum makinesi görevi genelde diğer görevlerden durum değişikliği yaratabilecek mesajlar (eventler) alır.

Koordinatör görevinde ise bir durum makinesi yoktur fakat yapılacak işlem alınan veriye göre değişir. Karar verme mekanizması bu görevin içinde gerçekleştirilir.

Son olarak kullanıcı etkileşim görevi kullanıcı ara yüzünü oluşturma ve bu arayüz üzerinden kullanıcı girdisi alma işlemini yürütür.

Görevleri Gruplama

Sistemde çok fazla görev olduğunda bunları yönetmek zorlaşmaktadır. Bu durumda tasarım aşamasında belirlenen görevler özelliklerine göre sınıflamak anlamlı olmaktadır. Zamansal sınıflandırmada aynı veya benzer periyodlarda okunması gereken girdiler birleştirilerek aynı görev içinde okunması sağlanabilir. Örneğin farklı sayısal veriler periyodik olarak okunuyor ise her bir girdi için ayrı görev yerinde birden fazla girdi okuma aynı görev içerisine yer alabilmektedir. Benzer şekilde birden fazla farklı UDP portundan mesaj okuma için select mekanizması ile aynı görev kullanılabilir.

Sıralı sınıflandırmada ise her zaman ardı ardına yapılan görevler aynı görev içine alınıp işlenebilir. Örneğin aracın durumunu aldıktan sonra onu ekranda gösterecek göreve göndermek yerine ikisini ardışık olarak aynı görevde yapabiliriz. Kontrol sınıflandırmada ise özellikle isteğe bağlı görevler onu tetikleyen kontrol görevinin içine alınıp peş peşe çalıştırılabilir.

Görevler Arası İletişim

Bir görev dış sistemden veriyi okuduktan sonra bu veriyi işlenmek üzere başka bir göreve iletmesi gerekebilir. Bu durumda kullanılabilecek en basit yaklaşım bu veriyi ortak bir alana kopyalayıp diğer görevlerin erişmesini sağlamaktır. Bu yaklaşım tercih edildiğinden verinin korunması için ekstra önlemler almalıyız. İşletim sistemi kullanıyor isek mutex dediğimiz ve aynı anda bir alana bir görevin erişmesini sağlayan mekanizmalar kullanılabilmektedir. Bu yöntem basit olmasına karşılık kilitlenme gibi problemlere yol açtığı için her zaman tercih edilmez.

Gömülü sistemler için en fazla tercih edilen yöntem görevler arası veri iletişimini mesaj kuyrukları aracılığı ile yapmaktadır. Bu durumda veriyi sağlayan görev veriyi bir kuyruğa atar ve veriyi işleyecek görev sırayla kuyruktan verileri alarak işlemeye başlar. Bu yaklaşımın tercih edilme sebebi kritik algoritmaların mutex tarzı kilit mekanizmalarına fazla ihtiyaç duymamasından dolayı daha kolay yönetilebilen sistemler geliştirilebilmesidir.

Eğer kullanılan gerçek zamanlı işletim sistemi görevler arası mesaj iletimini destekliyor ise bu yapı kullanılabilir. Aksi takdirde aynı mekanizma bir kuyruk yapısı (bazen önceliklı kuyruk) ile geliştirilebilir. Bu durumda sadece kuyruğu koruma adına mutex yapısı kullanılır. Mekanizma daha basit olduğundan bu yapıda kilitlenme riski yok gibidir. Mesaj hazırlama ve işleme kritik alan dışında yapılır. Kritik bölgede sadece kuyruğa masaj konur yada alınır.

Bu durumda veriyi işleyen görevin ana döngüsü aşağıdaki gibi basit bir yapıda olacaktır:

Hem visitor tasarım aklıbını kullanan hem de mesaj kuyruğu üzerinden gelen verileri işleyen bir C++-11 görev kodu kodu aşağıdaki gibi gözükebilir:

Bu mekanizma sadece gömülü sistemleri için değil diğer birçok uygulamada temel olarak kullanılabilmektedir. Örneğin Go dilinde aynı mekanizma için dilde hazır olan channel yapısı kullanılarak hızlıca aynı işlem yapılabiliyor:

Bilişim Hareketi

Türkiye'nin bilişim alanında gelişmesi için bir katkı

Huseyin Kutluca

Written by

Principal Software Architect at ICterra

Bilişim Hareketi

Türkiye'nin bilişim alanında gelişmesi için bir katkı

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade