0% found this document useful (0 votes)
5 views13 pages

Embededde

Uploaded by

pmb97672
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as ODT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views13 pages

Embededde

Uploaded by

pmb97672
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as ODT, PDF, TXT or read online on Scribd

1.

Preface

FreeRTOS, gerçek zamanlı bir çekirdek ve tamamlayıcı işlevleri uygulayan bir dizi modüler
kütüphaneden oluşan bir C kütüphaneleri koleksiyonudur.

FreeRTOS'ta her bir yürütme iş parçacığı 'görev' olarak adlandırılır. Gömülü topluluk içinde
terminoloji konusunda bir fikir birliği yoktur, ancak iş parçacığı bazı uygulama alanlarında daha
özel bir anlama sahip olabileceğinden, 'Task” kullanılmakta.

Data Türleri

TickType_t

TickType_t, tik sayısı değerini tutmak ve zamanları belirtmek için kullanılan veri türüdür.

Fonksiyon İsimleri

Fonksiyonların önüne hem döndürdükleri tip hem de içinde tanımlandıkları dosya eklenir.

Örneğin:

vTaskPrioritySet() bir void döndürür ve tasks.c dosyası içinde tanımlanmıştır.

xQueueReceive() BaseType_t türünde bir değişken döndürür ve queue.c dosyası içinde


tanımlanmıştır.

pvTimerGetTimerID() bir void gösterici döndürür ve timers.c içinde tanımlanmıştır.


Dosya kapsamı (özel) fonksiyonlarının başına 'prv' eklenir.

3. Heap Memory Management

Bu nesneleri tutmak için gereken RAM, derleme zamanında statik olarak veya çalışma zamanında
dinamik olarak tahsis edilebilir. Dinamik tahsis, tasarım ve planlama çabasını azaltır, API'yi
basitleştirir ve RAM ayak izini en aza indirir.

Statik tahsis daha deterministiktir, bellek tahsis hatalarını ele alma ihtiyacını ortadan kaldırır ve
yığın parçalanması riskini ortadan kaldırır (yığında yeterli boş bellek olduğu ancak kullanılabilir
bitişik bir blokta olmadığı durumlarda).

Heap_1.c
Heap_1.c, pvPortMalloc() işlevinin çok basit bir versiyonunu uygular ve vPortFree() işlevini
uygulamaz.

Heap_2.c
Bellek ayırmak için en uygun algoritmayı kullanır ve heap_1'den farklı olarak vPortFree() işlevini
uygular

Heap_3.c
Heap_3.c standart kütüphane malloc() ve free() işlevlerini kullanır, bu nedenle bağlayıcı
yapılandırması yığın boyutunu tanımlar ve configTOTAL_HEAP_SIZE sabiti kullanılmaz
Heap_4.c
Heap_4 bellek ayırmak için bir ilk uygun algoritma kullanır. Heap_2'nin aksine, heap_4 bitişik boş
bellek bloklarını tek bir büyük blokta birleştirerek (coalesces) bellek parçalanması riskini en aza
indirir.

Heap_5.c
Heap_5, heap_4 ile aynı tahsis algoritmasını kullanır. Tek bir diziden bellek ayırmakla sınırlı olan
heap_4'ün aksine, heap_5 birden fazla ayrılmış bellek alanından belleği tek bir yığın içinde
birleştirebilir

4. Task
Tasks C fonksiyonları olarak uygulanır. Tasks, void işaretçi parametresi alan ve void döndüren Liste
4.1'de gösterilen beklenen işlev prototipini uygulamalıdır.

void vATaskFunction( void * pvParameters );

Her görev kendi başına küçük bir programdır. Bir giriş noktası vardır, normalde sonsuz bir döngü
içinde sonsuza kadar çalışır ve programdan çıkmaz.

Task iki durumdan birinde mevcut olabilir: Running ve Not Running.

Six API functions may be used to create tasks: xTaskCreate(), xTaskCreateStatic(),


xTaskCreateRestricted(), xTaskCreateRestrictedStatic(), xTaskCreateAffinitySet(), and
xTaskCreateStaticAffinitySet()

The xTaskCreate() API Function

BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,


const char * const pcName,
configSTACK_DEPTH_TYPE usStackDepth,
void * pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * pxCreatedTask );

pvTaskCode
Task'lar basitçe asla çıkmayan C fonksiyonlarıdır ve bu nedenle normalde sonsuz bir döngü olarak
uygulanırlar. pvTaskCode parametresi basitçe görevi uygulayan fonksiyona bir işaretçidir (aslında
sadece fonksiyonun adıdır).

