rtos notlari

yapilanlar:

  • stm32f0 discovery’de rtos calistirma:
  • keil uvision 5 indiriliyor buradan
    • gerekirse - uvision’dan packet’lerin indirilmesi project-manage-pack installer-stmicroelectronics-stm32f051-micrium::rtos-install
    • gerekirse - mdk v4 legacy support indirilmesi buradan download legacy support for cortex-m devices
    • gerekirse - stlink utility indirilmeli buradan

klasik sistem

  • infinite loop system - interrupt bases systems - super loop systems - single loop systems - endless loop
  • tek bir endless loop’ta ana hesaplama islemi calisir. hesaplamanin arasina giren interrupt’lar ile tum sistem calisir.

rtos

  • sistem thread’ler uzerinden calisir. thread’lerin her birinde endless loop’lar olabilir. thread’lerin oncelikleri farklidir. thread’ler rtos scheduler tarafindan kontrol edilir. bu scheduler da periodik olarak cagirma islerini systick handler’i kullanarak yapar.
  • kodun farkli projelerde tekrar tekrar kullanilmasi mumkun. cunku bir thread create edildigi zaman kendi thread id’sinde de allocate ediliyor. thread id denilen sey de her tread’in handle edilmesine yardimci olan bir variable. yani bu thread id ile thread aktivitesi kontrol edilebiliyor. ???
  • running thread’lerin her switch edilisinde state of the thread ile thread variable’lari thread stack’ine kaydedilmesi gerek. thread ile ilgili tum runtime bilgisi thread control block’unda tutulur. bu thread control block da rtos kernel’i tarafindan kontrol edilir.
  • bir sistemde bir kerede tek bir thread calisir, diger thread’ler suspend edilir. en azından bizde (yani cok cekirdek olmadigindan)
  • thread’ler arasi iletisimler signals, messages, semaphores.
  • thread ancak 3 farkli state’te olabilir.
    • Running The Currently Running Thread
    • Ready Threads ready to Run
    • Wait Blocked Threads waiting for an OS Even
  • main.c dosyasi kernel’in baslamasi icin gerekli olan fonk’lari icerir. Yani aslinda main fonksiyonunun ana gorevi diger thread’lerin olusturulmasinda launcher olmak.
  • thread olusturulmasi 2 stage’te gerceklesir.
    • asagidaki satir ile thread1 isimli thread’in priority’si, olusturulacak olan instance sayisi, stack size’i.
osThreadDef(thread1, osPriorityNormal, 1, 0);
    • thread structure olusturulduktan sonra burada belirlenen isim ile (thread1) osThreadCreate() api’si (system call) cagrilarak thread olusturulur.

    thread1_id = osThreadCreate(osThread(thread1), NULL);

  • bir thread’e asagidaki gibi baslangic parametresi aktarilabilir.

uint32_t startupParameter = 0x23;
thread1_id = osThreadCreate(osThread(thread1), startupParameter);
  • thread olusturulunca tum bilgileri kendi stack’inde tutulur. Bu stack thread’a allocate edilmistir. Bu stack’in size RTOS configuration file’da default olarak ayarlanmistir. Eger thread structure’i olusturulurken stack size 0 girilmisse bu default degree set edilmistir.
  • Thread’e istenilen stack size atanacaksa asagidaki gibi. Fakat burada default stack size’a ek olarak mi 1KB eklendi yoksa default stack size 1KB’ye mi cikarildi bilinmiyor ???
osThreadDef(thread2, osPriorityNormal, 1, 1024); //assign 1KB of stack to this thread
  • sonradan olusturulan thread’in ismi Thread.c dosyasindaki 4 farkli yerde degistirilerek yapilabiliyor. yani bu dosyadaki Thread yazan 4 yere new_thread_name.
  • main function default first thread’tir.
  • default olarak toplamda 3 thread. osTimerThread, main, os_idle_demon.
  • main’de endless loop varsa main thread’i hic terminate etmez. ama endless loop yoksa main terminate eder, main icinde yeni bir thread olusturulmussa o devam eder.
  • thread’ler arasinda context switch yapabilmek icin kernel system call’larin gelmesini firsat bilir.
  • System calls api system calls
  • TCB task control block task’lar arasinda switch edilirken task state’inin, degiskenlerinin tutuldugu yer When a task is running, its context is highly dynamic. This dynamic context is maintained in the TCB. When the task is not running, its context is frozen within the TCB, to be restored the next time the task runs.
  • Rtos’larda 2 tur Scheduling Algorithm var.
    • Preemptive Priority-Based Scheduling task’larin oncelik durumlari farkli.

