User account menu

  • Giriş yapın
Anasayfa
Kozmotronik Blog
Yıldız tozundan teknolojiye!

Main navigation

  • Anasayfa
  • Kategoriler
    • Elektronik
    • Programlama
      • Gömülü Programlama
      • Mobil Programlama
    • Programlama Dilleri
  • Seriler
    • Android Bluetooth Programlama
    • JAL Başvuru Kılavuzu
    • Görevci ile Sistem Programlama
  • Projeler
    • Görevci
  • Hakkında

Görevciye Genel Bakış

Sayfa yolu

  • Anasayfa
  • Görevciye Genel Bakış
Yazar: İsmail Sahillioğlu | Kasım 25, 2023
Görevci

Görevci Tanıtım sayfasında Görevciyi kısaca tanıtmıştım. Bu yazıda, şöyle bir genel bakış yapalım istedim. Görevci nasıl edinilebilir, API'leri (Application Programming Interface, Uygulama Programlama Arayüzü) nelerdir, bir görevin yapısı kodda neye benzer gibi soruları kısaca yanıtlamaya çalışacağım. Hadi başlayalım.

Görevciyi Edinme

Görevci farklı yöntemlerle uygulamanıza tümleştirilebilir.

  • Kaynak kodunu Github reposundan clon edip uygulamanın proje ağacına eklemek.
  • Uygulamanızda git sürümleme kullanıyorsanız bir git alt modülü (submodule) olarak eklemek.

Yakında CMake desteği eklenmesi de planlanmaktadır.

Görevci API'leri

Bir görevin bir olay beklemesi ya da gecikmesi gerekiyorsa CPU'yu boşuna meşgul etmemek, gerektiğinde beklemesi gereken görevi bloklayıp çalışmaya hazır başka bir görevin çalışmasını sağlamak Görevcinin temel amaçlarındandır. Ancak bu mekanizmanın düzgün bir şekilde işlemesi için görev bloğunun ana döngüsü içerisinde return, continue ve break gibi döngü kontrol komutları kesinlikle kullanılmamalıdır. Böyle yapmak görevin düzgün ve beklendiği gibi çalışmamasına neden olur. Bunun yerine aşağıdaki örnek durumlara uygun düşen API'ler kullanılmalıdır. Bu durumu imgeleyen örnek bir kod vermek gerekirse:

char gorev(gorevTutucu_t tutucu) {
    
    static char karakter;
    
    grvBASLA(tutucu);

    /* Bu döngü bir görev bloğunun ana döngüsüdür. for(;;) biçiminde de
     * yazılabilir. Burada sonsuz döngüde kalmalı, kesinlikle break veya
     * return ile döngüden çıkılmamalıdır.
     */
    while(1) {
        // break komutu ana döngüyü kıracak ve; elle yeniden çalıştırılmadığı
        // sürece görevi sonlandıracaktır.
        break;
        
        // continue olası Görevci API'lerinin görmezden gelinerek döngünün başa 
        // dönmesine neden olacağından beklenmeyen davranışlara neden olacaktır.
        continue;
        
        // return, değer verilmeden yazılırsa derleme hatasına neden olur.
        // Bir değer ile kullanılırsa yine görevin çıkmasına neden olurken, 
        // göreve bir dahaki girişte görevin beklendiği gibi davranmamasına 
        // neden olabilir.
        return; // derleme hatası!
        return 1; // Görevden çıkar ve kestirilemez davranışlara yol açabilir.
    }

    grvBITIR(tutucu);
}

Nitekim ana döngü içinde kullanılan alt döngülerde continue ve break komutları dikkatlice kullanılabilir:

char gorev(gorevTutucu_t tutucu) {
    
    static char karakter;
    
    grvBASLA(tutucu);

    /* Ana döngü  */
    while(1) {
    
        // Bir alt döngü
        for(uint8_t i = 0; i < 5; i++) {
            // break, alt döngüler için kullanılabilir, bu, ana döngüyü etkilemez.
            if(a < i) break;
        }
        
        // Veya...
        while(a != b) {
            ...
            ...
            // Bu durum da ana döngüyü ekilemeyeceği için sorun yaratmaz.
            if(c == '0') continue;
            ...
        }
    }

    grvBITIR(tutucu);
}

Bir diğer önemli konu, görev blokları içinde kullanılan değişkenlerdir. Görevci, yapısı gereği dinamik bellek yönetimi ve içerik değiştirme (context-switching) kullanmamaktadır. Görevcinin küçük ölçekli birçok aygıtta çalışabilmesini sağlayan en önemli özelliği az önce bahsedilen, bellek ve çalışma zamanı açısından küçük aygıtlar için çok maliyetli olan bu mekanizmaları kullanmamasıdır. Ancak görev blokları özünde birer işlev (function) olduğundan, görevler bloklandığında değişkenler normalde derleyici optimizasyonundan kaçamaz ve tuttukları verileri yitirirler. Bunu önlemek için değerini koruması gereken değişkenler tanımlanırken static niteleyicisi ile tanımlanmalıdır. Bu niteleyici derleyiciye ilgili değişkeni işlevden dönerken yok etmemesini, işlev bir dahaki sefer çağrıldığında bu değişkenin içeriğinin kullanılacağını bildirir.