pcName
Görev için açıklayıcı bir isim. FreeRTOS bunu hiçbir şekilde kullanmaz ve yalnızca bir hata
ayıklama yardımı olarak dahil edilmiştir. Bir görevi insan tarafından okunabilir bir adla tanımlamak,
onu tanıtıcısıyla tanımlamaktan çok daha basittir.

usStackDepth
Görev tarafından kullanılmak üzere ayrılacak yığının boyutunu belirtir. Dinamik olarak ayrılan
bellek yerine önceden ayrılan belleği kullanmak için xTaskCreate() yerine xTaskCreateStatic()
işlevini kullanın.
pvParameters
Görevleri uygulayan işlevler tek bir void işaretçi (void *) parametresi kabul eder. pvParameters
değeri bu parametre kullanılarak göreve aktarılır.

uxPriority
Görevin önceliğini tanımlar. 0 en düşük önceliktir ve (configMAX_PRIORITIES - 1) en yüksek
önceliktir.

pxCreatedTask
Oluşturulan görevin tanıtıcısını saklamak için bir konuma işaretçi. Bu tanıtıcı, örneğin görevin
önceliğini değiştirmek veya görevi silmek için gelecekteki API çağrılarında kullanılabilir.
İki olası dönüş değeri vardır:
pdPASS Bu, görevin başarıyla oluşturulduğunu gösterir.

pdFAIL Bu, yeterli bellek alanı olmadığını gösterir

Not Running Durumunun Genişletilmesi

The Blocked State


1. Zamansal (zamanla ilgili) olaylar- bu olaylar ya bir gecikme süresi dolduğunda ya da mutlak bir
zamana ulaşıldığında meydana gelir. Örneğin, bir görev 10 milisaniyenin geçmesini beklemek için
Engellenmiş durumuna girebilir.

2. Senkronizasyon olayları- bu olaylar başka bir görevden veya kesintiden kaynaklanır. Örneğin, bir
görev bir kuyruğa veri gelmesini beklemek için Bloke durumuna girebilir. Senkronizasyon olayları
geniş bir olay türü yelpazesini kapsar.

The Suspended State


Askıya Alındı aynı zamanda Çalışmıyor'un bir alt durumudur. Askıda durumundaki görevler
zamanlayıcı tarafından kullanılamaz. Askıda durumuna girmenin tek yolu vTaskSuspend() API
işlevine yapılan bir çağrıdır ve çıkmanın tek yolu da vTaskResume() veya xTaskResumeFromISR()
API işlevlerine yapılan bir çağrıdır. Çoğu uygulama Askıya Alma durumunu kullanmaz.

The Ready State


Çalışmıyor durumunda olan ve Engellenmemiş veya Askıya Alınmamış olan görevlerin Hazır
durumunda olduğu söylenir. Çalışabilirler ve bu nedenle çalışmaya 'hazırdırlar', ancak şu anda
Çalışıyor durumunda değildirler.

Queue Management
'Kuyruklar' görevden göreve, görevden kesintiye ve kesintiden göreve iletişim mekanizması sağlar.

Bir kuyruk sonlu sayıda sabit boyutlu veri öğesi tutabilir[^8]. Bir kuyruğun tutabileceği maksimum
öğe sayısına 'uzunluk' denir. Her bir veri öğesinin hem uzunluğu hem de boyutu kuyruk
oluşturulduğunda ayarlanır.

The xQueueCreate() API Function

QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize );


uxQueueLength
Oluşturulmakta olan kuyruğun herhangi bir zamanda tutabileceği maksimum öğe sayısı.

uxItemSize
Kuyrukta saklanabilecek her bir veri öğesinin bayt cinsinden boyutu.
Dönüş değeri

NULL döndürülürse, yeterli yığın bellek olmadığı için kuyruk oluşturulamaz

NULL olmayan bir değer döndürülürse, kuyruk başarıyla oluşturulmuş demektir ve döndürülen
değer oluşturulan kuyruğun tanıtıcısıdır.

Queue Sets
birden fazla kuyruğu (queue) veya semaforu (semaphore) tek bir grup olarak ele almanızı sağlar. Bu
özellik, bir görev (task) tarafından birden fazla kuyruk veya semaforun herhangi birinden veri
alınmasını beklemek gerektiğinde kullanışlıdır.

Software Timer Management

Software Timer Callback Fonksiyonu