rtos_notlari_0

    • Round-Robin Scheduling task’larin equal share of CPU time’lari var. rtos’larda adam gibi tatmin saglamaz.

rtos_notlari_1

  • Multiple instances tek bir thread ile birden cok is yani instance yapilmasi. Mesela asagidaki gibi 2 farkli UART surulmesi. Kopya thread’ler bunlar aslinda. Yapilan is 2 thread’te de ayni ama farkli peripheral’lara hukmediyor. Her instance’in ID’si farkli olur.
    • thread1 icinde 2 tane instance:
osThreadDef(thread1, osPriorityNormal, 2, 0); 
    • sonra asagidaki sekilde 2 farkli UART
ThreadID_1_0 = osThreadCreate(osThread(thread1), UART1);
ThreadID_1_1 = osThreadCreate(osThread(thread1), UART2);

uvision notlari:

  • Thread viewer debug os support system and thread viewer
  • GPIO window peripherals general purpose I/O GPIOB
  • Event viewer debug os support event viewer
  • Proje olusturma – thread template ekleme
  • Project new uvision project decide project name
  • Device selection ok
  • CMSIS RTOS KEIL RTX tick resolve ok
  • Source Group right click add new item user code template CMSIS main function add
  • Source Group right click add new item user code template CMSIS thread add

Example 2 & 3

  • 2 ayri thread thread1 ve thread2 delay’ler for dongusu counter ile
    • Thread 1
      • Led 1 500 ms on
      • Led 1 500 ms off
    • Thread 2
      • Led 2 500 ms on
      • Led 2 500 ms off

While(1) var

rtos_notlari_2

Example 4

  • Tek thread 2 instance delay’ler for dongusu counter ile
    • Instance 1
      • Led 1 500 ms on
      • Led 1 500 ms off
    • Instance 2
      • Led 2 500 ms on
    • Led 2 500 ms off

While(1) yok

rtos_notlari_3

Example 5

  • 2 ayri thread farkli delay time’lari delay’ler kernel delay’leri
    • Thread 1
      • Led 1 500 ms on
      • Led 1 500 ms off
    • Thread 2
      • Led 2 100 ms on
      • Led 2 100 ms off

While(1) var

