Kendimize ait RTOS Yazımı, Multitasking hakkında

Başlatan bunalmis, 08 Ekim 2011, 11:35:31

z

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

#61
RTOS konusunda kafam çok karışmıştı, okuduğum dokümanlar ve sorduğum sorulara aldığım cevaplar sonucunda RTOS cekirdeginin asagidaki gibi davranmasi gerektigine karar verdim.

Uygulama programının bileşenlerini küçük fonksiyonlar (tasklar) olarak yazacağız. (Klavyeyi tara, Ekranda göster, hesapla vs)

- Bir tablo oluşturup tabloda bu fonksiyonların her birine öncelik sıralaması atayacağız. Bu tablo, taskın uyuyup uyumadığı, beklemede olup olmadığı gibi bilgileri de saklayacak.

- Çalışan bir fonksiyon, şu durumlarda uykuya geçecek;

Sleep komutu işletirse,
Delay komutu işletirse,
I/O işlemi yapmak isterse,
Kilitlenebilir bir değişkenin kilidinin kitli olduğunu öğrendiğinde,
Görev sıralayıcı, isterse.

- Bir fonksiyon (task) daha yüksek öncelikli bir fonksiyon tarafından yasaklı yada serbest hale getirilebilecek

--------------------------------------------------------------------------------------------------

Görev sıralayıcı, en yüksek öncelikli task varsa onu,  yok eşit öncelikli tasklar varsa hakkaniyetli olmak şartıyla en çok hakeden taskı koşturacak.

Task yukarıda anlatılan sebeplerle uyutulmadığı sürece çalışacak.

Bir task uyuduğunda;

Görev sıralayıcı, sırada bekleyen tasklardan çalışmayı hak eden taskı seçecek ve bu kez onu çalıştıracak.

--------------------------------------------------------------------------------------------------

Bir taskı uyumaya zorlayan neden ortadan kalkarsa ya da interrupt ya da bir event oluşursa, o an çalışmakta olan taskın önceliği, uyuma nedeni ortadan kalkmış taskın önceliğinden daha düşükse, çalışmakta olan task beklemeye alınacak daha önce uyumaya zorlanmış öncelikli taskımız kaldığı yerden çalışmaya başlayacak.

Bu durumda RTOS uygulama programının (kullanıcı programının) tasarımı, lojik devrelerin senkron lojik tasarımıyla büyük benzerlikler göstermektedir. RTOS çekirdeği de senkron lojik tasarımındaki kuralları işleten yazılım olacak demektir ki yapacağı işler durum geçişlerini tespit etmek, çıkış tablolarını elde etmektir

Nasıl senkron lojik devre tasarımlarında her bir olay (girişlerdeki yada durumlardaki değişiklik) bir durumdan bir diğer duruma geçmeye neden oluyorsa RTOS'da da bir taskdan bir diğer taska geçiş benzer mekanizmalarla sağlanacak. Burada en buyuk is gorev siralayiciya dusmekte

Nasıl senkron lojik tasarımda ölü bölgeler oluşmus ve çalışan sistem o durumlardan birine düştügunde sistem bloke oluyorsa  aynı durum RTOS uygulamasında da var.

RTOS denen problem, yukarıdaki gibi tanımlanırsa daha etkili CPU gücünü olması gereken fonksiyonda yoğunlaştıran gerektiği yerde bir o fonksiyonu terk edip bir başka fonksina yoğunlaşan yapı kurulmuş olacaktır.

-----------------------------------

RTOS, karmaşık bir programın küçük ve kolay anlaşılır kodlar şekilde yazılmasına imkan tanır. Fakat konvansiyonel yöntemlerle yazılmış bir programa kıyasla, RTOS da yazılmış program daha yavaş çalışacaktır. (Ana programa ilave olarak çekirdek kodlarının da işletimini gerekiyor) Fakat buna istisna olacak durumlar da çıkabilir.

RTOS uygulaması klasik usullerle yazılmış kodlara kıyasla daha fazla RAM istese ve daha yavaş çalışsa dahi, anlaşılırlık, bakım kolaylığı gibi sebeplerden ötürü RTOS tercih sebebidir.


Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

#62
Üstteki yazımda;

"Görev sıralayıcı, en yüksek öncelikli task varsa onu,  yok eşit öncelikli tasklar varsa hakkaniyetli olmak şartıyla en çok hakeden taskı koşturacak"
şeklinde bir ifade kullanmıştım.
Şu anda Hakkaniyetli olmak şartıyla çalışmayı en çok hakeden taskın bulunması probleminin çözümünde takıldım kaldım.