Callback fonksiyonu void tipinde tanımlanmış yani herhangi bir değer döndürmeyen, parametre
olarak TimerHandle_t tipinde bir değer alan aşağıdaki gibi bir fonksiyondur.

void ATimerCallback( TimerHandle_t xTimer );

Callback fonksiyonu olabildiğince kısa tutulmalı ve içerisinde vTaskDelay,xQueueReceive vb. gibi


taskı bloklayacak bir kod bulunmamalıdır.

Periyot: Software timer’ın periyodu timer başlatıldıktan callback fonksiyonu çağrılana kadar geçen
süredir. Timer tipine göre her periyot sonunda timer callback fonksiyonu yürütülür..

One-shot ve Auto-Reload Timer

İki tip yazılımsal timer vardır.

One-shot: Callback fonksiyonu sadece bir kez yürütülür. Manuel olarak tekrar başlatılmalıdır.
Kendini otomatik olarak tekrar başlatmaz.

Auto-reload: Timer callback fonksiyonu otomatik olarak yürütülür. Periyoda bağlı olarak kendini
tekrar başlatır. Yani callback fonksiyonu periyodik olarak yürütülür.

Yazılımsal Timer Durumları

Bir yazılımsal timer aşağıdaki iki durumdan birinde bulunabilir.


• Dormant(uykuda): Callback fonksiyonunun kodlarının yürütülmediği, timerın bir nevi
uykuda olduğu durumdur.
• Running: Bu durumda bulunan timer periyod süresini tamamladıktan sonra callback
fonksiyonunu çalıştırır.
Timer Daemon (Timer Service) Task
Bütün timer callback fonksiyonları daemon(deamon değil!) task adı verilen bir task
içerisinde yürütülür. Daemon task standart FreeRTOS taskıdır ve otomatik olarak scheduler
başlatıldığında oluşturulur. Daemon task’ın önceliği ve stack boyutu FreeRTOSConfig.h
dosyasındaki configTIMER_TASK_PRIORITY ve configTIMER_TASK_STACK_DEPTH
makrosuna göre belirlenir.

Timer Komut Kuyruğu


Yazılımsal timer fonksiyonları ,çağrıldığı tasktan daemon task a timer komut kuyruğu(timer
command queue) olarak isimlendirilen bir kuyruk ile komut gönderir. Bu kuyruk da scheduler
başlatıldığında otomatik tanımlanır.

Timer Oluşturma
FreeRTOS da timer oluşturmak için xTimerCreate() fonksiyonu kullanılır. Bu fonksiyon
TimerHandle_t tipinde bir handle döndürür. Başlangıçta software timer dormant state’de bulunur.
Yani oluşturulur oluşturulmaz hemen saymaya başlamaz. Timer scheduler dan önce veya sonra bir
task içerisinde oluşturulabilir.
TimerHandle_t xTimerCreate( const char * const pcTimerName,
TickType_t xTimerPeriodInTicks,
UBaseType_t uxAutoReload,
void * pvTimerID,
TimerCallbackFunction_t pxCallbackFunction );

pcTimerName: Timer a isim vermek için kullanılır. Bu parametre FreeRTOS tarafından


kullanılmaz , debug vb işlemler için kullanılabilir.
• xTimerPeriodlnTicks: Tick cinsinden timer periyodudur. pdMS_TO_TICKS() fonksiyonu
kullanılarak periyod milisaniye cinsinden ayarlanabilir.

• uxAutoReload: Bu parametre pdTRUE olarak girilirse timer auto-reload olarak çalışır.


Eğer pdFALSE olarak girilirse one-shot timer olarak çalışır.

• pvTimerID: Her yazılımsal timerın bir ID değeri vardır. Bu ID void pointer olarak
tanımlıdır ve yazılımcı tarafından herhangi bir amaç için kullanılabilir. ID genelde aynı
callback fonskiyonunu birden fazla timerın kullandığı uygulamalarda kullanışlıdır.

• pxCallbackFunction: Timer callback fonksiyonunun adı bu parametre ile girilir.

• Return Değeri: Döndürdüğü değer NULL ise timer oluşturmada hata olmuş demektir. Eğer
hatasız oluşturulmuş ise bir handle değeri döner.
Timer’ı Başlatma
Timer’ı baslatmak için xTimerStart() fonksiyonu kullanılabilir. Bu fonksiyon hali hazırda
oluşturulmuş ve dormant state de bulunan veya önceden başlatılmış(running state de bulunan) bir
timer’ı tekrar başlatır. Timer’ı durdurmak için ise xTimerStop() fonksiyonu kullanılır.
xTimerStart() fonksiyonu scheduler başlatılmadan önce de kullanılabilir fakat scheduler
başlamadan timer saymaya başlamaz.