rtos_notlari_4


  • Virtual timer’lar one-shot veya periodic olabiliyorlar. calismayi bitirdikten sonra call back fonksiyonunu cagiriyor. Call back fonksiyonuna virtual timer ile parametre gonderiliyor. Yani virtual timer’dan sonra bu parametre ile call back fonksiyonun cagir. osDelay ile virtual timer’lar arasindaki tek fark call back fonksiyonlarini cagirmalari. Tread’leri soktuklari waiting state’lerde bir fark var ama tam incelenmedi ???

  • Idle Demon state code icinde kosan hic running thread ya da ready to run thread yoksa yani hepsi delay’lerin bitmesini bekliyorsa yani hepsi wait state’te ise rtos kendini idle demon state’e alir. Islemcinin low power mode’a alinmasidir bu. Bu idle demon mode’u ayni zamanda low priority’li bir thread gibi de dusunulebilir. Idle demon state’te yapilacak olan isler RTX_Conf_CM.c dosyasinda config mode’den cikilip text mode’a gecilerek void os_idle_demon (void) {} fonkunun icine yazilabilir.

  • os_idle_demon (void) fonkunun icindeki __wfe(); “wait for interrupt” demek. Bu satir bir peripheral interrupt’i ya da system tick’i gelene kadar CPU’yu HALT ediyor. Bu yoksa CPU halt olmuyor ve os_idle_demon tum CPU processi zaptediyor. Tabi butun bunlarin olmasi icin o anda calisan hic thread’in olmamasi lazim.


  • Inter thread communication signals, semaphores, mutexes, mailboxes and message queues

  • Signals thread kendini wait state’e sokup (osSignalWait ile) , bu wait state’ten cikmak icin baska bir thread’ten signal gelmesini bekleyebilir. osSignalWait (0x00,osWaitForever); icindeki 0x00 parametresi ile herhangi bir flag gelirse wait state’ten cikilir. Bu aslinda signal flag’ini belirtiyor. Wait state’te bekleyen 0x01 nolu signal flag’i, ancak 0x01 nolu signal flag’i tarafindan set edilebiliyor. CMSIS-RTOS RTX’ta thread basina 16 tane signal flag’i var. Normalde osSignalWaitin 2.parametresi millisec cinsinden. osWaitForever default ayarda 0xffff olarak define edilmis.

  • Signal usage The use of signal flags is a simple and efficient method of triggering actions between threads running within the RTOS. Signal flags are also an important method of triggering RTOS threads from interrupt sources within the Cortex-M microcontroller.


  • Interrupt handling rtos’ta thread’ler ile calisirken interrupt’larin da isin icine girmesi kabul edilmez. Bunun icin interrupt’larin da thread’ler gibi uygulanmasi gerekir. Yani interrupt kodlari high priority’li bir thread icine gomulmeli. Buna interrupt thread’i diyelim. Bir interrupt thread’inin ilk satirinda wait for osSignalWait olmasi gerekli.

  • interrupt handling’in calismasi icin NVIC register’larina erisim saglayabilmek icin privileged mode’un acilmasi lazim. TX_Conf_CM.ctaki configuration’dan. thread’ler bu sayede mcu’ya full access sagliyorlar. bu da run time error’lere ihitmal verebiliyor. bunun engellenmesi icin SVC exception’lari var.

rtos_notlari_5


  • SVC exceptions thread’lerin NVIC (nested vectored interrupt contoller) register’larina erisim saglamasi icin privileged mode’da calismasi gerekiyordu. SVC exception’lari sayesinde buna gerek kalmiyor. yani privileged mode’a gecmeden de kernel’e ulasabiliyoruz. sistem peripheral’larinin (DMA, SDRAM vs )privilege mode’a girmeye ihtiyaci varken standart peripheral’larin (UART, USB vs) yoktur. yani burada usage’taki ayrim, user mode ile privileged mode olarak 2’ye ayriliyor. baska bir değişle kernel space user space. user space’teki task’larin kendilerine ayrilmis olan memory space’lerine access’leri vardir. bu memory space’ler arasindaki paylasim da semaphore’lar ve queue’lar ile oluyor, baska türlü bir memory paylasimi yok. sistem peripheral’larina erisim de sadece privileged mode’da oluyor. standard peripheral’lari ile ilgili boyle bir durum yok. privilege mode’daki bir task kendini user space’e alabilir. ama user space’teki kendini privilege mode’a alamaz. sebebi zaten belli main func’tan onceki asm dosyalarina privilege mode’da calisan task’in tanitilmasi lazim.

kaynak


  • semaphores 2 veya daha fazla thread’in haberlesmesi. token’lar tutan container’lardir. thread’ler ile bu token’lari alip, yine thread’ler ile token’lari semephore icine release edilebilinir. bir semaphore olusturulurken kac token ile olusturulacagi bellidir, sifir da olabilir.
  • semaphore’larin en basit kullanimi signaling.
  • signal bekler gibi sem1 id’li semaphore’un beklenmesi
osSemaphoreWait(sem1, osWaitForever);
  • sem1 id’li semaphore’a token release edilmesi
osSemaphoreRelease(sem1);
  • semaphore’daki token sayisi anlik olarak okunamaz burada

  • semaphore basligi altinda incelenecek olan alt basliklar:

    • signaling thread’lerin ortak calismasinda seri calismayi saglar. statement b1’in calismasi icin statement a1’in calismasi lazim. buna binary semaphore da deniyor.

