RENESAS için RTOS

Başlatan picusta, 26 Mayıs 2006, 14:44:02

picusta

Renesas islemcinin mimarisini inceledikten sonra (simdilik en ufak olan R8C), bu islemcinin yapisinin RTOS için ne kadar uyumlu oldugunu anladim.
Amacim FreeRTOS sitesindeki kodlari m16c serisine port etmek. Baska bir deyisle, sitede bulunan hazir RTOS algoritmasini alip (C ile yazilmis), birkaç define ve birkaç satir kod ilave ederek m16c de kullanmak.
m16c nin donanimsal olarak çift stack'li olusu, (user stack, interrupt stack), task control block'un neredeyse donanimsal olarak varligi (stack base, stack pointer,frame base kullanarak), hem port isini kolaylastiracak, hem de RTOS'un performans ve karaliligi bakimindan avantaj.
Böyle bir projeyi maalesef tek basima kaldiramam, haftada ancak 1-2 saat ayirabilirim. Macerayi seven birkaç programci da bu kadar zaman ayirabilirse (datasheet, RTOS yapisini inceleme) kisa sürede çalisan bir sürüm elde edebiliriz.
M16c için RTOS "Embos" tarafindan yazilmis, sitelerinde 3 task çalistiracak demoyu indirebilrisiniz.
Assembler'inden reverse engineering yapip context saving'de hangi registerler kayit ediliyor bakabiliriz.
Sonra FreeRTOS sitesine bu portu gönderip picprojeyi dünya çapinda tanitabiliriz. yayimlayip
Daha sonra baska islemciler için port yapabiliriz.
O da hizimizi kesmezse, picproje dagitimi Linux: picprojus. içinde picprojus messenger hazir kurulu geliyor.

Hepinize işlerinizde basarilar.

picusta

Evet beyler ve hanimlar, bu projeyi tekrar gündeme getirelim.
özel mesajdan:
Alıntı Yaphocam ben renesas için RTOS işinde sonuna kadar varım ancak haziran 20 de sonra yardımcı olabilirim
demek veya
Alıntı YapEğer gerekirse uygulama konusunda da sonuna kadar destek veririz vs. vs.
demek yetmiyor, ise girismek lazim, gerisi gelir.

Simdi diyeceksiniz ki RTOS ne isimize yarar, nasil kullanacagiz programlarda bug olayini nasil halledecegiz. Hakli olarak tabii.
Bu yüzden RTOS'u hakki ile kullanmaniz için size birkaç yardimci ders verecegim:
- SA-RT metodu ile RTOS uygulama nasil yazilir.
- Petri aglarini kullanarak RTOS uygulamalarini modelemek, simüle etmek ve "dead-lock" olayindan arindirmak.

Port yazmaya gelince, biraz arastirdiktan sonra sunlari gördüm:

- Embos'un port'u var, daha önce dedigim gibi ASM'sine bakarak gereken fonksyonlari alabiliriz.

-  ÂµC/os-II : OS'in kendisi bir kitapta anlatiliyor, kitabin yaninda bide kodlari içeren CD veriliyor. Kodu açik RTOS ama kullanmak için para ödemek gerekiyor. Renesas  için port'u daha sonra sitesinden bedavaya indiriliyor (gereken fonksyonlar). Bu fonksyonlardan esinlenerek Free-RTOS'a port yapabiliriz. Veya µC/os-II'yi internetten bulmak çözüm olabilir.

- Circuit Cellar 'in 190. numarasinda (2005 M16C Contest). M16C ile web camera ve görüntü isleme sayesinde cisim takip edebilen bir robot yapmak için yazar uexec (Imagecraft) adli açik kodlu bir RTOS'u port etmis.

Bu üç port'u inceleyerek kendimizde bisiler katarak daha iyisini yapabiliriz diye düsünüyorum.

Tabii önce RTOS nasil çalisir, stack, Task Control Block nedir, bunlari burda anlatalim.

tevfik_kadi

Hocam yardımcı olmak isterim bu konuda bu arada m16c kullanmak için bir adet almıştım. tez uygulama devresi ile uğraştığımdan bir türlü devre yapıp kullanma şansım olmadı . Tezimde msp430 kullandım o da güzel bir işlemci kullanmaya devam ediyorum her neyse konu RENESAS. Kozları ortaya dökelim diyorum dosyalar varsa elinizde incelemem için gönderebilir misin? Hiç yoktan çeviri yaparım :) çorbada benim de bir tuzum olsun.