Timer’ı interrupt fonksiyonu içinden başlatmak için xTimerStartFromISR() fonksiyonu


kullanılmalıdır

BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );

• xTimer: xTimerCreate fonskiyonunun döndürdüğü handle girilir.


• xTicksToWait: Timerın komut kuyruğu kullandığını söylemiştik. Bu parametre kuyruk dolu
ise ne kadar süre bekleneceğini belirtmek için kullanılır. Eğer xTimerStart fonksiyonu
scheduler başlatma fonksiyonundan önce kullanılırsa FreeRTOS bu parametreyi dikkate
almaz.
• Return Değeri: timer başlatma komutu kuyruğa başarılı bir şekilde gönderildi ise pdTRUE,
gönderilemedi ise pdFALSE değeri döndürür.

Interrupt Safe API


FreeRTOS'ta kesme servis rutinlerinden (ISR'ler) güvenli bir şekilde kullanılabilecek fonksiyonları
ifade eder. ISR'ler, sistemdeki olaylara hızlı yanıt vermek için kullanılan yüksek öncelikli kod
parçalarıdır. Bu nedenle, ISR'lerden yapılan işlerin hızlı ve kesintisiz olması önemlidir. FreeRTOS,
ISR'lerden güvenli bir şekilde çağrılabilecek bir dizi API sağlar.

Neden Interrupt Safe API?


ISR'ler ve normal görevler arasında paylaşılan veri yapılarının güvenli bir şekilde yönetilmesi
gerekir. ISR'ler, normal görevlerden daha yüksek önceliğe sahip olduklarından, kesintiye
uğramadan çalışmaları sağlanmalıdır. Bu yüzden, ISR'ler için özel olarak tasarlanmış API'ler
kullanmak, veri bütünlüğünü korumak ve sistemin kararlı çalışmasını sağlamak için önemlidir.

Binary Semaphore (ikili semafor), FreeRTOS ve diğer gerçek zamanlı işletim sistemlerinde (RTOS)
kullanılan basit bir senkronizasyon aracıdır. Bir binary semaphore, yalnızca iki durumu temsil
edebilir: alınmış (taken) veya serbest (available). Bu, onu özellikle bir görevin bir olayın
tamamlanmasını beklemesi veya bir kaynağın erişimini yönetmesi gereken durumlar için ideal hale
getirir.

Binary Semaphore Kullanım Alanları


• Görev Senkronizasyonu: Bir görev diğer bir görevin veya kesmenin tamamlanmasını
beklemek istediğinde kullanılır.
• Kaynak Yönetimi: Bir kaynağın yalnızca bir görev tarafından kullanılmasını sağlamak için
kullanılır.
Counting Semaphores, FreeRTOS ve diğer gerçek zamanlı işletim sistemlerinde (RTOS) kullanılan
başka bir senkronizasyon aracıdır. İkili semaforlardan farklı olarak, bir counting semaphore (sayısal
semafor) birden fazla görevin veya kaynağın erişimini yönetmek için kullanılabilir. Bu, özellikle
belirli sayıda kaynağın paylaşılması gereken durumlar için kullanışlıdır.

Counting Semaphore Kullanım Alanları


• Kaynak Yönetimi: Birden fazla aynı türde kaynağın paylaşımını yönetmek için kullanılır.
Örneğin, belirli sayıda belleğe sahip bir bellek havuzunun yönetimi.
• Görev Senkronizasyonu: Belirli sayıda görevin tamamlanmasını beklemek veya belirli
sayıda olayın gerçekleşmesini beklemek için kullanılır.

Mutex

Görevler kritik bölgede işlem yaparken diğer görevler bu bölgeye erişemez ve bu sayede veri
tutarlılığı korunur.
Her iki görev de Mutex'i almaya çalışır, almayı başardığında kritik bölgede işlem yapar ve ardından
Mutex'i serbest bırakır. Bu işlem, görevlerin sırayla kritik bölgede çalışmasını sağlar.
Sadece mutex’e sahip olan görev çalışabilir.

