Okullar için Robotik ve Mühendislik · anaokulundan liseye

11. ünite / 11 · yaklaşık 6 saat

FreeRTOS: görevler, zamanlayıcı ve senkronizasyon

Süper döngüden görevlere; öncelikli kesintili zamanlama, tick, zaman dilimleme; kuyruk, semafor, mutex ve öncelik tersine dönmesi.

Bu ünitenin sonunda

  • Süper döngünün sınırlarını ve bir RTOS'un ne kazandırdığını açıklamak
  • Görev oluşturup öncelik vermek; vTaskDelayUntil ile kaymasız periyot kurmak
  • Zamanlayıcının kararlarını (kesinti, zaman dilimleme, boşta görev) zaman çizelgesinde okumak
  • Kuyruk ve mutex kullanmak; öncelik tersine dönmesini ve kalıtımı göstermek

Ders notları

Şimdiye kadarki programlar bir süper döngüydü: while (1) içinde sırayla motor, UART, sensör. Bir iş uzarsa diğerleri gecikir; her işin zamanlamasını elle dengelemek gerekir. FreeRTOS gibi gerçek zamanlı işletim sistemi, programı bağımsız görevlere böler ve hangisinin çalışacağına bir zamanlayıcı karar verir.

Zamanlama kuralları

  • Öncelikli ve kesintili: çalışmaya hazır en yüksek öncelikli görev çalışır. Daha yüksek öncelikli bir görev hazır olunca, çalışan görev hemen kesilir.
  • Tick: SysTick her 1 ms'de zamanlayıcıyı çağırır; gecikmeler tick cinsindendir.
  • Zaman dilimleme: eşit öncelikli hazır görevler her tick'te sırayla çalışır.
  • Boşta görev: hiçbir görev hazır değilse çalışır; burada düşük güç kipine girilebilir.

Periyodik bir görev vTaskDelayUntil kullanmalıdır: vTaskDelay(5) "şimdiden 5 tick sonra" der ve işin süresi kadar kayar; DelayUntil "bir önceki uyanıştan 5 tick sonra" der.

U = Σ Ci / Ti    RM yeterli koşulu: U ≤ n (21/n − 1)

Senkronizasyon

Görevler küresel değişken yerine kuyrukla veri paylaşır. Paylaşılan bir kaynağı (UART) korumak için mutex kullanılır. Tehlike: düşük öncelikli görev mutex'i tutarken yüksek öncelikli görev onu bekler, bu arada orta öncelikli görev düşüğü keserse yüksek görev de orta görevi bekler: öncelik tersine dönmesi. FreeRTOS mutex'leri öncelik kalıtımı uygular: mutex'i tutan görev geçici olarak bekleyenin önceliğine yükselir. Bu yüzden kaynak koruma için ikili semafor değil mutex seçilir.

Simülasyon

FreeRTOS zamanlayıcı görselleştirici

Görevlerin önceliğini, periyodunu ve süresini ayarla; tick tick hangi görevin çalıştığını, kesintiyi, eşit öncelikte zaman dilimlemeyi ve kaçan son tarihleri gör. Paylaşılan mutex ile öncelik tersine dönmesini ve öncelik kalıtımını dene.

motoruartlogidlet=0 motort=1 uartt=2 uartt=3 uartt=4 logt=5 motort=6 logt=7 logt=8 logt=9 idlet=10 motort=11 uartt=12 uartt=13 uartt=14 idlet=15 motort=16 idlet=17 idlet=18 idlet=19 idlet=20 motort=21 uartt=22 uartt=23 uartt=24 logt=25 motort=26 logt=27 logt=28 logt=29 idlet=30 motort=31 uartt=32 uartt=33 uartt=34 idlet=35 motort=36 idlet=37 idlet=38 idlet=39 idle0510152025303540
U = 0,70 · RM sınırı = 0,780 · boşta 30% · bağlam değişimi 21 en kötü yanıt: motor 1 · uart 4 · log 9 tick tüm son tarihler tuttu
motor
uart
log

Kendin dene