rtos_notlari_6

  • Multiplex aslinda birbirlerini semaphore’lar ile tetikleyen instance’lar.

    • token’lari alma sirasi son token bekleyen instance’a ilk token’in verilmesi seklinde. ex12 debug edilerek gorulebilir. yani instance’larin token’larin almasi FIFO seklinde degil, LILO seklinde.
    • buna counting semaphore da deniyor.
  • rendezvous 2 thread 2 farkli semaphore’dan beslenerek birbirleri ile bulusma mantigiyla islerini devam ettiriyor. yani 2 thread’in birbirlerinin semaphore token’larini wait ve release ederek ayni noktaya islem yapmadan gelerek beklemeleri durumu. sadece 2 thread icin calisir, daha fazlasi icin barrier turnstile.

  • Barrier Turnstile rendezvous’un daha genel hali.

  • Mutex semaphore’larin ozellesmis halleri. semaphore’lardan farki donanima erisim hallerinde kullanilir. binary token alir. donanim ile isi bitince mutex token’i release edilmelidir. baska thread’lerin donanima erisimini engelleyen yapilardir. bir thread donanim ile isini bitirir, diger thread oyle baslar.

mutex’in detaylarina girilmesi gerekirse burada


thread’ler arasi data exchange

  • message queue seri olarak her seferinde tek bir datanin transferi pass parameters by value
    • message queue linear buffer aslinda. Duz array.
    • message queue illa ki degisken size’i ile calisma zorunda degil, structure size’la da olabilir. Bu kullanimi zaten memory pool’da var. memory pool’dan farki memory’nin release edilememesi. Yani dynamic allocation yok burda.
    • Message queue’nun nerede locate edildigi belli degil, bu bir dezavantaj.

ilgili ornek kodlar burada (ters tiklayip save as diyebilirsiniz.)

  • memory pool birden fazla datanin paralel transferi Passing parameters by references message queue’ya degisken size’i degil, structure size’i verilir dynamic allocation fixed sized blocks allocation
    • cok sık sekilde allocation/deallocation yapilmasi gereken durumlarda
    • memory pool ile yapilan structure’a memory allocate edilmesi ve bunun release edilebilmesi.
    • memory pool’un normal allocation’dan farki release edilen her ayri kisim yuzunden olusan fragmantation sorununu ortadan kaldirmasi. Memory pool release edilince fragmantation olmayacak sekilde dolu memory block’larini shift ediyor. Run time sirasinda performansi azalttiginda real time/embedded sistemlerde bu tercih ediliyor.

kaynak_0

kaynak_1

ilgili ornek kodlar burada (ters tiklayip save as diyebilirsiniz.)

  • mail box birden fazla datanin transferi
    • message queue ile memory pool’un birlesimi. Gorunur bir queue kullanimi yok. Ama dynamic memory allocation var burda da. Memory pool’dan farki allocate edilen kisimlarin pool kadar genis olmamasi, message queue’lar kadar allocate ediliyor.

ilgili ornek kodlar burada (ters tiklayip save as diyebilirsiniz.)


  • thread’lerin stack size’lari conf dosyasi arayuzunden ayni anda calisabilecek 6 thread ayarinda thread basina 200 byte total ram usage = 1200 byte
  • Number of threads with user-provided stack size stack asimi durumunda diger thread’lerin stack’lerine tecavuz edecek thread sayisi
  • Total stack size [bytes] for threads with user-provided stack size stack asimi durumunda diger thread’lerin stack’lerine tecavuz edecekleri stack size

  • Conf dosyasi arayuzunden stack over flow checking stack asimi durumunda os_error fonkunun icinde sonsuz donguye girilmesi.

    • bu flag’in gelistirme asamasinda acilmasi, nihayi halde proje bitiminde kapatilmasi lazim. Kernel’de yer kaplamasin diye.
  • Stack Usage Watermark max memory usage during runtime 0xCC yazarak hesaplama - watermark ???

  • Timer Callback Queue size eger virtual timer kullaniliyorsa 0 olarak kalmamali. Bu virtul timer sayisi kadar olmali.


  • Systick timer kullanilmak zorunda degil bu timer’in frek’i ???
  • alternative timer initi os_tick_init
  • timer interrupt service routine os_tick_irqack