Kolay gelsin;
Saygılar

CoşkuN

Alıntı yapılan: "picusta"E

Tabii önce RTOS nasil çalisir, stack, Task Control Block nedir, bunlari burda anlatalim.
Evet hocam önce şu RTOS konusunu bir anlatsanız güzel olur.

picusta

Kendimi yanlis ifade ettim, özür dilerim. ben demistim ki
Alıntı Yap
anlataliM
Yani insanlari konuya katilmalari için tesvik etmek istedim.
bu konuyu benden iyi bilenler vardir.
Isterseniz buyrun açilisi siz yapin.
stack olayini anlamak için interruptlardan baslayalim. interrupt gelince noluyor? context nasil kaydediliyor anlatirsaniz sevinirim.
Gerisini ben devam ettiririm.

tevfik_kadi

Hmm Hocam benim bulduğum incelediğim pic için olan bir multi-task uygulaması vardı ordaki olay timerlar üzerinden interrupt oluşturup her oluşan kesmeye göre bir programı çalıştırıp diğerinin bilgilerini zaten mikro denetleyici otomatik olarak yığına atıyor. Yani bir kesme geldiği zaman, Çalışan programın registarları (geçici bilgileri) kesme yığınına atılıp diğeri çalıştırılıyor böyle böyle bu olay devam ediyordu incelemek isterseniz kod :
//multitasking system – handle multiple tasks with one microprocessor

//task counters used to tell when a task is ready to be executed
//all these counters are incremented every time a 500us interrupt happens
//every task has its own counter that is updated every time a 500us interrupt happens
#include "16F84A.h"
unsigned int task0_counter=0;
unsigned int task1_counter=0;
unsigned int task2_counter=0;

//this tells when a task is going to happen again
//for example, when task0_counter==TASK0_COUNTER_MAX, set task0_counter=0 and do task
#define TASK0_COUNTER_MAX 1         //high frequency task – every 500us, maybe PWM
#define TASK1_COUNTER_MAX 2000      //low frequency task – every 1000ms
#define TASK2_COUNTER_MAX 5000      //low frequency and low priority task, every 2500ms

//Note: every variable referenced in both interrupt and main() must be declared volatile. You have been warned!
//this enables/disables a task
volatile unsigned char task0_enable=TRUE;
volatile unsigned char task1_enable=TRUE;
volatile unsigned char task2_enable=TRUE;

//this allows tasks triggered by interrupt to run in the background in main()
volatile unsigned char task2_go=FALSE;
void setup_multitasking(void)
{
   //set up tmr1  to interrupt every 500us
   TMR1CS=0;
   T1CKPS0=0;
   T1CKPS1=0;

/*We want to wait 2000 clock cycles, or 500us @ 16MHz (instructions are 1/4 speed of clock).  Timer 1 interrupts when it gets to 0xFFFF or 65535.  Therefore, we set timer 1 to 65535 minus 2000 = 63535, then wait 2000 ticks until rollover at 65535.  To test, use simulator to find that its exactly correct*/

   #define  TICKS_BETWEEN_INTERRUPTS      2000
   #define  INTERRUPT_OVERHEAD            19
   #define TMR1RESET (0xFFFF-(TICKS_BETWEEN_INTERRUPTS-INTERRUPT_OVERHEAD))
   #define TMR1RESET_HIGH TMR1RESET >> 8
   #define TMR1RESET_LOW TMR1RESET & 0xFF
   TMR1ON=0;
   TMR1H=TMR1RESET_HIGH;
   TMR1L=TMR1RESET_LOW;
   TMR1ON=1;
   TMR1IF=0;
   TMR1IE=1;
   PEIE=1;
   GIE=1;
}

