Kuyruk Ynetimi Kuyruklar bir greve grev grevkesme ve
Kuyruk Yönetimi • ‘Kuyruklar’, bir göreve görev, görev-kesme ve göreve kesme sağlayan iletişim mekanizması sağlar. • Kapsam • • • Kuyruk nasıl oluşturulur? Bir sıra, içerdiği verileri nasıl yönetir. Bir sıraya nasıl veri gönderilir. Kuyruktan veri alma. Kuyrukta engellenmesi ne demektir. Birden fazla kuyrukta nasıl engellenir. Kuyrukta verilerin nasıl yazılacağı. Sıra nasıl temizlenir. Bir sıradan yazarken ve okurken görev öncelikleri etkisi.
Kuyruğun karakteristikleri • Veri depolama • Kuyruk, sınırlı sayıda sabit boyutlu veri öğelerini tutabilir. Bir kuyruğun tutabileceği maksimum öğe sayısına «uzunluk» denir. Her bir veri öğesinin uzunluğu ve boyutu, kuyruk oluşturulduğunda ayarlanır. • Kuyruklar normalde sıraya göre kuyruğa (kuyruk) yazılan ve kuyrğun önünden (başından) kaldırılan İlk Giren İlk Çıkar (FIFO) tamponları olarak kullanılır. Bir FIFO olarak kullanılan bir kuyruğa yazılan ve okunan verileri gösterir. Bir kuyruğun önüne yazmak ve kuyruğun önünde bulunan verilerin üzerine yazmak da mümkündür. Görev A ve Görev B'nin iletişim kurmasını sağlamak için bir kuyruk oluşturulur. Kuyruk maksimum 5 tamsayı tutabilir. Kuyruk oluşturulduğunda, herhangi bir değer içermiyor, yani boş.
Görev A, yerel bir değişkenin değerini kuyruğun arkasına yazar (gönderir). Kuyruk önceden boş olduğu için, kuyrukdaki değer artık kuyrukdaki tek öğe ve bu nedenle hem kuyruğun arkasındaki değer hem de kuyruğun önündeki değerdir. Görev A, yerel değişkeninin değerini tekrar sıraya yazmadan önce değiştirir. Sıra, artık kuyruğa yazılan her iki değerin kopyalarını içerir. Yazılan ilk değer, sıranın önünde kalır, sıranın sonunda yeni değer eklenir. Kuyrukta kalan üç boş alan var.
Görev B, sıradan farklı bir değişkene okur (alır). Görev B tarafından alınan değer, sıranın başındaki değerdir; bu, Görev A'nın sıraya yazdığı ilk değerdir Görev B, bir öğeyi kaldırdı, yalnızca sıradaki Görev A tarafından yazılmış ikinci değeri bıraktı. Bu, sıradan tekrar okursa Görev B'nin alacağı değerdir. Sıra artık dört boş alana sahip.
Kuyruk davranışının gerçekleştirilebildiği iki yol vardır: 1. Kopya ile kuyruk • Kopya ile kuyruğa koyma, kuyruğa gönderilen verilerin byte için kuyruğa kopyalandığı anlamına gelir. 2. Referans ile kuyruk • Referans ile kuyruğa koyma, kuyruk, verilerin kendisine değil, yalnızca kuyruğa gönderilen verilere ilişkin işaretçileri tutması anlamına gelir.
• Free. RTOS, kopya yöntemiyle kuyruk kullanır. Kopya ile kuyruklama, aynı anda referans olarak kuyruğa göre kullanmaktan çok daha güçlü ve daha basittir: • Yığın değişkeni, bildirilmiş olduğu işlevden sonra değişmeyecek olsa bile, doğrudan bir kuyruğa gönderilebilir. • Veriler, önce verileri tutmak için bir arabellek tahsis edilmeden ve sonra da tahsis edilen ara belleğe kopyalanmadan bir kuyruğa gönderilebilir. • Gönderme görevi hemen kuyruğa gönderilen değişkeni veya arabelleği yeniden kullanabilir. • Gönderme görevi ve alma görevi tamamen ayrıştırılmıştır; uygulama tasarımcısı, hangi verilere sahip olduğunu veya verilerin serbest bırakılmasından hangi işin sorumlu olduğunu düşünmek zorunda değildir. • Kopya ile kuyruğa koyma, kuyruğun referans olarak sıraya alınmasını da engellemez. Örneğin, kuyruğa yerleştirilen verinin boyutu, verilerin kuyruğa kopyalanmasını imkansız kılarsa, veriye bir işaretçi bunun yerine kuyruğa kopyalanabilir. • RTOS, verileri depolamak için kullanılan belleği ayırmak için tüm sorumluluğu üstlenir. • Bellek korumalı bir sistemde, bir görevin erişebileceği RAM kısıtlanır. Bu durumda, referans ile kuyruğa alma, sadece gönderme ve alma görevi, verilerin depolandığı RAM'e erişebiliyorsa kullanılabilir. Kopya ile kuyruğa koyma, bu kısıtlamayı dayamaz; çekirdek her zaman tam ayrıcalıklarla çalışır ve bellek koruma sınırları boyunca veri iletmek için kuyruğa izin verir.
• Çoklu Görevlere Göre Erişim • Kuyruklar, kendi varlıkları ile ilgili herhangi bir görev veya ISR tarafından erişilebilen nesnelerdir. Herhangi bir sayıda görev aynı kuyruğa yazabilir ve herhangi bir sayıda görev aynı kuyruktan okuyabilir. Pratikte, bir kuyruğun birden fazla yazara sahip olması çok yaygındır, ancak bir kuyruk için birden fazla okuyucunun olması daha az yaygındır. • Kuyruk Okumalarını Engelleme • Bir görev, bir kuyruktan okumayı denediğinde, isteğe bağlı olarak bir "blok" süre belirtebilir. Bu, kuyruk zaten boş olması durumunda, sıraya göre verilerinin beklenmesi için görevin Bloke edilmiş durumda tutulacağı zamandır. Engellenen durumdaki, bir kuyruğun kullanılabilir hale gelmesini bekleyen bir görev, başka bir görev veya kesinti, verileri kuyruğa yerleştirdiğinde otomatik olarak Hazır durumuna geçirilir. Veriler mevcut duruma gelmeden önce belirtilen blok süresinin dolması durumunda, görev aynı zamanda Engellenen durumdan Hazır durumuna otomatik olarak taşınır. Kuyruklar birden fazla okuyucuya sahip olabilir, bu nedenle tek bir kuyruğun veri beklerken birden fazla görevi engellemesi mümkündür. Bu durumda, veri mevcut olduğunda sadece bir görev engellenecektir. Engeli olmayan görev, her zaman veri bekleyen en yüksek öncelikli görev olacaktır. Engellenen görevler eşit önceliğe sahipse, verileri en uzun süre bekleyen görev engellenir. • Kuyruk Yazmalarını Engelleme • Bir kuyruktan okurken olduğu gibi, bir görev isteğe bağlı olarak bir sıraya yazarken bir blok zamanı belirtebilir. Bu durumda blok süresi, kuyruğun zaten dolu olması durumunda, alanın kullanılabilir durumda kalmasını beklemek için Engellenen durumda tutulması gereken maksimum süredir. Kuyruklar birden fazla yazara sahip olabilir, bu yüzden tam bir kuyrukta, bir gönderme işlemini tamamlamak için bekleyen birden fazla görev engellenebilir. Bu durumda, kuyruktaki alan kullanılabilir olduğunda yalnızca bir görev engellenir. Engeli olmayan görev, her zaman alan için bekleyen en yüksek öncelikli görev olacaktır. Engellenen görevler eşit önceliğe sahipse, alanın en uzun süredir beklediği görev engellenir. • Birden Fazla Kuyruğu Engelleme • Kuyruklar kümeler halinde gruplandırılabilir, böylece bir görev kümedeki kuyruklardan herhangi birinde kullanılabilir hale gelmesini beklemek için Engellenen duruma girmesine izin verir.
x. Queue. Create() API Function • Queue. Handle_t x. Queue. Create( UBase. Type_t ux. Queue. Length, UBase. Type_t ux. Item. Size ); ux. Queue. Length Oluşturulacak kuyruğun maksimum sayısı, herhangi bir zamanda tutabilir. ux. Item. Size Kuyrukta depolanabilecek her veri öğesinin bayt cinsinden boyutu. Return Value NULL döndürülürse, kuyruk veri yapıları ve depolama alanı ayırmak için Free. RTOS için yeterli yığın bellek var olduğundan, sıra oluşturulamıyor. Döndürülen bir NULL olmayan değer, kuyruğun başarıyla oluşturulduğunu gösterir. Döndürülen değer, oluşturulan kuyruğun tanıtıcısı olarak saklanmalıdır.
x. Queue. Send. To. Back() ve Queue. Send. To. Front() API Functions • x. Queue. Send. To. Back (), bir kuyruğun arkasına (kuyruğuna) veri göndermek için kullanılır ve x. Queue. Send. To. Front (), bir kuyruğun önüne (başına) veri göndermek için kullanılır. • Base. Type_t x. Queue. Send. To. Front( Queue. Handle_t x. Queue, const void * pv. Item. To. Queue, Tick. Type_t x. Ticks. To. Wait ); • Base. Type_t x. Queue. Send. To. Back( Queue. Handle_t x. Queue, const void * pv. Item. To. Queue, Tick. Type_t x. Ticks. To. Wait ); x. Queue pv. Item. To. Queue x. Ticks. To. Wait Verilerin gönderildiği kuyruğun tanıtıcısı. Kuyruk tanımı, çağrı oluşturmak için kullanılan x. Queue. Create () öğesine döndürüldü. Kuyruğa kopyalanacak verilere işaretçi. Kuyrukun tutabileceği her bir öğenin boyutu, sıra oluşturulduğunda ayarlanır; bu nedenle, bu çok sayıda bayt, pv. Item. To. Queue öğesinden kuyruk depolama alanına kopyalanır. Kuyrukta, alanın zaten dolu olması için, alanın kullanılabilir durumda kalmasını beklemek üzere, Maksimum Duruş süresi içinde kalması gereken süre. XTicks. To. Wait sıfırsa ve kuyruk zaten doluysa, x. Queue. Send. To. Front () ve x. Queue. Send. To. Back () öğesi hemen döner. Blok süresi işaretçi periyotlarında belirtilir, böylece temsil ettiği mutlak süre işaret frekansına bağlıdır. Makro pd. MS_TO_TICKS (), milisaniye cinsinden belirtilen süreleri işaretler içinde belirtilen bir zamana dönüştürmek için kullanılabilir.
x. Queue. Receive() API Function • x. Queue. Receive (), bir kuyrudan bir öğeyi almak (okumak) için kullanılır. Alınan öğe kuyruktan kaldırılır. Note: interrupt içinden çağırılmaz. Base. Type_t x. Queue. Receive( Queue. Handle_t x. Queue, void * const pv. Buffer, Tick. Type_t x. Ticks. To. Wait ); x. Queue Verilerin alındığı kuyruğu taşıyıcısı (okunur). Kuyruk taşıyıcısıı, çağrı oluşturmak için kullanılan x. Queue. Create () öğesine döndürüldü. pv. Buffer Alınan verilerin kopyalanacağı belleğe işaretçi. Kuyruk oluşturulduğunda, kuyruktaki her veri öğesinin boyutu ayarlanır. Pv. Buffer tarafından işaret edilen bellek, çok sayıda bayt tutmak için yeterince büyük olmalıdır. x. Ticks. To. Wait Verilerin kuyruğa boş olması durumunda, verilerin kuyruğa girmesini beklemek için, Görevlerin Engellenen durumunda kalması gereken maksimum süredir. XTicks. To. Wait sıfır ise, kuyruk zaten boşsa, x. Queue. Receive () hemen döner. Blok süresi işaret periyotlarında belirtilir, böylece temsil ettiği mutlak süre işaret frekansına bağlıdır. Makro pd. MS_TO_TICKS (), milisaniye cinsinden belirtilen süreleri işaretler içinde belirtilen bir zamana dönüştürmek için kullanılabilir.
ux. Queue. Messages. Waiting() API Function • ux. Queue. Messages. Waiting (), şu anda bir kuyrukta bulunan öğelerin sayısını sorgulamak için kullanılır. • UBase. Type_t ux. Queue. Messages. Waiting( Queue. Handle_t x. Queue ); x. Queue Returned value Kuyruk taşıyıcısı. 0 ise kuyruk boş yada kuyruktaki öğe sayısını döndürür.
Birden Fazla Kaynaktan Veri Alma • Free. RTOS tasarımlarında birden fazla kaynaktan veri alma görevi yaygındır. Alma görevinin, verilerin nasıl işleneceğini belirlemek için verilerin nereden geldiğini bilmesi gerekir. Kolay bir tasarım çözümü, hem verilerin değeri hem de verilerin kaynağıyla yapıları aktarmak için tek bir kuyruk kullanmaktır.
- Slides: 12