Bir görevde gecikme yapılmak isteniyorsa

  • grvGECIK_MS() - işletim sistemlerinde sleep() işlevlerine benzer

  • grvKOSULLU_GECIK_MS() - işletim sistemlerinde sleep() işlevlerine benzer

Bir koşul veya olayın beklenmesi isteniyorsa

  • grvKOSUL_BEKLE()

  • grvBU_KOSULDA_BEKLE()

Verilere erişimde senkronizasyon gerekiyorsa

  • grvBAYRAK_BEKLE() - işletim sistemlerindeki wait() işlevlerine benzer

  • grvBAYRAK_IMLE() - işletim sistemlerindeki signal() işlevlerine benzer

CPU kontrolünden vazgeçmek gerekiyorsa

Bazen bir görev kendi isteğiyle kontrolü çalışmak için bekleyen başka bir göreve vermek isteyebilir. Böyle bir durumda:

  • grvVAZGEC() - işletim sistemlerindeki yield() işlevlerine benzer

  • grvKOSULA_DEK_VAZGEC()

Bu API'lerin herbirinin örnek kullanımları için birer yazı yazacağım, takipte kalın.

Görevlerin Temel Yapısı

Bir görevin normal bir C işlevinden pek bir farkı yoktur, yalnızca biraz daha yapılandırılmıştır ve sürekli çalışması gereken görevler içlerinde bir sonsuz döngü içerir. Bir görevin temel yapısı şu şekilde olmalıdır:

char gorev(gorevTutucu_t tutucu) {
    /* Görev kapsamında (scope) kullanılacak değişkenler burada
     * tanımlanabilir. Değerini koruması gereken değişkenler "static"
     * niteleyicisiyle tanımlanmalıdır.
     */
    static char karakter;

    /* Bir görev ana görev döngüsünden hemen önce her zaman görev yapısına
     * başvuru olarak parametre alan grvBASLA() ile başlamalıdır.
     */
    grvBASLA(tutucu);

    /* Buraya bir kereye mahsus çalışacak kodlar. Örneğin bir giriş - çıkış
     * portunu ilkleme veya bir analog ucunu ilkleme kodları gibi.
     * Buradaki kodlar görevin yaşam süresi boyunca yalnızca bir kez
     * çalışacağı için ilklendirme işlemlerini yapmak için idealdir.
     */

    /* Bu döngü bir görev bloğunun ana döngüsüdür. for(;;) biçiminde de
     * yazılabilir. Burada sonsuz döngüde kalmalı, kesinlikle break veya
     * return ile döngüden çıkılmamalıdır.
     */
    while(1) {
        // Buraya görev kodları ve bloklayıcı API çağrıları
    }

    /* Tüm görev işlevleri görev yapısına başvuru olarak parametre alan
     * grvBITIR() ile sonlanmalıdır. Akış sonsuz döngüden buraya buraya
     * gelmesi görevin bir daha çalışmamasına neden olabilir.
     */
    grvBITIR(tutucu);
}

Pekala, yazının girişindeki soruları kısaca yanıtlamaya çalıştım. Sonraki yazılarda Görevci API'lerinin kullanımlarını örneklendirerek, onların nasıl yerine uygun bir şekilde kullanılabileceğini betimleyeceğim. Sonrakinde görüşmek üzere, herkese mutlu kodlamalar.

görevci
C
Multitarea
Sistem programlama
Programación
Gömülü Programlama
Görevci ile Sistem Programlama
Görevci
  • < prev
  • All
  • next >

12 of 34

Sorumluluk Reddi

Bu site bilgilendirme amaçlıdır. Burada sunulan bilgileri, uygulayıcı kendi sorumluluğu altında uygular. Bu bilgilerin uygulanması sırasında ihmal, dikkatsizlik, konuyla ilgili bilgi eksikliği veya yanlış uygulama nedeniyle meydana gelebilecek hasarlardan, can veya mal kaybından, maddi veya fiziksel kayıplardan tamamen uygulayıcı sorumlu olup site ve yazarları sorumlu tutulamaz.

Projects

Görevci

Monthly archive

  • Şubat 2017 (2)
  • Mart 2017 (1)
  • Nisan 2017 (1)
  • Mart 2019 (1)
  • Nisan 2019 (1)
  • Temmuz 2019 (3)
  • Eylül 2019 (1)
  • Ekim 2019 (1)
  • Mart 2020 (1)
  • Ağustos 2020 (3)
Sayfalama
  • Sayfa 1
  • Sonraki sayfa ››

Footer menu

  • İletişim

Copyright © 2026 Kozmotronik Tech - All rights reserved

Kozmotronik Tech