Priority inversion
Yüksek öncelikli bir görevin düşük öncelikli bir görev tarafından dolaylı olarak engellenmesi
durumudur.
Low, Medium, High görevleri olsun. Low ve High aynı mutex üzerinden resource control sağlansın.
Low kritik bölgeye gelmeden önce çalışmaya başlayıp mutex’e sahip. Kritk bölgeye girdikten sonra
High çalışmak için Low’un mutex’i bırakması gerekmekte. Bu nedenle High devre-dışı(bloklandı).
Medium çalışması için bir mutex’e ihtiyaç duymadığından, Low’un üzerinde olduğundan çalışmaya
başlar, Medium çalışmayı bitirene kadar, Low’un çalışması yarıda kesilir. Sonuç olarak High’ın
çalışması için önce Medium’un sonrada Low’un çalışmasını bitirmesi gerekir.
Bu durumu çözmek için "priority inheritance" (öncelik mirası) adlı bir mekanizma kullanılabilir. Bu
mekanizma, düşük öncelikli bir görevin (Low), yüksek öncelikli bir görev tarafından bekleniyorsa
(High), geçici olarak yüksek önceliğe sahip olmasını sağlar. Bu, düşük öncelikli görevin (Low)
kritik bölgeyi (Mutex) daha hızlı serbest bırakmasına ve yüksek öncelikli görevin (High) daha kısa
sürede devam etmesine olanak tanır.

Deadlock
İki veya daha fazla işlemin veya görevin, birbirlerinden bağımsız olarak tamamlanabilmeleri için
karşılıklı olarak birbirlerinin kilitli kaynaklarına erişmeye ihtiyaç duydukları bir durumdur. Bu,
işlemlerin birbirlerini beklemelerine ve dolayısıyla hiç kimsenin ilerleyememesine neden olur.
Deadlock’u engellemek için,
Bir işlem kaynakları tutmadan önce tüm gerekli kaynakları almalıdır.
Bir işlem, gerekli kaynakları alamazsa sahip olduğu kaynaklar elinden alınır.
Kaynaklar, önceden tanımlanmış bir sıra ile talep edilmelidir.

Recursive Mutexes
Bir thread'in aynı mutex'i birden fazla kez kilitlemesine izin veren bir mutex türüdür. Bu, thread'in
aynı mutex'i kilitledikten sonra, mutex'i serbest bırakmadan tekrar kilitlemek istemesi durumunda
deadlock oluşmasını önler.

Event Groups
Event Groups, FreeRTOS'un olayları yönetmek ve görevler arasında senkronizasyon sağlamak için
sunduğu bir mekanizmadır. Event Group'lar, bir veya daha fazla görev veya interrupt (kesme)
arasında iletişim kurmayı kolaylaştıran bir dizi bit (olay bayrağı) olarak düşünülebilir. Her bit,
belirli bir olayın gerçekleştiğini veya bir durumun aktif olduğunu temsil eder.
Event Groups, aşağıdaki durumlar için kullanılabilir:
• Birden fazla görevin aynı anda farklı olayları beklemesi.
• Bir görevin birden fazla olayın gerçekleşmesini beklemesi.
• Olayların bit düzeyinde senkronize edilmesi.

Event Group Oluşturma: Event Group'u oluşturmak için xEventGroupCreate() fonksiyonu


kullanılır.
• Event Bits Set Etme ve Temizleme:
• Olay bayraklarını set etmek için xEventGroupSetBits() fonksiyonu kullanılır.
• Olay bayraklarını temizlemek için xEventGroupClearBits() fonksiyonu kullanılır.

• Event Bits Bekleme: Bir veya daha fazla bitin set edilmesini beklemek için
xEventGroupWaitBits() fonksiyonu kullanılır.

• Event Bits Almak: Mevcut bitleri almak için xEventGroupGetBits() veya


xEventGroupGetBitsFromISR() fonksiyonu kullanılır.

