RTOS gerekli mi sorusuna verilen "kullansak iyi olur" cevabı çoğu küçük projede gereksiz yere karmaşa katıyor. Tek bir LED yakıp ADC okuyan bir kart için zamanlayıcı kurmak hem hafıza hem CPU yükü açısından savurganlık. Diğer yandan üç-dört eş zamanlı görev olan bir cihazda bare-metal'de kalmak da çok geçmeden büyük bir state machine canavarı doğuruyor.
Aşağıdaki rehber RTOS gereken/gerekmeyen senaryoları, FreeRTOS'un temel kavramlarını ve ilk projeye nasıl başlayacağınızı kapsıyor.
Bu rehberde FreeRTOS'un ne olduğunu, ne zaman gerektiğini, temel kavramlarını ve pratik kullanımını açıklıyoruz. Yazının sonunda STM32 üzerinde basit bir FreeRTOS örneği ile başlangıç yapabilirsiniz.
RTOS Nedir, Bare-Metal'den Farkı Nedir?
Klasik bare-metal yaklaşımda tüm program tek bir main fonksiyonunda akar; görevler sırayla yürütülür. Kesmeler (interrupt) ile çoklu olay yönetimi mümkündür ama karmaşık projelerde bu yaklaşım sürdürülemez.
RTOS, MCU üzerinde çalışan bir görev yöneticisidir. Birden fazla görevin (task) eş zamanlı çalıştığı ILLÜZYONUNU yaratır; aslında MCU her an tek görev yürütür ama RTOS bu görevler arasında çok hızlı geçiş (context switch) yaparak paralel çalışıyormuş gibi gösterir.
| Özellik | Bare-Metal | FreeRTOS |
|---|---|---|
| Yapı | Tek main loop + ISR | Çoklu task, scheduler |
| Eş Zamanlılık | Manuel state machine | Doğal task ayrımı |
| Bellek Kullanımı | Minimum | Task başına ~256B-1KB stack |
| Öğrenme Eğrisi | Düşük | Orta |
| Ölçeklenebilirlik | Düşük | Yüksek |
| Hata Ayıklama | Kolay | Zor (race condition, deadlock) |
Ne Zaman RTOS Kullanmalı?
Her gömülü projeye RTOS gerekmez. Doğru karar verme rehberi şudur:
RTOS Mantıklı Olduğu Durumlar
- Aynı anda 3+ farklı zamanlamada iş yapılması gereken projeler
- UART, USB, Ethernet gibi haberleşme protokollerinin paralel yürütülmesi
- LCD/UI yönetimi ile arka plan veri işlemenin birlikte yapılması
- Sensör okuma, veri işleme, haberleşme, kullanıcı arayüzü gibi birden çok bağımsız görev
- Wi-Fi/BLE stack'leri (zaten dahili olarak FreeRTOS kullanır - örn. ESP-IDF)
- Karmaşık state machine'ler
Bare-Metal Yeterli Olduğu Durumlar
- Tek görevli sensör-aktüatör uygulamaları
- Çok düşük bellek (8 KB altı RAM) içeren MCU'lar
- Sıkı zamanlama gereksinimleri olan motor kontrol uygulamaları (FOC, PWM)
- Pille çalışan, çoğu zaman uyku modunda olan basit cihazlar
FreeRTOS Temel Kavramları
Task (Görev)
Bir task, kendi yığını (stack) olan bağımsız çalışan bir fonksiyondur. Her task'a bir öncelik atanır. Scheduler, en yüksek öncelikli ve hazır durumda olan task'ı çalıştırır.
Scheduler (Zamanlayıcı)
FreeRTOS preemptive (kesmeli) scheduler kullanır. Yüksek öncelikli bir task hazır olduğunda, çalışan düşük öncelikli task'ı durdurur ve kendi çalışır. Tipik tick frekansı 1 ms'dir; her tick'te scheduler hangi task'ın çalışacağına karar verir.
Queue (Kuyruk)
Task'lar arasında veri alışverişi için kullanılan FIFO yapıdır. Sensör okuyan bir task, okuduğu değeri queue'ya bırakır; veri işleyen task queue'dan alır. Bu yapı race condition'ları engeller.
Semaphore ve Mutex
Paylaşılan kaynaklara (UART, SPI, I2C) eş zamanlı erişimi engellemek için kullanılır. Mutex (mutual exclusion) bir kaynağı kilitler; o anda başka bir task aynı kaynağa erişemez. Semaphore daha genel amaçlıdır; kaynak sayısı sınırlı bir havuzu yönetir.
Event Group ve Notification
Task'lar arası senkronizasyon için. Bir task belirli bir olayın gerçekleşmesini bekleyebilir. Notification API'si daha hafif ve hızlıdır; çoğu senaryoda semaphore yerine notification kullanmak daha verimlidir.
Pratik Örnek: STM32 Üzerinde 3 Task'lı Sistem
Tipik bir IoT cihazı düşünelim: sıcaklık sensörünü her saniye okur, veriyi MQTT üzerinden buluta gönderir, LED ile durum gösterir. FreeRTOS ile bu üç işi birbirinden bağımsız task olarak tasarlarız:
- Task A: Sensör okuma görevi (öncelik: orta, periyot: 1 saniye)
- Task B: MQTT yayın görevi (öncelik: düşük, queue'dan veri bekler)
- Task C: LED durum görevi (öncelik: en düşük, 100 ms periyot)
Task A okuduğu sıcaklığı queue'ya bırakır. Task B queue'dan veri alır almaz MQTT üzerinden yayınlar. Task C arka planda LED'i yakıp söndürerek 'sistem çalışıyor' bilgisini verir. Üç görev tamamen birbirinden ayrı kodlanır; her biri kendi mantığına odaklanır.
Sıkça Yapılan Hatalar
Hata 1: Yanlış Stack Boyutu
Her task'ın kendi stack'i vardır. Stack overflow, FreeRTOS projelerinin en sık sorunudur. Stack boyutunu yetersiz tutarsanız sistem rastgele crash olur. uxTaskGetStackHighWaterMark() ile gerçek kullanımı ölçün ve ihtiyaca göre artırın.
Hata 2: ISR İçinde Yanlış API
FreeRTOS API'lerinin ISR-safe versiyonları vardır (örn. xQueueSendFromISR). ISR içinde normal versiyonu çağırmak sistemi kilitler. ISR'lerinizde mutlaka FromISR uzantılı fonksiyonları kullanın.
Hata 3: Priority Inversion
Düşük öncelikli bir task'ın elindeki kaynağı bekleyen yüksek öncelikli task, başka orta öncelikli task'lar nedeniyle bekleyebilir. Bu sorunu çözmek için mutex kullanırken priority inheritance özelliğini aktif tutun.
Hata 4: Task İçinde Sonsuz Polling
RTOS'un avantajı task'ların 'beklemesidir'. Bir task while(1) içinde sürekli bir flag'i kontrol ediyorsa CPU'yu boşa harcar. Onun yerine queue, semaphore veya notification ile bloklayıp uyandırılmalıdır.
Hata 5: vTaskDelay vs HAL_Delay Karışıklığı
FreeRTOS task'ları içinde HAL_Delay() kullanmayın; bu fonksiyon scheduler'ı bloklar ve diğer task'ların çalışmasını engeller. Bunun yerine vTaskDelay() veya vTaskDelayUntil() kullanın.
STM32CubeIDE ile FreeRTOS Entegrasyonu
Modern STM32 geliştirme akışında FreeRTOS entegrasyonu çok kolaydır. STM32CubeMX'in Middleware sekmesinden FreeRTOS'u aktif edebilir, görev ve queue tanımlarını grafiksel olarak yapabilirsiniz. CMSIS-RTOS v2 API'si standart bir soyutlama katmanı sunar; doğrudan FreeRTOS API'si yerine bu API ile yazmak ileride farklı bir RTOS'a geçiş yapma esnekliği sağlar.
Sonuç
FreeRTOS, gömülü sistem geliştiricisinin araç kutusunda olması gereken temel bir teknolojidir. Her projeye gerek olmasa da, orta-büyük ölçekli projelerde kod kalitesini, sürdürülebilirliği ve güvenilirliği ciddi şekilde artırır.
Önemli olan, RTOS'u olmazsa olmaz görmek değil, projeye gerçekten katkı sağlayacağı durumlarda kullanmaktır. Yanlış kullanılan bir RTOS, bare-metal'den daha kötü sonuç verebilir.
EA ARGE olarak, müşterilerimizin gömülü sistem projelerinde mimari kararını projenin gereksinimine göre veriyor; FreeRTOS, Azure RTOS (ThreadX) veya bare-metal yaklaşımlardan en uygunu öneriyor ve uçtan uca firmware geliştirme hizmeti sunuyoruz.
Bir tavsiye
RTOS'u öğrenmeden önce bare-metal'in altyapısını sağlam tutun. Interrupt, DMA, peripheral inisiyalizasyonu ve zamanlama mantığı net olmadan üstüne RTOS koyduğunuzda, hata aldığınızda kim yaratıyor; task priority mi, ISR'den çağrı mı, malloc/free heap fragmentation mı; anlayamıyorsunuz. Önce alt katmanı tut, sonra RTOS'u bunun üzerine yerleştir.