void interrupt isr(void)
{
   //one tick every 500us at 16Mhz
   if (TMR1IF)
   {
      //set up timer 1 again to interrupt 500us in future
      TMR1IF=0;
      TMR1ON=0;
      TMR1H=TMR1RESET_HIGH;
      TMR1L=TMR1RESET_LOW;
      TMR1ON=1;
      task0_counter++;
      if (task0_counter>=TASK0_COUNTER_MAX)     //high frequency task – every 1 tick
      {
            task0_counter=0;
            if (task0_enable==TRUE)
            {
                  //do high frequency important task 0, for example PWM
            }
      }
      task1_counter++;
      if (task1_counter>=TASK1_COUNTER_MAX)     //low priority task - every 2000 ticks
      {
            task1_counter=0;
            if (task1_enable==TRUE)
            {
                  //do low frequency yet important task 1
            }
      }

/*this task takes a long time, 100ms for example, lots of maths.  Is extremely low priority, but has to be done at regular intervals, so all this does is trigger it.  In main(), it will, at leisure, poll ‘task2_go' and then execute it in the background.*/

      task2_counter++;
      if (task2_counter>=TASK2_COUNTER_MAX)     //every 250ms
      {
          task2_counter=0;
          if (task2_enable==TRUE)
          {
               //every 250ms take 100ms to do maths, do this in main() so the we can get back to doing the high frequency tasks.
               task2_go=TRUE;
          }
      }
   }  //if (TMR1IF)
} //interrupt routine


main()
{
   setup_multitasking();
   while(1)
   {
      if (task2_go==TRUE)
      {
            task2_go=FALSE;
            //take our time, doing heaps of complex maths at our leisure in the background
      }
   }
}

picusta

Bu uygulamadaki multitasking cooperative, bizim yazmak istedigimiz ise preemptive.
Bu uygulama niye cooperative?
her task'i (0.,1. ve 2.) isleme sirasi ve zamani önceden belirlenmis.
önce 0. task 500µsaniyeyi geçmemeli, 1. Task 250 ms. Sonrada 2. Task.
Aslinda bakilirsa burda gerçek anlamda 2 task var: Main birde interrupt. Main alçak öncelikli. interrupt ise yüksek öncelikli ve main'i herhangi bir zamanda bölebilir (interruptlar açiksa).
Simdi diyelim ki bu iki görev birbiri ile iletisime geçmesi gerekiyor. Eger tek bir degisken kullanilacaksa söyle bir sorun çikiyor: diyelim 16 bitlik degiskenimiz var, bizim PIC'imiz 8bitlik oldugu için her komutta 8 bit yazabilir. Main'de bu degisken ile ilgili hesabimizi yaptik simdi sonucu o degiskene aktarmak istiyoruz, birinci MOV komutu ile ilk 8biti (mesela MSB) yazdik, sonra ikinci MOV komutu ile ikinci 8biti yazacagiz. Ama o da ne? araya interrupt girmez mi? dolayisi ile ona bagli görev baslamaz mi? Simdi degiskenimizin yarisi eski deger yarisi yeni deger:
örnegin eski degeri 0x 01 FF idi biz birinci görevle bunu bir ile topladik sonuç : 0x02 00. Sadece üst bitleri yazabildik, geri kalan eski bitler. Interrupt geldigi sirada degiskenimizin degeri : 0x02 FF. Yani gerçek degerinden hayli büyük.
Interrupt görevi bu degerle hesabini yapacagi için, sonuç yanlis olabilir ve hatalar dogurabilir.
Tabii bunu engellemek için önlemler alinabilir, mesela interruptlari durdurmak. veya double buffer teknigini kullanmak.

Cooperative uygulama yazarken, her görevi digerlerinden bagimsiz yazamiyorsunuz, önce görevlerin ne zaman çagrilacagini düsünüp plan yapmak gerekiyor, ve ona göre programi yazmak gerekiyor. Bir nevi statik oluyor.
Cooperative multitasking görevlerin öncelikleri sayesinde çalisir.
her baslayan görev ya isini bitirene kadar islemini yapar ya da daha yüksek öncelikli bir görev tarafindan kesilene kadar.
Arada durup, islemcinin baska bir görevi sürdürmesine(daha düsük öncelikli) sonra tekrar kaldigi yerden devam etmesine izin vermez.
Cooperative mutlitasking'in yapamadigi bir olay ise taskleri senkronize etmek (randevu vermek):
diyelim main taskinde islemler yapiliyor. arada interrupt geliyor, hizli islemlerini yapiyor, sonra durup mainden gelen sonuca göre islemini devam etirmesi gerekiyor. Iste o noktada islemci interruptu birakip (ama nerden biraktigini unutmamali) main'e devam etmesi gerekiyor ki islem bitsin. Islem bitince de main görevi interrupt'a haber göndermeli ki, islemci main'i birakip interrupt'a devam etsin(kaldigi yerden).

