- Çok çekirdekli işlemcinin avantajları
- ESP32 ve FreeRTOS
- ESP32 çekirdek kimliğini bulma
- ESP32 Çift Çekirdekli Programlama
ESP modülleri, ESP8266, ESP-12E, vb. Gibi Wi-Fi işlevleri açısından popülerdir. Bunların tümü, Wi-Fi işlevlerine sahip güçlü Mikroişlemci modülleridir. Önceki ESP modüllerinden daha güçlü ve çok yönlü bir ESP modülü daha var - adı ESP32. Bluetooth ve Wi-Fi bağlantısı var ve biz zaten ESP32'nin BLE yeteneklerini anlattık ve birçok IoT projesinde ESP32'yi kullandık. Ancak çok az kişi ESP32'nin Çift çekirdekli bir mikro denetleyici olduğunu biliyor.
ESP32, onu güçlü bir çift çekirdekli (core0 ve core1) mikro denetleyici yapan iki adet 32-bit Tensilica Xtensa LX6 mikroişlemciye sahiptir. Tek çekirdekli ve çift çekirdekli olmak üzere iki çeşidi mevcuttur. Ancak çift çekirdekli varyant daha popüler çünkü önemli bir fiyat farkı yok.
ESP32, Arduino IDE, Espressif IDF, Lua RTOS, vb. Kullanılarak programlanabilir. Arduino IDE ile programlama yaparken kod yalnızca Core1'de çalışır çünkü Core0 zaten RF iletişimi için programlanmıştır. Ancak burada, aynı anda iki işlemi gerçekleştirmek için ESP32'nin her iki çekirdeğinin nasıl kullanılacağını göstereceğiz. Burada ilk görev yerleşik LED'i yakıp söndürmek olacak ve ikinci görev DHT11 sensöründen sıcaklık verilerini almak olacaktır.
Öncelikle çok çekirdekli bir işlemcinin tek bir çekirdekteki avantajlarını görelim.
Çok çekirdekli işlemcinin avantajları
- Çok çekirdekli işlemciler, aynı anda çalışacak 2'den fazla işlem olduğunda kullanışlıdır.
- İş, farklı çekirdekler arasında dağıtıldıkça, hızı artar ve birden çok işlem aynı anda bitirilebilir.
- Güç tüketimi, herhangi bir çekirdek boş moddayken, o sırada kullanılmayan çevre birimlerini kapatmak için kullanılabileceğinden daha azaltılabilir.
- Çift çekirdekli işlemciler, tek çekirdekli işlemcilerden daha az sıklıkta farklı iş parçacıkları arasında geçiş yapmak zorunda kalırlar çünkü aynı anda bir yerine ikisini aynı anda işleyebilirler.
ESP32 ve FreeRTOS
ESP32 kartında zaten FreeRTOS bellenimi yüklü. FreeRTOS, çoklu görevlerde çok yararlı olan açık kaynaklı bir Gerçek Zamanlı İşletim sistemidir. RTOS, kaynakları yönetmeye ve sistem performansını en üst düzeye çıkarmaya yardımcı olur. FreeRTOS, farklı amaçlar için birçok API işlevine sahiptir ve bu API'leri kullanarak görevler oluşturabilir ve farklı çekirdekler üzerinde çalıştırabiliriz.
FreeRTOS API'lerinin eksiksiz dokümantasyonu burada bulunabilir. Her iki çekirdekte de çalışacak çok görevli bir uygulama oluşturmak için kodumuzda bazı API'leri kullanmaya çalışacağız.
ESP32 çekirdek kimliğini bulma
Burada kodu ESP32'ye yüklemek için Arduino IDE'yi kullanacağız. Kodun üzerinde çalıştığı Çekirdek Kimliğini bilmek için bir API işlevi vardır
xPortGetCoreID ()
Bu işlev, üzerinde çalışmakta olan çekirdek kimliğini bilmek için void setup () ve void loop () işlevinden çağrılabilir.
Aşağıdaki çizimi yükleyerek bu API'yi test edebilirsiniz:
geçersiz kurulum () { Serial.begin (115200); Seri.print ("çekirdekte çalışan setup () işlevi:"); Serial.println (xPortGetCoreID ()); } void döngü () { Serial.print ("döngü () işlevi çekirdek üzerinde çalışıyor:"); Serial.println (xPortGetCoreID ()); }
Yukarıdaki çizimi yükledikten sonra, Seri monitörü açın ve her iki fonksiyonun da aşağıda gösterildiği gibi core1 üzerinde çalıştığını göreceksiniz.
Yukarıdaki gözlemlerden, varsayılan Arduino taslağının her zaman core1 üzerinde çalıştığı sonucuna varılabilir.
ESP32 Çift Çekirdekli Programlama
Arduino IDE, ESP32 için FreeRTOS'u destekler ve FreeRTOS API'leri, her iki çekirdekte bağımsız olarak çalışabilen görevler oluşturmamıza izin verir. Görev, kart üzerinde yanıp sönen led, sıcaklık gönderme vb. Gibi bazı işlemleri gerçekleştiren kod parçasıdır.
Aşağıdaki işlev, her iki çekirdekte de çalışabilen görevler oluşturmak için kullanılır. Bu işlevde, öncelik, çekirdek kimlik vb. Gibi bazı argümanlar vermemiz gerekiyor.
Şimdi, görev ve görev işlevi oluşturmak için aşağıdaki adımları izleyin.
1. İlk olarak, void kurulum işlevinde görevler oluşturun. Burada iki görev oluşturacağız, biri her 0,5 saniyede bir yanıp sönen LED için ve diğer görev her 2 saniyede bir sıcaklık okuması almak.
xTaskCreatePinnedToCore () işlevi 7 argüman alır:
- Görevi uygulamak için işlev adı (görev1)
- Göreve verilen herhangi bir ad ("görev1" vb.)
- Göreve kelimelerle ayrılan yığın boyutu (1 kelime = 2 bayt)
- Görev giriş parametresi (NULL olabilir)
- Görevin önceliği (0 en düşük önceliktir)
- Görev tanıtıcısı (BOŞ olabilir)
- Görevin çalışacağı çekirdek kimliği (0 veya 1)
Şimdi, xTaskCreatePinnedToCore () fonksiyonundaki tüm argümanları vererek led'in yanıp sönmesi için Task1 oluşturun.
xTaskCreatePinnedToCore (Task1code, "Task1", 10000, NULL, 1, NULL, 0);
Benzer şekilde, Task2 oluşturmak Task2 ve 7'de temel id 1 yapmak inci tartışma.
xTaskCreatePinnedToCore (Task2code, "Task2", 10000, NULL, 1, NULL, 1);
Görevin karmaşıklığına bağlı olarak önceliği ve yığın boyutunu değiştirebilirsiniz.
2. Şimdi, Task1code ve Task2code fonksiyonunu uygulayacağız. Bu işlevler, gerekli görevin kodunu içerir. Bizim durumumuzda, ilk görev led'i yanıp sönecek ve başka bir görev sıcaklığı getirecektir. Bu nedenle, void kurulum işlevinin dışında her görev için iki ayrı işlev yapın.
0,5 saniye sonra yerleşik led'in yanıp sönmesi için Task1code işlevi aşağıda gösterildiği gibi uygulanır.
Void Task1code (void * parametresi) { Serial.print ("Task1 çekirdekte çalışıyor"); Serial.println (xPortGetCoreID ()); for (;;) {// sonsuz döngü digitalWrite (led, HIGH); gecikme (500); digitalWrite (yol, DÜŞÜK); gecikme süresi (500); } }
Benzer şekilde, sıcaklığı almak için Task2code işlevini uygulayın.
void Task2code (void * pvParameters) { Serial.print ("Task2 çekirdekte çalışıyor"); Serial.println (xPortGetCoreID ()); for (;;) { float t = dht.readTemperature (); Seri.print ("Sıcaklık:"); Seri baskı (t); gecikme (2000); } }
3. Burada boşluk döngüsü işlevi boş kalacaktır. Döngü ve kurulum işlevinin core1 üzerinde çalıştığını zaten bildiğimiz gibi, core1 görevini void döngü işlevinde de uygulayabilirsiniz.
Artık kodlama kısmı bitti, bu yüzden sadece Araçlar menüsünde ESP32 kartını seçerek kodu Arduino IDE kullanarak yükleyin. DHT11 sensörünü ESP32'nin D13 pinine bağladığınızdan emin olun.
Artık sonuçlar Seri Monitör veya Arduino IDE üzerinden aşağıda gösterildiği gibi izlenebilir:
Gerçek zamanlı sistem gibi karmaşık uygulamalar, ESP32'nin çift çekirdeği kullanılarak aynı anda birden fazla görev çalıştırılarak oluşturulabilir.
Demo videosuyla birlikte eksiksiz kod aşağıda verilmiştir.