RTOS görselleştiricisinde varsayılan üç görevle çizelgeyi incele: motor görevi neden her 5 tick'te hemen çalışıyor? Günlük görevinin süresini artırıp kullanım oranını 1'in üstüne çıkar ve kaçan son tarihleri gör. "Öncelik tersine dönmesi" senaryosunu aç, yüksek görevin yanıt süresini kalıtım kapalı ve açıkken karşılaştır.

Kod

FreeRTOS: iki görev, kuyruk ve mutex
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

static QueueHandle_t cmdq;
static SemaphoreHandle_t uart_mtx;                 /* mutex: öncelik kalıtımı var */

static void motor_task(void *arg) {
  TickType_t next = xTaskGetTickCount();
  int duty = 0;
  for (;;) {
    xQueueReceive(cmdq, &duty, 0);                 /* beklemeden bak */
    pwm_set_percent(duty);
    vTaskDelayUntil(&next, pdMS_TO_TICKS(5));      /* kesin 5 ms periyot, kaymasız */
  }
}

static void log_task(void *arg) {
  for (;;) {
    xSemaphoreTake(uart_mtx, portMAX_DELAY);
    printf("alive\r\n");
    xSemaphoreGive(uart_mtx);
    vTaskDelay(pdMS_TO_TICKS(1000));
  }
}

int main(void) {
  HAL_Init(); SystemClock_Config(); pwm_init(); uart_init();
  cmdq = xQueueCreate(4, sizeof(int));
  uart_mtx = xSemaphoreCreateMutex();
  xTaskCreate(motor_task, "motor", 256, NULL, 3, NULL);   /* yüksek öncelik */
  xTaskCreate(log_task, "log", 256, NULL, 1, NULL);
  vTaskStartScheduler();                           /* geri dönmez */
}

Sık yapılan hatalar

  • Yüksek öncelikli görevde sonsuz döngüyü bekleme (delay ya da kuyruk) olmadan yazmak: düşük öncelikli görevler hiç çalışmaz.
  • Görev yığınını küçük vermek: taşma rastgele çökme yapar; configCHECK_FOR_STACK_OVERFLOW aç.
  • ISR'de normal API kullanmak: ISR'den yalnız ...FromISR işlevleri çağrılır.
  • Kaynak korumak için ikili semafor kullanmak: öncelik kalıtımı yoktur.

Yazılım mühendisliği bağlantısı

Görev tasarımı bir mimari belgedir: her görevin önceliği, periyodu, en kötü süre tahmini ve iletişim kanalları bir tabloda.

  • Bu tablo, simülasyondaki gibi bir çizelgeleme analizine girer; kullanım oranı ve yanıt süreleri hesaplanır.
  • Görev gövdelerindeki mantık saf fonksiyonlardadır ve RTOS olmadan test edilir.

Kendini sına

  1. Öncelik 3 ve öncelik 1 iki görev aynı anda hazırsa hangisi çalışır?

  2. Periyodik görevde vTaskDelayUntil neden vTaskDelay'e tercih edilir?

  3. Öncelik tersine dönmesinin FreeRTOS'taki çözümü?

  4. Görevler 1/5, 3/10 ve 4/20 (süre/periyot). Toplam kullanım?

Bu üniteden sonra bitirme projesinde

  • Sistem ve demo: FreeRTOS görevleri (motor, komut, izleme) ya da gerekçeli süper döngü; demo videosu ve rapor.

Gerçek parçalar (Hyvex, 3B modelli)

Esc
  • PanelAna sayfaSayfa
  • ModüllerTüm modüllerSayfa
  • ParçalarParça ansiklopedisiSayfa
  • Mühendislik yoluBüyükler için robotik: 128 parça, 7 seviyeSayfa
  • Robotik dersi (ESOF 323)Üniversite robotik dersi, 14 haftaSayfa
  • Drone dersiBüyükler için: parça, simülasyon, yazılım; 10 üniteSayfa
  • Blok atölyesiSerbest blok programlamaAraç
  • Devre laboratuvarıSanal Arduino ve devreAraç
  • Robot arenasıSanal robot sürüşüAraç
  • OyunlarBloklarla 8 öğretici oyunAraç
  • Mikro Kart atölyesiSanal LED kartı bloklarla programlaAraç
  • Robot atölyesiMikro Kart'ı robota tak, bloklarla görev yapAraç