Cooperative mutlitasking'den bahsettik. Simdi preemptive konumuza dönelim.
stack denilen sey ard arda yerlestirilmis yazmaçlar. Bu yazmaçlari bir deste olarak düsünebiliriz. Deste bir deger koydugumuzda, destenin üzerine koyulmus oluyoruz, böylece en üstte son koydugumuz deger oluyor. Desteden bisey çektigimizde ise en üsttekini alabiliyoruz. Bu destenin bilgisayarda var olabilmesi için gereken sey bir stack pointer, bu deger destenin tepesinin hangi yazmaçta oldugunu söylüyor. Destege bisey koydugumuzda bu deger 1 artiyor, çektigimizde 1 azaliyor. Birde stack base var, bu a destenin hangi yazmaçtan (adresten) basladigini belirtiyor.
PIC 16 serisinde interrupt stack 7 register derinliginde (yanlis hatirlamiyorsam). interrupt geldiginde otomatik olarak Program counter (islemcinin hangi program satirinda oldugunu belirten yazmaç ) oraya konuluyor, birde status register(yine yanlis hatirlamiyorsam). Sonra interrupt vektörüne gidiliyor, orda islemler yapiliyor ve return form interrupt komutu geldiginde ise, desteden bu iki deger alinip ilgili (program counter, status)yazmaçlarina yaziliyor.
Kisaca, interrupt geldiginde, önce islemci nerde oldugunu bi yere not aliyor(program counter'i stack'e atarak(desteye)), sonra interruptan dönüste ise desteden bakarak oldugu yere dönüyor.
Bu yazmaçlara(program counter, status) context deniyor. Ayrica assembly'de yazanlar bilir, ayriyetten interrupt'larda W yazmacini "el ile" kaydetmek, bi yere yazmak gerekiyor, çikarken de bu degeri tekrar W'ye yazmak gerekiyor.
18 serisinde ise çarpma özelligi oldugu için çarpma sonucunu yazmaci var, eger interruptta çarpma yapilacaksa(bu yazmacin degeri degisecegi için) bunu da kaydetmek gerekir.
18 serisinin bi avantaji ise bu stack denilen yere PUSH( desteye yazma) ve POP (desteden alma) komutlari ile desteye ulasilmasini saglamak. Böylece bir interrupt ana programi hangi yerden kestigini bilebilir (destedeki program counter degerine bakabilir).
Bu komutlar sayesinde istedigimiz olan preemptive RTOS'u yazabiliriz.  PIC18 için PICos18 adli RTOS böyle yazilmistir.

tevfik_kadi

Sanırım yanlış anlamadıysam sizin önerdiğiniz şey aslında yığını kullanmak yani yığına interrupt içindeyken başlayacağı programın adresini iterek interrupt dönüşünde burdaki programı çalıştırmak gibi birşey
örneğin :

push program_adresi
IRET (80286 için yığının en üstündeki adres kesmenin oluştuğu kodun adresi dönüşte burdan başlıyor program)

sanırım benzer bir uygulamayı 80286 assebly sini görürken hoca bahsetmişti umarım karıştırmamışımdır. Yani yığını kabartacak bir işlemci m16c bu iş için uygun mudur dediğim şekilde bir yöntem mi dediğiniz birinci yöntemi anladım. İkinci yöntem hakkında aklımda bir fikir oluşmuşsa da tam olarak kavrayamadım "preemptive" yöntemi nasıl bir yöntemdir biraz daha açıklayabilirmisiniz.

picusta

Evet, bu yigin sayesinde preemptive RTOS'u yazacagiz (m16c için).
demek istedigim preemptive RTOS PIC16 ile yapilamaz, PIC18 ile yapilir.

Simdi preemptive RTOS nedir ve nasil çalisir, mekanizmalari nedir bunlari anlatmak gerekli.
Buyrun söz hakkini bunlari anlatacak bir arkadasa veriyorum, simdiden kendisine tesekkür ediyorum.

kurumahmut

picusta verdiğiniz 0x02 FF örneğindeki hata preemptive  de de görülebilen bir hata sanırım. Gene alt 8biti yazarken kesme gelebilir ve kesme programı bu sayıyı kullanırken hata oluşabilir değil mi? Bunun tek çözüm yolu yazma işlemleri sırasında kesmeler örtülmeli gibi geldi bana...

yanlış mı düşünüyorum? eksik mi anladım?

picusta