Geçmişte bir takım olaylar gelişti, Bazı düşük öncelikli tasklar durduruldu araya yüksek öncelikli tasklar girdi ve şu anda  geçmişte yarıda kesilen düşük öncelikli taskları kaldıkları yerden çalıştırma aşamasına geldik. Elimizde tek bir yarıda kesilmiş task olsa işimiz çok kolay olurdu.

Diyelimki aynı öncelikli tasklardan birincisi Delay komutu işletti, sıra 2. taska geldi, bu da delay işletti ..... n'ci task da delay komutu işletti bu esnada araya yüksek öncelikli tasklar girdi onların işlemi yapıldı vs vs ve nihayetinde geçmişte de Delay çalıştırmış tüm taskların delay süreleri tam da bu anda bitmiş olsun.

Şimdi, n tane task içinden çalışmayı en çok hakeden taskı arayıp bulmamız lazım.

Elimde her bir taskın seceresini tutan blok var. Hangi task ne durumda, önceliği ne, şu ana kadar kaç kez çalıştı, ne zaman beklemeye alınmıştı vs vs vs

Tüm bu durumları değerlendirip çalışması gereken taskı adil bir şekilde bulacak yazılım RTOS'un kalbi niteliğinde.

Ancak bu yazılımın uzun zamanda çalışmasını gerektirecek kodlar içermesi RTOS'un kalitesini düşürür.

-------------------------------------------------------------------

Şimdi hangi task çalışmalı sorusunun cevabını arayan program parçacığı konusunda ne düşünüyorsunuz?

Nasıl bir algortima kurmalıyız?



Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Andromeda

bu noktaya gelmiş biri için algoritma zor olmamalı...
görevlerin önceliği belli olduğuna göre...
yanılıyormuyum..?
" Tanrı, iradesini hakim kılmak için yeryüzündeki iyi insanları kullanır, yeryüzündeki kötü insanlar ise kendi iradelerini hakim kılmak için Tanrı'yı kullanırlar." ..." Tanrı'dan mesaj gelmiyor, biz Tanrı'ya mesaj gönderiyoruz"

z

