- مزايا المعالج متعدد النواة
- ESP32 و FreeRTOS
- البحث عن معرّف ESP32 الأساسي
- البرمجة ثنائية النواة ESP32
تشتهر وحدات ESP بوظائف Wi-Fi الخاصة بها مثل ESP8266 و ESP-12E وما إلى ذلك ، وكلها وحدات تحكم دقيقة قوية مع وظائف Wi-Fi. هناك وحدة ESP واحدة أكثر قوة وتنوعًا من وحدات ESP السابقة - اسمها هو ESP32. لديه اتصال Bluetooth و Wi-Fi وقد أوضحنا بالفعل إمكانات BLE لـ ESP32 واستخدمنا ESP32 في العديد من مشاريع إنترنت الأشياء. لكن قلة قليلة من الناس يعرفون أن ESP32 عبارة عن متحكم ثنائي النواة.
يحتوي ESP32 على اثنين من معالجات Tensilica Xtensa LX6 32 بت مما يجعله متحكمًا قويًا ثنائي النواة (core0 و core1). وهي متوفرة في نوعين مختلفين أحادي النواة وثنائي النواة. لكن البديل ثنائي النواة أكثر شيوعًا لأنه لا يوجد فرق كبير في السعر.
يمكن برمجة ESP32 باستخدام Arduino IDE و Espressif IDF و Lua RTOS وما إلى ذلك. أثناء البرمجة باستخدام Arduino IDE ، يعمل الكود فقط على Core1 لأن Core0 مبرمج بالفعل لاتصالات RF. ولكن هنا هذا البرنامج التعليمي سوف نوضح كيفية استخدام كل من نواة ESP32 لإجراء عمليتين في وقت واحد. ستكون المهمة الأولى هنا هي وميض مؤشر LED الموجود على اللوحة ، وستكون المهمة الثانية هي جلب بيانات درجة الحرارة من مستشعر DHT11.
دعونا نرى أولاً مزايا المعالج متعدد النواة على نواة واحدة.
مزايا المعالج متعدد النواة
- تعد المعالجات متعددة النواة مفيدة عندما يكون هناك أكثر من عمليتين للعمل في وقت واحد.
- نظرًا لتوزيع العمل بين النوى المختلفة ، تزداد سرعته ويمكن إنهاء عمليات متعددة في نفس الوقت.
- يمكن تقليل استهلاك الطاقة لأنه عندما يكون أي نواة في وضع الخمول ، يمكن استخدامه لإغلاق الأجهزة الطرفية التي لم تكن قيد الاستخدام في ذلك الوقت.
- يجب أن تقوم المعالجات ثنائية النواة بالتبديل بين الخيوط المختلفة في كثير من الأحيان أقل من المعالجات أحادية النواة لأنها تستطيع التعامل مع اثنين في وقت واحد بدلاً من واحد في كل مرة.
ESP32 و FreeRTOS
تحتوي لوحة ESP32 بالفعل على برنامج FreeRTOS الثابت المثبت عليه. FreeRTOS هو نظام تشغيل في الوقت الحقيقي مفتوح المصدر ومفيد للغاية في تعدد المهام. يساعد نظام RTOS في إدارة الموارد وتعظيم أداء النظام. يحتوي FreeRTOS على العديد من وظائف API لأغراض مختلفة وباستخدام واجهات برمجة التطبيقات هذه ، يمكننا إنشاء مهام وتشغيلها على نوى مختلفة.
يمكن العثور على التوثيق الكامل لواجهات برمجة تطبيقات FreeRTOS هنا. سنحاول استخدام بعض واجهات برمجة التطبيقات في التعليمات البرمجية الخاصة بنا لبناء تطبيق متعدد المهام يعمل على كلا المركزين.
البحث عن معرّف ESP32 الأساسي
هنا سوف نستخدم Arduino IDE لتحميل الكود إلى ESP32. لمعرفة معرف Core الذي يعمل عليه الرمز ، هناك وظيفة API
xPortGetCoreID ()
يمكن استدعاء هذه الوظيفة من وظيفة void setup () و void loop () لمعرفة المعرف الأساسي الذي تعمل عليه هذه الوظائف.
يمكنك اختبار واجهة برمجة التطبيقات هذه عن طريق تحميل الرسم التخطيطي أدناه:
إعداد باطل () { Serial.begin (115200) ؛ Serial.print ("وظيفة setup () تعمل على النواة:") ؛ Serial.println (xPortGetCoreID ()) ، } حلقة فارغة () { Serial.print ("loop () وظيفة تعمل على النواة:")؛ Serial.println (xPortGetCoreID ()) ، }
بعد تحميل الرسم أعلاه ، افتح الشاشة التسلسلية وستجد أن كلتا الوظيفتين تعملان على core1 كما هو موضح أدناه.
من الملاحظات المذكورة أعلاه ، يمكن استنتاج أن رسم Arduino الافتراضي يعمل دائمًا على core1.
البرمجة ثنائية النواة ESP32
يدعم Arduino IDE FreeRTOS لـ ESP32 و FreeRTOS APIs تسمح لنا بإنشاء مهام يمكن تشغيلها بشكل مستقل على كلا النوى. المهمة هي جزء من الكود الذي يقوم ببعض العمليات على السبورة مثل وميض الصمام ، وإرسال درجة الحرارة ، وما إلى ذلك.
تُستخدم الوظيفة أدناه لإنشاء مهام يمكن تشغيلها على كلا المركزين. في هذه الوظيفة ، يتعين علينا تقديم بعض الحجج مثل الأولوية والمعرف الأساسي وما إلى ذلك.
الآن ، اتبع الخطوات التالية لإنشاء وظيفة مهمة ومهمة.
1. أولاً ، قم بإنشاء مهام في وظيفة الإعداد الفارغة . سننشئ هنا مهمتين ، واحدة لوميض LED بعد كل 0.5 ثانية ومهمة أخرى هي الحصول على قراءة درجة الحرارة بعد كل ثانيتين.
تأخذ الدالة xTaskCreatePinnedToCore () 7 وسيطات:
- اسم الوظيفة لتنفيذ المهمة (المهمة 1)
- أي اسم معين للمهمة ("المهمة 1" ، إلخ)
- حجم المكدس المخصص للمهمة بالكلمات (كلمة واحدة = 2 بايت)
- معلمة إدخال المهمة (يمكن أن تكون فارغة)
- أولوية المهمة (0 هي أدنى أولوية)
- مقبض المهمة (يمكن أن يكون فارغًا)
- معرف الأساسية حيث سيتم تشغيل المهمة (0 أو 1)
الآن ، قم بإنشاء Task1 من أجل وميض led عن طريق إعطاء جميع الوسائط في دالة xTaskCreatePinnedToCore ().
xTaskCreatePinnedToCore (Task1code، "Task1"، 10000، NULL، 1، NULL، 0) ؛
وبالمثل، إنشاء Task2 لTask2 وجعل الهوية الأساسية 1 في 7 تشرين حجة.
xTaskCreatePinnedToCore (Task2code، "Task2"، 10000، NULL، 1، NULL، 1) ؛
يمكنك تغيير الأولوية وحجم المكدس اعتمادًا على مدى تعقيد المهمة.
2. الآن، سنقوم بتنفيذ Task1code و Task2code وظيفة. تحتوي هذه الوظائف على رمز المهمة المطلوبة. في حالتنا ، ستومض المهمة الأولى المصباح وستقوم مهمة أخرى بجلب درجة الحرارة. لذا قم بعمل وظيفتين منفصلتين لكل مهمة خارج وظيفة الإعداد الباطلة.
يتم تنفيذ وظيفة Task1code للوميض على اللوحة بعد 0.5 ثانية كما هو موضح أدناه.
باطل Task1code (باطل * معلمة) { Serial.print ("Task1 قيد التشغيل على النواة") ؛ Serial.println (xPortGetCoreID ()) ، لـ (؛ ؛) {// حلقة لانهائية digitalWrite (led ، عالية) ؛ تأخير (500) ؛ digitalWrite (بقيادة، LOW)؛ تأخير (500)؛ } }
وبالمثل ، قم بتنفيذ وظيفة Task2code لجلب درجة الحرارة.
باطل Task2code (void * pvParameters) { Serial.print ("Task2 يعمل على النواة") ؛ Serial.println (xPortGetCoreID ()) ، لـ (؛ ؛) { float t = dht.readTemperature () ؛ Serial.print ("درجة الحرارة:") ؛ Serial.print (t) ؛ تأخير (2000) ؛ } }
3. هنا ستبقى وظيفة الحلقة الفارغة فارغة. ونحن نعلم بالفعل أن حلقة و الإعداد وظيفة يعمل على core1 حتى تتمكن من تنفيذ مهمة core1 في حلقة باطلة وظيفة أيضا.
الآن انتهى جزء الترميز ، لذا ما عليك سوى تحميل الكود باستخدام Arduino IDE عن طريق اختيار لوحة ESP32 في قائمة الأدوات. تأكد من توصيل مستشعر DHT11 بدبوس D13 في ESP32.
الآن يمكن مراقبة النتائج على Serial Monitor أو Arduino IDE كما هو موضح أدناه:
يمكن إنشاء التطبيقات المعقدة مثل نظام الوقت الفعلي عن طريق تشغيل مهام متعددة في وقت واحد باستخدام نوى مزدوجة من ESP32.
كود كامل مع فيديو تجريبي موضح أدناه.