Is tam öyle değil:
Yukaridaki verilen örnek kodda (tevfik kardesin verdigi) Aslinda o sadece multitasking yapan bir UYGULAMA. Bizim yapmaya (yazmaya, daha dogrusu yazilan kodu islemciye uyarlamaya) çalistigimiz bir gerçek zaman ISLETIM SISTEMI yazmak (RTOS).
0x02FF'li örnekte, amaç iki görev arasinda veri göndermek.
uygulamada bunu biz "el ile" gerçeklestiriyoruz. Gereken önlemleri almasak, veriler hatali olur. önlemlerden bi tanesi interruptu kesmek tabii, diger bir mekanizma double buffer.
RTOS kullanirsak, veri göndermeyi isletim sisteminin bize sundugu bir hizmet  sayesinde gönderiyoruz (buna posta kutusu mekanizmasi deniyor).Gönderme otomatik oluyor, veriyi okuyanin öncelik durumuna bakmazsizin programimizi yaziyoruz.
Kisaca: isletim sistemi bize bir takim hizmetler sunacak, bu hizmetleri kullanarak programimizin içinde bulunan her görevi diger görevlere bagli kalmadan yazacagiz.

engin_

Kesme olayında A çipi B çipi arasında sürecin işleyişi bakımından bir fark olmaması lazım. Yani kesme geldikten sonra proram yarım kalabilmeli, kesmenin anlamı burda zaten.

Burda ara bir kesme programı hazırlamak lazım sanırım. Yani süreçlerin hangisinin çalışacağını veya yeni süreçleri takip eden ve bir sürecin artık işlerini anımsayacak veya yönetecek bir ara kesme program hazırlamak lazım.

picusta

Simdi kavramlari karistirmayalim.
multitasking, multiprocessor, preemptive, cooperative, isletim sistemi, interrupt kullanan uygulama. Bunlari ayirt etmek lazim.
O yüzden birisinin gelip RTOS'u anlatmasini bekliyorum.

Alıntı YapYani süreçlerin hangisinin çalışacağını veya yeni süreçleri takip eden ve bir sürecin artık işlerini anımsayacak veya yönetecek bir ara kesme program hazırlamak lazım.
Asagi yukari yapmak istedigimizin bir kismi bu, bunun adina scheduler (planlayici) deniyor.
Bunu söyle degistirebiliriz:

Görevlerin hangisinin çalışacağını veya yeni görevleri takip eden ve bir görevin artık işlerini anımsayacak veya yönetecek bir "ara kesme programi"na scheduler denir.

örneklerimizde hep interrupttan bahsettik. Oysa interruptlar sadece hardware tarafindan tetiklenir (timer, adc bitis, seri veri alis vs...). RTOS'ta tetikler (event) softwareden de gelebilir.

engin_

Alıntı yapılan: "picusta"
örneklerimizde hep interrupttan bahsettik. Oysa interruptlar sadece hardware tarafindan tetiklenir (timer, adc bitis, seri veri alis vs...). RTOS'ta tetikler (event) softwareden de gelebilir.

Ara kesme programının bir koluda bu işe yarıyor olmalı. Yani sadece donanım isteklerini değilde yazılım isteklerini de karşılıksız bırakmamak için var. Ama bir yazılımın çalışması için mecburen bir donanımsal kesme olması gerekir. Yani ben klavyenin tuşuna basmassam, klavye kesme oluşturmaz. Sonuçta bilgisayarda çalışan program da birşey yapmaz. Tabi otonom şeylerin buna ihtiyacı yok.

Ara kesme programı işletim sisteminin bel kemiği olmalı. Her donanımsal kesme ayrı bir yazılımın işletilmesi demek olduğuna göre bu yazılımlarada ayrı süreçler tahsis edilecek. Var olan süreçler arasında da zaman paylaştırılacak. Tabi işletim sisteminin sağladığı işlevlerden haberi olan bir kesme programı bu. Yazılım isteklerine göre işletim sisteminin sağladığı işlevleri de tahsis edecek.

Tanımlanacak tüm donanım kesmeleri, işletim sistemi tarafından da tanımlanmış olacak zaten. Yani bunları linuxdaki gibi modüller olarak düşünürsek. Ara kesme programıda kernel olacak. Biz kernel vasıtasıyla modülleri kullanacağız. Modüller de donanımı kullanacak.

Şimdi burdan bir sonuç çıkartmaya çalışırsak.