Task Notification
Task bildirim mekanizması tasklar arasında doğrudan bir haberleşme imkanı sağlar. Yani
xSemaphoreCreate() fonksiyonu gibi bir fonksiyon ile herhangi bir nesne oluşturmaya gerek
kalmaz.
Eğer bir task bildirim gönderiyorsa “notification state” i “pending” , eğer bildirim alıyorsa “not-
pending” olarak ayarlanır.
Task bildirim mekanizması queue, event groups ve semaphore dan daha hızlıdır. RAM
kullanımı da diğerlerine göre daha azdır. Task bildirim mekanizması RAM de task başına 8 byte’lık
alan kaplar.
Task bildirim mekanizması hızlı ve daha az RAM kullanmasına rağmen bazı eksiklikleri
vardır.
• Birden fazla taskı harekete geçirme
Diğer nesnelere birden fazla task tarafından erişilebilirken(handle ile) task bildirimde ise
sadece bir taska bildirim gönderilebilir. Yani bir bildirim ile birden fazla task harekete
geçirilemez her taska ayrı ayrı bildirim gönderilmelidir.
• Buffer da birden fazla veri tutamama.
Queue kullanımında kuyrukta veriler depolanabiliyordu. Task bildirimde ise sadece bir adet
veri(notification value) tutulur.
• Gönderme tamamlanana kadar taskı bloklayamama.
Queue kullanırken eğer kuyruk dolu veya boş iken tasklar opsiyonel olarak
bloklanabiliyordu. Task bildirimde ise eğer task bildirimi zaten almışken tekrar bildirim
göndersek bile gönderen taskı bloklayamıyoruz.

Task Bildirim Fonksiyonları


Task bildirim mekanizması binary semaphore, counting semaphore , event grup ve hatta queue
yerine kullanılabilen çok güçlü bir FreeRTOS özelliğidir. Bu geniş kullanım özelliğine sahip task
bildirim mekanizmasında, bildirim göndermek için xTaskNotify() ve bildirim almak için
xTaskNotifyWait() fonksiyonu kullanılabilir. Bu fonksiyonların daha basit halleri olan
xTaskNotifyGive() ve ulTaskNotifyTake() fonksiyonları daha yaygın olarak kullanılır. Bu
fonksiyonlar diğerlerine göre daha basit olmasına rağmen esnek değildirler.

xTaskNotify() fonksiyonu, bir göreve belirli bir değeri bildirim olarak göndermek için
kullanılır.
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, // Bildirim gönderilecek görev
uint32_t ulValue, // Gönderilecek bildirim değeri
eNotifyAction eAction // Bildirim eylemi );

eNotifyAction Seçenekleri
• eNoAction: Bildirim değerini değiştirmez, sadece bildirimi tetikler.
• eSetBits: Gönderilen değerin bitlerini mevcut bildirim değeri ile birleştirir (OR işlemi).
• eIncrement: Bildirim değerini 1 artırır.
• eSetValueWithOverwrite: Mevcut bildirim değerini gönderilen değer ile değiştirir.
• eSetValueWithoutOverwrite: Bildirim değeri zaten ayarlanmışsa değiştirmez, yoksa
gönderilen değer ile değiştirir.
xTaskNotifyWait() fonksiyonu, bir görev için belirli bir bildirimi beklemek ve alındığında
bildirim değerini işlemek için kullanılır.
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, // Girişte temizlenecek bitler
uint32_t ulBitsToClearOnExit, // Çıkışta temizlenecek bitler
uint32_t *pulNotificationValue, // Alınan bildirim değeri
TickType_t xTicksToWait // Bekleme süresi );
xTaskNotifyGive() fonksiyonu, belirli bir göreve bildirim göndererek o görevin bildirim
değerini artırmak için kullanılır. Genellikle semafor benzeri bir işlev görür.
ulTaskNotifyTake() fonksiyonu, bir görevin bildirim almasını ve alınan bildirim değerini
tüketmesini sağlar. Bu fonksiyon, belirli bir süre boyunca bildirim bekler ve alındığında bildirim
değerini 0'a düşürür.