#64
Buraya kadar olan kisimlar cerez niteliginde ve asil problem bence bu. (Belki de bu kisimdaki hakkaniyet'e gereginden fazla onem veriyorum ve bu konuda hataliyim)

Gecmiste durdurulmus fakat simdi calismaya hazir N tane ayni oncelikte task olsun.

Amacimiz bu tasklardan birisini secip calistirmak.

Oncelik dersen hepsi ayni oncelikte. Bazilari su ana kadar 3 kez calismis bazilari 5 kez bazilari 10 kez.

Yazik su task sadece 3 kere calismis bunu calistiralim desek bakiyoruz 10 kez calisan task da cok onceden delay komutuna baslamis zamani dolmus.

Kafam burada karisti iste.

Bir de şöyle bir durum var.

Kesilen tasklar stackda bayağı bir register saklanmasına neden oluyor. Çok sayıda task varsa stağı şişirmek de tehlikeli.
Amaçlardan birisi de stağı olabildiğince boş tutmak olmalı.

Hangi task ne zaman beklemeye alındı bilgisi de kritik. 1ms lik timer ticklerinde 32 bitlik bir değişken 50 gün geçmişi saklayabilir. Bu kadar da abartma denilebilir.
Bir sistem 50 günde muhakkak kapatılıp açılır dersek anlarım.


Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Andromeda

" Tanrı, iradesini hakim kılmak için yeryüzündeki iyi insanları kullanır, yeryüzündeki kötü insanlar ise kendi iradelerini hakim kılmak için Tanrı'yı kullanırlar." ..." Tanrı'dan mesaj gelmiyor, biz Tanrı'ya mesaj gönderiyoruz"

z

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Andromeda

rtos nedir yazılarında diyor ya; otomobil, uzay gemisi, özel cihazlar..
bu durumda her görevin önceliği cihazın çalışması ile ilgili diye düşündüm..
" Tanrı, iradesini hakim kılmak için yeryüzündeki iyi insanları kullanır, yeryüzündeki kötü insanlar ise kendi iradelerini hakim kılmak için Tanrı'yı kullanırlar." ..." Tanrı'dan mesaj gelmiyor, biz Tanrı'ya mesaj gönderiyoruz"

z

RTOS kullanmak icin illaki otomobil yada ucakla ugrasmak gerekmiyor.

Her hangi bir programi ya klasik usulde ya da RTOS uzerinde kosacak sekilde yazarsin.
 
Bu basit bir led yakip sondurme programi dahi  olabilir.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

vsalma

@bunalmis hocam os dersinden hatırladığım kadarıyla bu konuda çok değişik yaklaşımlar mevcuttu. Doğrusu hangisi bilmiyorum. Seçenek sunup uygulamaya göre konfigure edilmeli olabilir.
Mesela en çok bekleyen taska öncelik verilebilir. veya önceki çalışma durumlarından istatistikler tutulup işlemciyi en az tutup sonra bırakan taska öncelik verilebilir.  Bu söylediklerim muhtemelen PC lerimizde çalışan OS lar için. Ticari RTOS ların yöntemini bilmiyorum. Ben de merak ettim. 

z

#70
Gerbay

preemptive calisiyoruz. Task0 en yuksek oncelikli, digerleri daha dusuk ve hepsi ayni oncelik seviyesinde.

Task0 calismaya basladi fakat bir noktada donanimdan bir sey beklemeye baslasin. Task1 isletilecek,
Task1 osdelay isletsin. Task2 isletilecek,
Task2 osdelay isletsin. Task3 isletilecek,
Task3 osdelay isletsin. Task4 isletilecek,
Task4 osdelay isletsin. Taskn isletilecek...

Burada  Donanim veriyi hazir etsin.
Task0 calisti ve isi bitti diyelim.

Tam bu anda Task1,Task2,Task3,Task4 delay sureleri de bitmis olsun.

Task1,Task2,Task3,Task4 den hangisine geri donecegiz?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Sirayla tasklari calistiran projem yarim kalmisti projeyi bu gunlerde tekrardan ele aliyorum.

Acik kaynak kodlari Keilde denemek isterseniz link: http://www.cncdesigner.com/wordpress/?p=3102

Programin yaptigi is Tasklari sira ile calistirmaktan ibaret.

System Tick conter her 1 ms de int uretiyor ve calisan task yarida kesiliyor bir sonraki yarida kalmis task isletilmeye baslaniyor ve bu boyle devam ediyor.

Aklima bir sorun geldi ve simdi nasil cozecegimi arastiriyorum.

Normalde isler ornegin 2 task icin asagidaki gibi yuruyor.

Task1 -->SystemTickInt-->Task2-->SystemTickInt-->Task1

Sorun surada olusacak;

Task1 -->Xint--->SystemTickInt-->Task2-->SystemTickInt-->Yarim kalmisXint-->Task1

Daha acik yazacak olursak;

Task1 isletirlirken herhangi bir X interrupt harekete gecsin.
Bu durumda Task1 yarida birakilir ve ilgili interrup rutini isletilmeye baslar.
int rutini islerken daha hala int rutini icindeyken System Tick int gelirse int rutinimiz de yarida birakilir ve system Tick int rutinine atlanir.
System Tick bir sonraki Task olan Task2 parametrelerini islemci registerlerine yukler ve Task2 ye gecisi yaptirir.

Task2 tekrardan System Tick int ile kesilince bu kez Task1 parametreleri islemci registerlerine yuklenir ve Task1 kosturulur.

Burada Task1 aslinda X interrupt ile kesildiginden yarim kalmis olan Xinterrupt rutinine devam edilir ve bitiminde yarida kalmis Task1 rutini isler.

Bu bir sorundur. Cunku cevaplanmaya baslamis herhangi bir int, task gecisi nedeniyle yarida birakilmis ve ancak tum tasklar isledikten sonra interrupt rutini calismasina devam edecektir.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Hocam ama bahsettigim sorunumda soyle bir durum var. Task islerken int gelirse bu interrupt islenirken bunu da Timer Tick int keserse (Timer Tick bir exception) bu durumda yazdigim cekirdek kodlar yarim kalmis interrupti task gecisi oldugu icin tamamlamayacak. 

Ustelik Stack alani switch edildiginden inta girildiginde yapilan context saving islemi dikkate alinmadigindan (cekirdegimdeki bug) cekirdek cokuyor. Neyse sorunu tespit ettim bir sekilde cozerim.

Sorunun cozumu icin artistik bir kod yazmam gerekecek.

problemimiz;

A kullanici programi I ve J birer interrupt.

Eger A, I tarafindan kesilirse I'ya ait int rutini isletecegiz ve bu rutinin en sonunda X diye bir fonksiyonu cagiracagiz.

Eger A, J tarafindan kesilirse J de I tarafindan kesilirse I nin sonunda X fonksiyonunu cagirmayacagiz once  J nin yarida kesilen kismini islettirecegiz ardindan yarim kalan I int rutininde X fonksiyonunu cagiracak noktaya gelecegiz.




I_Rutini
.....
.....
Herhangi bir interrupt rutininin kesilmesine neden oldukmu?
Evet ise, kestigin Interrupt rutinlerini tamamlat.
X fonksiyonunu cagir.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

hasankara

hazır konu ile ilgilenen arkadaşlarımı bulmuşken bende bazı hedeflerimden bahsetmek isterim. güzel bir beyin fırtınası ile iyi şeyler ortaya çıkabilir diye düşünüyorum. biraz konunun ortasından girmiş gibi olacağım ama lafı uzatmadan sadede getirmek istiyorum.

zaman.h:
// Calculate the timer tick period
#define SYS_FREQ            GetSystemClock()
#define PB_DIV              1
#define PRESCALE            256
#define TOGGLES_PER_SEC     8
#define T2_TICK             (SYS_FREQ/PB_DIV/PRESCALE/TOGGLES_PER_SEC)
unsigned int timer_count;
//_/__/___/____/_____/______/_______/________/_________/__________/
#define 	mmxreg 		20

#define		s1hz 		0
#define		lcd_bsy	 	1
#define		pipeline 	2
#define		ucgn_ef1 	3
#define		sys_hz	 	4
#define		i2cwdt		5
#define		btn1_sur	6
#define		btn2_sur	7
#define		btn3_sur	8
#define		anim1		9
#define		ldrsn		10
#define		adcoku		11

unsigned 	int rdelay_msn[mmxreg];

extern void zaman_sayac(void);
extern void zaman_init(void);
//_/__/___/____/_____/______/_______/________/_________/__________/

zaman.c :
#include  "zaman.h" 
#include <GenericTypeDefs.h>
#include <plib.h>
#include "HardwareProfile.h"
#include "USB/usb.h"
#include "USB/usb_device_generic.h"
#include "user.h"
//_/__/___/____/_____/______/_______/________/_________/__________/
void zaman_sayac(void){
unsigned char i=0;

while(TMR2>625){TMR2=TMR2-625;
	for(i=0;i<mmxreg;i++)if(rdelay_msn[i]>0)rdelay_msn[i]--;}}
//_/__/___/____/_____/______/_______/________/_________/__________/

void zaman_init(void){

//*** TMR2 ***
    OpenTimer2(T2_ON|T2_PS_1_64, T2_TICK);
}


main:
int main ( void )
{
	zaman_init();
    while(1)
    {
		// rutinsel zaman sayaç kontrolü yapılır
		zaman_sayac();

		// sistem çalışır ledi (1hz)
		if(rdelay_msn[s1hz]==0){rdelay_msn[s1hz]=500;	mLED_6_Toggle();}
    }
} // main


burada bir çok işlem paralel olarak yürütülmekte ancak kafa karıştırmasın diye bir çoğunu sildim. zaman.h danda bu anlaşılabilir zaten. çalıştırmakta olduğum kodlardan alıntı yaptığımı da belirteyim.

şimdi; ana döngüde ki sistem çalışır ledi işlemini açıklayayım hızlıca, rdelay_msn[s1hz] dizisinin s1hz inci hücresindeki sayısal değer 0 ise bu hücreye 500 yüklenip led toggle ediliyor. zaman_sayac(); fonksiyonu ile her bir hücre 1ms de bir otomatik birer azaltılıyor. bu sayede 500 ms geçtiği anlaşılıp ona göre karar veriliyor.

farkettiyseniz, amaca tam şekilde hizmet ediyor olsada yazım şekli bana da pek hoş gelmiyor. yani sıradan bir delay(500); diyemiyoruz da önce yazılımsal olarak zaman.h kütüphanesinden bir hücre tayin edip o hücreyi sadece o amaç için kullanılır kılıyoruz. bunun yerine öyle bir fonksiyon oluşturayım ki önce nerden kullandığımı farketsin ona göre tayin işlemleri yapsın. biraz call_return için kullanılan stack gibi bir yapı elde edilebilir gibi düşündüm. ya da otel ve odaları muhabbetini duymuştum ona benzer bir yapı kurmayı hedefliyorum. bu işin bir standartı var mıdır? yada nasıl yapılabilinir konusunda ki fikirlerinizi duymak mutluluk verir.

z

Alıntı yapılan: z - 29 Ağustos 2013, 21:39:13
....Sorunun cozumu icin artistik bir kod yazmam gerekecek.......

Karsi karsiya kaldigim problem (interruptin System Tick ile kesilmesi, System Tick ile Task degistirme asamasinda kesilen interupt rutininde islenmemis kodlarin oylece kalmasi) zaten OS yapisinda bilinen bir problemmis. Neyseki cozumu de var.

Cozum: The Definitive Guide To The ARM CORTEX M3 (Second Edition) Sayfa 128

Bir diger aciklama ise http://embeddedgurus.com/state-space/2011/09/whats-the-state-of-your-cortex/
Bana e^st de diyebilirsiniz.   www.cncdesigner.com