-Yürütülmekde olan bir programımız var. Buna bir süreç tahsis ettik. Linux da mesela PID numarası verilir.
-Bu program işletim sisteminin özelliklerini kullanacak. O zaman kullanılan modüllerin sürecini de tutmamız lazım. Ama bunlar çok küçük ve önemli uygulama parçaları deyip bitirene kadar çalıştırılmalı diye düşünülebilir. Yada PID numarası çerçevesinde bir yere kaydı düşülebilir.

Her ne yapılırsa yapılsın belleği çok iyi kullanmak gerek. Bir den fazla sürecin aynı modülü kullanığını düşünün.

picusta

Evet isletim sisteminin temelleri bunlar.
Ayrica isletim sistemi kat kat olan bir olaydir, çekirdekten (kernel) baslayip, her katta ayri hizmetler sunar.
Bizim yapacagimiz isletim sisteminin mikrodenetleyici üzerinde çalisacagini göz önüne alirsak, fazla RAM ve FLASH harcama lüksümüz yok. Bu yüzden sadece kernel, ve primitifleri ile ilgilenecegiz.
Bir görev, (veya task, process, thread, süreç vs...) nedir onu açiklamamiz gerekiyor önce.
Herkesin bildigi gibi bir program parçasidir. Ama sadece bundan ibaret değil. Isletim sistemi ortaminda tamamen özerk bir nesnedir, ve ayni anda birkaçtanesi aktif olabilir. Bu nesneyi bir makine olarak düsünebiliriz. Bu makinenin 4 durumu olabilir :
- Hizmet disi: ilk yaratildiginda aldigi durum, baska bir görevin onu aktif edene kadar kaldigi durum, desaktive edildiginde bu duruma döner.
- Hazir : Aktive edilmis durumda, ama CPU ona vakit ayiramiyor, daha yüksek öncelikli baska bir görev CPU'yu mesgul ediyor. Dolayisi ile, göreve bagli olan program o esnada ilerlemiyor.
- çalisiyor : CPU göreve bagli olan programi isliyor, programin ilerliyor.
- Beklemede : görev çalisiyor vaziyette iken, isleyisi bloke eden bir kosul (daha yüksek öncelikli bir görev aktif edilmesi, görevin kaynak beklemesi, uykuya alinamasi (wait5sec) ) beliriyor, CPU programi islemeyi duraklatiyor, baska bir göreve bagli programi devam ettiriyor.
Bloke eden kosul kalktiginda (5 saniye beklemesi, kaynagin yeniden hazir olmasi, yüksek öncelikli görevin beklemeye alinmasi) makine tekrar CPU'yu alabiliyor ve program oldugu yerden devam ediyor.

Görevlerin bu durumlarini hatirlamak için, isletim sistemi her görev için Task Control Block (TCB) denilen bir veri yapisi olusturuyor. Buraya mesela engin arkadasimizin bahsettigi Process Identification (PID veya Task ID) denilen numara yaziliyor(her görev için farkli bir numara tabii).
Ayrica öncelik seviyesi (mesela 0'dan 255'e kadar), görevin çalisirkenki context'i yani ihtiyaç duydugu özel registerlerin degeri (stack'in baslangiç bitis) program counter, çalisma registerleri(PIC için W, R8 için A0 A1 R0 R1 R2 R3 FB SB registerleri) gibi degerleri de barindirmasi gerekiyor.
Bu degerler sayesinde isletim sistemi bir görevi beklemeye alabiliyor, sonrada tekrar kaldigi yerden devam edebiliyor.

Bu görevler iyi hos, birbirinden bagimsiz (göreceli olarak tabii) olarak yazilmis. Ama bu görevler birbiri ile iletisimde bulunmali, mesaj degistirmeli. Ayrica bu görev sanal olarak ayni anda çalisabilecegini unutmamak gerekir. Sistemin bir aygitini bir görev kullanirken digeri gelip kullanmaya kalkisirsa pek iyi olmaz.
Bu soruna karsi isletim sistemi görevler arasinda kaynaklarin (dogru düzgün) paylasilabilmesi için Semaphore adli mekanizma gelistirilmis. Ayrica bu mekanizma sayesinde görevler birbirlerine randevu verebiliyor.

Simdi bu konuyla ilgilenen kimler var acaba? bir takim kurup icraata geçelim, kodlari inceleyelim.
RTOS'u burda daha iyi anlatmak için sitelerden resimli anlatim bulabilirz.