Design Pattern
Design patternleri sık karşılaşan hatalara genel bir çözümdür. Pattern olması için sorunun sık
yaşanması ve genellikle çözümü geniş uygulama alanlarına yayılması gerekir. Tek bir uygulama
alanında olursa da analiz pattern’i olur.
Design Patternleri 4 önemli yapısı vardır.
İsmi, Amacı, Çözümü, Ve Sonuçları.
İsmi, pattern’e referans olur,
Amaç, problem bağlamını ve modelin optimize etmeyi amaçladığı QoS özelliklerini sağlar. Amaç,
kalıbın özellikle uygun olabileceği sorun bağlamlarının türlerini tanımlar.
Çözüm, pattern’in kendisi çözüm zaten.
Sonuçları, patternin kullanımı sonucu oluşan artılar ve eksiler.
Desen İsmi bize iki şey kazandırır. Birincisi, desene açık bir şekilde referans vermemizi sağlar, açık
bir şekilde, ayrıntılar mevcut ancak belirtilmemiş olarak. İkinci olarak, tasarımlarımız hakkında
konuşmak için bize daha soyut bir kelime dağarcığı sağlar. "Sistem, bir Proxy Kalıbı ile bir dizi
işlemciye dağıtılmış Döngüsel Yönetici Eşzamanlılığına sahip Homojen Kanal yedekli bir mimari
kullanır" ifadesi, sistemin genel yapısı hakkında çok fazla bilgi içerir çünkü mimariyi bu kalıplar
açısından tartışabiliriz.
Desenin amacı, desenin uygulanabilir olması için gereken temel problem bağlamlarını ve desenin
hangi tasarım kriterlerini optimize etmeye çalıştığını tanımlar. Bu bölüm, kalıbın hangi durumlarda
uygun olduğunu ve hangi durumlarda kaçınılması gerektiğini belirtir.
Çözüm, elbette, modelin kendisinin yapısını ve davranışını belirler. Desenin unsurlarını ve bunların
desen bağlamındaki rollerini tanımlar. Bu desen çözümü, desen örneklemesi olarak bilinen bir
süreçle tasarımınıza entegre edilir.
Sonuçlar önemlidir çünkü bir modeli diğerine tercih ettiğimizde her zaman dengeleme yaparız.
Etkili bir şekilde uygulamak için modelin artılarını ve eksilerini anlamalıyız. Artılar ve eksiler
genellikle bazı tasarım özelliklerinin iyileştirilmesi veya bozulması ve bu sonuçların geçerli olduğu
problem bağlamlarının olası bir detaylandırılması şeklinde ifade edilir.

Her desen aynı temel sunum tarzını izler ve dokuz temel unsurla sunulur:
Özet
Özet, ele aldığı sorunlara, çözüm yapısına ve temel sonuçlara genel bir bakış da dahil olmak üzere
modele ve neden ilgilenebileceğinize dair genel bir bakış sunar.
Problem
Bu bölümde problem bağlamı ve kalıp tarafından sağlanan optimizasyonlar tartışılmaktadır.
Uygulanabilirlik
Bu bölümde, modelin uygulanabilir olması için gereken koşulların bir listesi verilmektedir.
Desen yapısı
Kalıp yapısı, kalıp içindeki yapısal unsurları, bunların rollerini ve ilişkilerini gösterir. Her bir model
bir UML sınıf diyagramı kullanılarak gösterilecektir.
İşbirliği rol tanımları
Bu bölümde her bir yapısal unsurun modelde oynadığı rol ve sorumlulukları ayrıntılı olarak
açıklanmaktadır.
Sonuçlar
Sonuçlar, model tanımının önemli bir yönüdür. Bu bölüm, modelin kullanılmasının hem faydalarını
hem de maliyetlerini tanımlar.
Uygulama stratejileri
Kalıplar farklı şekillerde uygulanabilir. Bu bölümde bazı uygulama alternatifleri tartışılmaktadır.
İlgili desenler
Bu bölüm, muhtemelen farklı uygulanabilirlik kriterleri ve sonuçları ile benzer sorunları ele alan
kitaptaki diğer modellere referanslar sağlar.
Örnek
Her kalıp bir örnekle gösterilecektir. Örnekle birlikte hem bir UML diyagramı hem de kaynak kodu
verilecektir.
Muhtemelen gömülü sistemlerin en ayırt edici özelliği donanıma doğrudan erişmek zorunda
olmalarıdır. Gömülü bir sistemin tüm amacı, yazılımın belirli bir tür hizmet sağlayan ve donanıma
erişmeyi gerektiren bir “akıllı cihaz” içine gömülü olmasıdır. Genel olarak, yazılıma erişilebilen
donanımlar altyapı, iletişim, sensörler ve aktüatörler olmak üzere dört gruba ayrılabilir.

Altyapı donanımı, yazılımın üzerinde çalıştığı bilgi işlem altyapısını ve cihazları ifade eder. Bu
sadece CPU ve belleği değil, aynı zamanda depolama aygıtlarını, zamanlayıcıları, giriş aygıtlarını
(klavyeler, düğmeler ve butonlar gibi), kullanıcı çıkış aygıtlarını (yazıcılar, ekranlar ve ışıklar),
bağlantı noktalarını ve kesmeleri de içerir. Bu donanımların çoğu özellikle uygulamaya özel
değildir ve aynı anakart üzerinde, yüksek hızlı erişim bağlantılarına sahip ek kartlarda veya ortak
bir arka paneli paylaşan diğer kartlarda bulunabilir.

