Bu yazımda platform bağımsız olarak mikroişlemcili sayısal sistemlerde istenilen görevlerin delay fonksiyonları ile geciktirilerek çalıştırılması yerine görevlerin zamanlanmasını, co-operative ve multitasking yapılı sistemlerin çalışma mantığını basit olarak inceleyeceğiz.
Kompleks uygulamalarda mikroişlemcinin çalıştırması gereken birden fazla görev olmaktadır.Bunlara örnek olarak haberleşme görevleri,ölçüm görevleri, hesaplama görevleri gibi görevleri verebiliriz.Sağlıklı bir sistemde bu görevlerin hepsi uyum içerisinde çalışmalıdır.Mikroişlemci bu görevlerden aynı anda sadece birtanesini çalıştırabilmektedir. Bir görev çalışırken diğerleri beklemekte ve bekleyerek boşa geçirdikleri zaman ölü zaman olarak değerlendirilmektedir.Dolayısıyla kapsamlı uygulamalarda bir işlem yapılırken o işlemin mümkün olduğunda çabuk bitirilip akışın diğer görevlere verilmesi istenir.Delay ve bekleme mantığından mümkün olduğunca uzak durulması istenir.Bu çalışma biçimine co-operative çalışma denilmektedir.
Kullandığımız bilgisayarlarda buna benzer şekilde çalışmaktadır. Aslında bir anda sadece bir görev çalışmaktadır fakat siz aynı anda müzik dinleyip, dosya indirip, yazı yazabilir okuyabilirsiniz.Tüm bu işlemler 10ms gibi zaman periyotları ile sıra sıra çalıştırıldığından bize aynı anda çalışıyorlarmış gibi gelirler (tabi birde görevlerin önem sırasıda vardır).Bu çalışma biçmine multitasking denilmektedir (çok çekirdekli işlemcilerde aynı anda çekirdek sayısı kadar görev çalışmaktadır). Aşağıdaki şekilde delay mantığı kullanan ve zamanlanmış co-operative çalışan sistemlerin karşılaştırılması üzerine bir örnek gösterilmiştir.
Co-operative çalışma biçimi
Delay mantığı kullanan sistemin çalışması
Yukarıdaki iki sistemde de görevlerin 500ms sonra çalıştırılması istenmiştir ve görev süreleri eşit olarak 10ms dir.Co-operative çalışan sistemde 500ms lik periyotlar ile görevler otomatik olarak ard arda sırası ile çalışmıştır.Aralarda kalan boş zamanlara başka görevlerde sıkıştırılabilir.Böylece işlemciyi en verimli şekilde kullanmış oluruz.Gecikme mantığı kullanan sistemde ise gecikme zamanında işlemcide hiçbir işlem yapılamaz ve işlemci en verimsiz şekilde kullanılır.Bu zamana ölü zaman denilmektedir.Bu sistemde bir görev çalıştıktan sonra 500ms lik bekleme yapılır ve diğer görev çalıştırılır. Yukarıdaki şekiller anlatıma örnek teşkil etmesi bakımından hazırlanmıştır.Farklı algoritmalar kullanılabilir.
Şimdi platform bağımsız bir örnek yapalım. İşlemcimizin timer donanımını 1ms de kesme oluşturacak şekilde kuralım ve kesme fonksiyonunda bir değişkenin içerisini bir arttıralım. Bu 1ms lik zamanı bir tick diye isimlendirelim.Bir fonksiyon yazalım ve bize tick değişkeninin değerini versin. Uygulama fonksiyonlarımızda yerel değişkenlere istediğimiz zamanı tick türünden atayalım ve tick değişkenimizin değeri ile karşılaştırarak görevimizin çalıştırılıp çalıştırılmayacağını anlayalım.Hassas zaman isteyen uygulamalarda bir saat, bir gün, bir hafta gibi sürelerde çalışacak görevler için işlemcinin RealTimeClock donanımı kullanılmalıdır.
#define SANIYE 1000
#define DAKIKA 60 * SANIYE
#define SAAT 3600 * SANIYE
typedef unsigned long int TICK_t;
TICK_t tick;
void kesme_fonksiyonu(void)
{
tick++;
//Diger kesme islemleri
}
TICK_t tick_sayisi(void)
{
return tick;
}
int main()
{
TICK_t t1,t2,t3;
//Baslangic islemleri
t1=t2=t3=tick_sayisi();
for(;;)
{
//100mslik periyotlar ile calistirilmak istenen gorev
if( tick_sayisi() - t1 >= SANIYE/10 )
{
t1=tick_sayisi();
gorev1();//Gorev 1 fonksiyon cagrisi
}
//5 dakikalik periyotlar ile calistirilmak istenen gorev
if( tick_sayisi() - t2 >= DAKIKA*5 )
{
t2=tick_sayisi();
gorev2();//Gorev 2 fonksiyon cagrisi
}
//1 saatlik periyotlar ile calistirilmak istenen gorev
if( tick_sayisi() - t3 >= SAAT )
{
t3=tick_sayisi();
gorev3();//Gorev 3 fonksiyon cagrisi
}
//Yapilmak istenen diger islemler.
}
}
Yukarıdaki zaman kontrolünü şu şekildede yapabilirdik
t1=tick_sayisi()+SANIYE/10;
if( tick_sayisi() >= t1)
{
t1=tick_sayisi()+SANIYE/10;
gorev1();
}
Bu yazımda mikroişlemcili sayısal sistemlerde görevlerin çalışma şeklini ve kod yazarken görevlerimizi nasıl zamanlayıp işlemciyi daha verimli kullanabileceğimizi, sistemdeki donanımların birbiri ile uyum içerisinde sağlıklı bir şekilde nasıl çalışabileceğini inceledik.Bir sonraki yazıda görüşmek üzere :)