İletişim donanımı, standart (gömülü olmayan) bilgisayarlar, diğer gömülü sistemler, sensörler ve
aktüatörler gibi farklı bilgi işlem cihazları arasındaki iletişimi kolaylaştırmak için kullanılan
donanımı ifade eder. Bu genellikle kablolu veya kablosuz iletişim alt sistemleri anlamına gelir.

Son olarak, fiziksel evreni izleyen veya manipüle eden cihazlarımız var - bunlar sensörler ve
aktüatörlerdir. Sensörler, bir kalp atışının hızı, bir uçağın konumu, bir nesnenin kütlesi veya bir
kimyasalın konsantrasyonu gibi fiziksel olayların durumunu izlemek için elektronik, mekanik veya
kimyasal araçlar kullanır. Öte yandan aktüatörler, bazı gerçek dünya unsurlarının fiziksel durumunu
değiştirir. Tipik aktüatörler motorlar, ısıtıcılar, jeneratörler, pompalar ve anahtarlardır.

Hardware Proxy Pattern, donanım kaynaklarına erişim ve kontrol için kullanılan bir yazılım tasarım
desenidir. Bu desen, donanım kaynaklarına doğrudan erişimi sınırlayarak, araya bir proxy (vekil)
koyar ve bu sayede donanım kaynaklarının güvenli, kontrollü ve optimize edilmiş bir şekilde
kullanılmasını sağlar. İşte bu desenin temel bileşenleri ve nasıl çalıştığı hakkında detaylı bir
açıklama:

Temel Bileşenler
1. Proxy (Vekil) Nesne:
• Donanım kaynağına erişimi kontrol eden ve yöneten nesnedir.
• Donanım kaynağı ile istemci arasındaki etkileşimi sağlar.
• Gerekli durumlarda erişim kontrolü, önbellekleme, ve güvenlik işlemlerini
gerçekleştirir.
2. Gerçek Donanım Kaynağı:
• Proxy tarafından yönetilen ve kontrol edilen fiziksel donanım kaynağıdır (örneğin,
bir sensör, motor, veya başka bir cihaz).
3. İstemci:
• Donanım kaynağını kullanmak isteyen uygulama veya bileşendir.
• Donanım kaynağına doğrudan erişmek yerine, proxy aracılığıyla erişim sağlar.

Nasıl Çalışır?
1. İstemci, Proxy'ye Talepte Bulunur:
• İstemci, donanım kaynağına erişmek için proxy nesnesine bir istek gönderir.
2. Proxy, İsteği İşler:
• Proxy, istemciden gelen isteği alır ve işlemek için gerekli kontrolleri yapar (örneğin,
erişim izni, önbellekleme durumu).
• Gerekli kontroller yapıldıktan sonra, isteği gerçek donanım kaynağına yönlendirir.
3. Donanım Kaynağı İle İletişim:
• Proxy, donanım kaynağı ile iletişim kurar ve istemcinin talebini yerine getirir.
• Donanım kaynağından gelen yanıtı alır ve gerektiğinde işleyerek istemciye iletir.

Avantajları
• Güvenlik: Proxy, donanım kaynağına erişimi kontrol ederek yetkisiz erişimleri
engelleyebilir.
• Kontrol ve İzleme: Proxy, donanım kaynaklarının kullanımını izleyebilir ve yönetebilir.
• Performans: Önceden sık kullanılan verileri önbelleğe alarak performansı artırabilir.
• Soyutlama: Donanım kaynağının karmaşıklığını soyutlayarak istemciyi bu karmaşıklıktan
korur.

Bir akıllı ev sisteminde, sıcaklık sensörleri ve ısıtma sistemi gibi donanım bileşenleri bulunur. Bu
bileşenlere erişim ve kontrol, bir proxy nesnesi aracılığıyla yapılır. Örneğin, bir mobil uygulama
evin sıcaklığını kontrol etmek istediğinde, doğrudan sıcaklık sensörüne veya ısıtma sistemine
erişmez. Bunun yerine, proxy nesnesine bir istek gönderir. Proxy, bu isteği işler, gerekli güvenlik
kontrollerini yapar ve ardından gerçek donanım bileşenine erişimi sağlar. Bu sayede, sistem güvenli
ve verimli bir şekilde çalışır.
Bu şekilde, Hardware Proxy Pattern donanım kaynaklarının yönetiminde önemli bir rol oynar ve bu
kaynakların güvenli, kontrollü ve optimize edilmiş bir şekilde kullanılmasını sağlar.

You might also like