الحقيقة الكاملة عن RTOS. المادة رقم 9. المجدول: التنفيذ


تم تناول المبادئ الأساسية لعمل مخططي RTOS في مقالة "المهام والتخطيط". في هذه المقالة ، سنلقي نظرة على الميزات التي تقدمها Nucleus RTOS ، بالإضافة إلى تلك التي يوفرها Nucleus SE بمزيد من التفاصيل.


المقالات السابقة في السلسلة:
المادة رقم 8. Nucleus SE: التصميم الداخلي والنشر
المادة رقم 7. Nucleus SE: مقدمة
المادة رقم 6. خدمات RTOS الأخرى
المادة رقم 5. تفاعل المهام والمزامنة
المادة رقم 4. المهام وتبديل السياق والمقاطعات
المادة رقم 3. المهام والتخطيط
المادة رقم 2. RTOS: البنية ووضع الوقت الحقيقي
المادة رقم 1. RTOS: مقدمة.


التخطيط في Nucleus RTOS


نظرًا لأن Nucleus RTOS هو عبارة عن RTOS تجارية راسخة ومتكاملة ، يمكننا أن نفترض بأمان أن الجدولة قد تم تطويرها وفقًا لمتطلبات هذا المنتج. يوفر نظام التشغيل المعقد والمرن هذا للمطور مجموعة كبيرة من الإمكانات لحل أي مهمة برمجة يمكن تصورها في الوقت الفعلي تقريبًا.


يمكن للجدولة دعم عدد غير محدود من المهام (محدودة فقط من خلال الموارد المتاحة) والعمل مع إدارة الأولويات. يمكن تعيين المهمة أولوية من 0 إلى 255 ، حيث 0 هي الأولوية الأعلى و 255 هي الأدنى. للمهمة أولوية ديناميكية ، أي أنه يمكن تغييرها في وقت التشغيل إما بالمهمة نفسها أو بأخرى. يمكن تعيين عدة مهام بنفس مستوى الأولوية. في الحالة القصوى ، يمكن تعيين جميع المهام بنفس الأولوية ، مما يجعل من الممكن تنفيذ سياسة تخطيط على مبدأ Round Robin و Time-Slice.
إذا كانت هناك عدة مهام بنفس الأولوية ، فسيتم جدولتها باستخدام خوارزمية Round Robin بالترتيب الذي تم إعدادها به. تحتاج المهمة إلى إيقاف التحكم مؤقتًا أو نقله حتى تبدأ المهمة التالية. يمكن أيضًا تعيين المهام الفواصل الزمنية التي توفر فصلًا أكثر تحكمًا لوقت المعالج المتاح.


تخطيط المهام هو 100٪ حتمية ، وهو أمر متوقع من جوهر مماثل. يمكن أيضًا إنشاء المهام وتدميرها ديناميكيًا ، وذلك بفضل المجدول ، لا يلاحظه المستخدم.


التخطيط في Nucleus SE


لقد طورت جميع جوانب Nucleus SE بحيث تكون متوافقة بشكل عام مع Nucleus RTOS ، ولكنها أيضًا أبسط وأكثر كفاءة من حيث الذاكرة. المجدول ليس استثناء. يوفر العديد من ميزات Nucleus RTOS Scheduler ، ولكنه محدود إلى حد ما. يتم تحقيق المرونة من خلال التكوين أثناء التجميع.
يمكن أن يحتوي تطبيق Nucleus SE على 16 مهمة كحد أقصى (ومهمة واحدة على الأقل). على الرغم من أنه يمكن زيادة هذا العدد نظريًا ، إلا أن كفاءة الخوارزميات ستكون معرضة للخطر ؛ يعتمد عدد من بنيات البيانات على تخزين رقم فهرس المهام (من 0 إلى 15) في قضم (أربعة بتات) ، وستحتاج إلى معالجتها مع الرمز المقابل.


لتحقيق التوازن بين المرونة والبساطة (والحجم) ، بدلاً من أن يكون لديك برنامج جدولة واحد مع العديد من القدرات ، يقدم Nucleus SE واحدًا من أربعة أنواع من برامج الجدولة للاختيار من بينها: Run to Component (RTC) ، Round Robin (RR) ، Time-Slice ( TS) والأولوية. يتم تحديد المجدول بشكل ثابت في وقت التجميع. يتم وصف التفاصيل حول كل نوع من أنواع المجدول أدناه في قسم "أنواع الجدولة".


مثل أي جانب آخر من Nucleus SE ، تعد المهام كائنات ثابتة. يتم تحديدها أثناء التكوين ، ولا يمكن تغيير أولويتها (الفهرس).


مخططو Nucleus SE


كما هو مذكور أعلاه ، تقدم Nucleus SE أحد أربعة أنواع من برامج الجدولة للاختيار من بينها. مثل معظم جوانب تكوين Nucleus SE ، يتم تحديد هذا الاختيار عن طريق الكتابة إلى nuse_config.h ، يجب تعيين المعلمة NUSE_SCHEDULER_TYPE وفقًا لذلك ، كما هو موضح في هذا الجزء من ملف التكوين:



بغض النظر عن الجدول الزمني المحدد ، يتم استدعاء رمز بدء التشغيل الخاص به فور تهيئة النظام. سيتم تقديم معلومات كاملة حول تهيئة Nucleus SE في المقالة التالية.


تشغيل إلى مجدول الإنجاز


يعد RTC Scheduler هو الحل الأسهل والأنسب إذا استوفى متطلبات التطبيق. يجب أن تكمل كل مهمة عملها قبل أداء وظيفة الإرجاع والسماح للجدولة بإكمال المهمة التالية.


ليست هناك حاجة إلى تكديس منفصل لكل مهمة. كل التعليمات البرمجية مكتوبة بلغة C ، لغة التجميع غير مطلوبة. أدناه هو رمز جدولة RTC بأكمله.



الرمز هو مجرد حلقة لا نهائية تتناوب على استدعاء كل مهمة. يحتوي الصفيف NUSE_Task_Start_Address [] على مؤشرات الوظيفة الخارجية لكل مهمة. الماكرو PF0 هو تحويل بسيط لمؤشر باطل إلى مؤشر لدالة باطلة بدون معلمات. تم تصميمه لضمان سهولة قراءة التعليمات البرمجية.
يتم استخدام الترجمة الشرطية لتمكين الدعم للوظائف الإضافية: NUSE_SUSPEND_ENABLE يحدد ما إذا كان يمكن تعليق المهام ؛ يحدد NUSE_SCHEDULE_COUNT_SUPPORT ما إذا كانت قيمة العداد مطلوبة في كل مرة يتم فيها جدولة مهمة. يمكن العثور على مزيد من المعلومات حول هذا في المقالة التالية.


جدولة جولة روبن


إذا كانت هناك حاجة إلى مرونة أكثر قليلاً مما يوفره جدولة RTC ، فإن جدولة RR مناسبة. يسمح للمهمة بنقل التحكم أو الإيقاف المؤقت ، ثم المتابعة من نفس النقطة. زيادة إضافية ، بالإضافة إلى تعقيد التعليمات البرمجية وعدم إمكانية النقل ، هو أن كل مهمة تتطلب مكدس خاص بها.
يتكون رمز المجدول من جزأين. مكون الإطلاق على النحو التالي:



إذا تم تمكين دعم الحالة الأولية للمهمة (باستخدام المعلمة NUSE_INITIAL_TASK_STATE_SUPPOR T ، راجع "المعلمات" في المقالة التالية) ، يبدأ التخطيط من أول مهمة منتهية ؛ وإلا ، يتم استخدام مهمة مع الفهرس 0. ثم يتم تحميل سياق هذه المهمة باستخدام NUSE_Context_Load () . لمزيد من المعلومات حول حفظ السياق واستعادته ، راجع قسم "حفظ السياق" في المقالة التالية.


الجزء الثاني من المجدول هو مكون "إعادة التخطيط":



يتم استدعاء هذا الرمز عندما تحرر المهمة المعالج المركزي أو تتوقف مؤقتًا.


يحدد الكود المهمة باستخدام الفهرس التالي للبدء ويضع القيمة في NUSE_Task_Next ، مع مراعاة ما إذا كان تعليق المهمة ممكّنًا أم لا. يتم بعد ذلك استخدام ماكرو NUSE_CONTEXT_SWAP () لاستدعاء تبديل السياق باستخدام مقاطعة البرنامج. لمزيد من المعلومات حول حفظ السياق واستعادته ، راجع قسم "حفظ السياق" في المقالة التالية.


جدولة الأولويات


تم تصميم جدولة الأولوية في Nucleus SE ، مثل الخيارات الأخرى ، لتوفير الوظائف المطلوبة ، مع كونها بسيطة للغاية. ونتيجة لذلك ، فإن لكل مهمة أولوية فريدة ، فمن المستحيل أن يكون هناك عدة مهام ذات مستوى أولوية واحد. يتم تحديد الأولوية بواسطة فهرس المهمة ، حيث يمثل 0 أعلى مستوى من الأولوية. يتم تحديد فهرس المهمة من خلال موقعها في الصفيف NUSE_Task_Start_Address []. ستقدم المقالة التالية معلومات أكثر تفصيلاً حول إعداد المهام.


مثل جدولة RR و TS ، جدولة الأولوية لها مكونان. إن مكون بدء التشغيل الخاص بجدولة الأولوية هو نفس جدولة RR و TS ، كما هو موضح أعلاه. يختلف عنصر إعادة الجدولة قليلاً:



لا يوجد رمز شرطي يمكن أن يعطل تعليق المهام ، لأن هذه الميزة إلزامية لجدولة الأولوية ؛ سيكون أي بديل غير منطقي. تقبل الدالة NUSE_Reschedule () معلمة "تخبر" بالمهمة التي يمكن جدولتها بعد ذلك - new_task. يتم تعيين هذه القيمة عند استدعاء إعادة الجدولة بسبب استدعاء مهمة أخرى. يتم تمرير فهرس هذه المهمة كمعلمة. يمكن للجدولة بعد ذلك تحديد ما إذا كان سيتم إجراء تبديل السياق من خلال مقارنة قيمة new_task بفهرس المهمة الحالية (NUSE_Task_Active) . إذا كانت إعادة الجدولة نتيجة لإيقاف مهمة مؤقتًا ، فسيتم تعيين المعلمة على NUSE_NO_TASK ، وسيبحث المجدول عن المهمة ذات الأولوية الأعلى.


حالات المهمة


كقاعدة عامة ، تحتوي جميع أنظمة التشغيل على مفهوم العثور على المهام في "حالة" معينة. تختلف التفاصيل حسب RTOS. في هذه المقالة ، سنلقي نظرة على كيفية استخدام Nucleus RTOS و Nucleus SE لحالات المهام.


دول مهام Nucleus RTOS


يدعم Nucleus RTOS 5 حالات مهام.


  • التنفيذ: المهمة التي تدير المعالج حاليًا. من الواضح أن مهمة واحدة فقط يمكنها احتلال هذه الدولة.
  • الجاهزية: مهمة جاهزة للتنفيذ (أو لمواصلة التنفيذ) قبل أن يقرر المخطط إطلاقها. عادةً ما تكون للمهمة أولوية أقل من تلك التي يتم تنفيذها.
  • التعليق: مهمة "النوم". لا يؤخذ في الاعتبار أثناء التخطيط حتى يستيقظ ، وفي هذه اللحظة سيكون "جاهزًا" وقد يستمر في التنفيذ لاحقًا. عادة ما تكون المهمة في حالة "سكون" لأنها تنتظر شيئًا ما: عندما يصبح المورد متاحًا ، أو عندما تنتهي الفترة الزمنية المحددة ، أو عندما توقظ مهمة أخرى.
  • إلغاء: المهمة "قتلت". لا تؤخذ في الاعتبار أثناء التخطيط حتى يتم إعادة تعيينها ، وبعد ذلك ستكون المهمة "جاهزة" أو "معلقة".
  • الإنهاء: اكتمال المهمة وإنهاء وظيفتها الخارجية بمجرد ترك الوحدة الخارجية أو بتنفيذ بيان الإرجاع. لا تؤخذ في الاعتبار أثناء التخطيط حتى يتم إعادة تعيينها ، وبعد ذلك ستكون المهمة "جاهزة" أو "معلقة".
نظرًا لأن Nucleus RTOS يدعم الإنشاء الديناميكي للأشياء وتدميرها ، بما في ذلك المهام ، يمكن أيضًا اعتبار المهمة في حالة "بعيدة". ومع ذلك ، نظرًا لأنه بمجرد حذف المهمة ، تنتهي جميع موارد النظام الخاصة بها ولم تعد المهمة نفسها موجودة ، فلا يمكن أن يكون لها حالة. قد يكون رمز المهمة متاحًا ، ولكن يجب إنشاء كائن المهمة مرة أخرى.

حالات المهمة في Nucleus SE


نموذج حالة المهمة في Nucleus SE أبسط قليلاً. عادة ما تكون هناك 3 حالات فقط: التنفيذ والتوافر والإيقاف المؤقت. يتم تخزين حالة كل مهمة في NUSE_Task_Status [] ، التي تحتوي على قيم من النوع NUSE_READY ، على الرغم من أنها لا تحتوي أبدًا على قيمة تعكس حالة التنفيذ. إذا لم يتم تمكين تعليق المهمة (راجع "خيارات" في المقالة التالية) ، فهناك حالتان فقط من المهام ممكنة ، وهذا الصفيف غير موجود.

هناك عدة أنواع من مهام الإيقاف المؤقت. إذا تم تعليق مهمة بشكل صريح من تلقاء نفسها أو من قبل مهمة أخرى ، فإن هذا يُسمى "تعليق صاف" ويتم تمثيله بالحالة NUSE_PURE_SUSPEND. إذا كانت حالة "السكون" قيد التشغيل وتم تعليق المهمة لفترة معينة من الوقت ، فستكون لها الحالة
NUSE_SLEEP_SUSPEND . إذا تم تمكين وظيفة حظر مكالمات API (عبر NUSE_BLOCKING_ENABLE ، راجع "المعلمات" في المقالة التالية) ، يمكن تعليق المهمة حتى يصبح المورد متاحًا. كل نوع من الكائنات له حالة تعليق مهمة خاصة به ، على سبيل المثال ، في شكل NUSE_MAILBOX_SUSPEND. في Nucleus SE ، يمكن قفل المهمة في قسم الذاكرة أو مجموعة الأحداث أو صندوق البريد أو قائمة الانتظار أو القناة أو الإشارة.

حالة الخيط


عند مناقشة سلوك المهمة ، يتم عادةً استخدام الكلمتين "الحالة" و "الحالة" بحرية تامة. هناك عامل إضافي ، يمكن تسميته بشكل مشروط "حالة التدفق". هذا هو المتغير العام NUSE_Thread_State ، والذي يحتوي على مؤشر لطبيعة الشفرة التي يتم تنفيذها. ينطبق هذا على سلوك العديد من مكالمات API. القيم الممكنة:

  • NUSE_TASK_CONTEXT - تم إجراء استدعاء API من مهمة.
  • NUSE_STARTUP_CONTEXT - تم إجراء مكالمة API من رمز بدء التشغيل ؛ المجدول لم يبدأ بعد.
  • NUSE_NISR_CONTEXT و NUSE_MISR_CONTEXT - تم إجراء استدعاء API من معالج المقاطعة. ستتم مناقشة المقاطعات في Nucleus SE في المقالة التالية.

ستعرض المقالة التالية تفاصيل ميزات الجدولة المتقدمة في Nucleus SE ، بالإضافة إلى الحفاظ على السياق.

نبذة عن الكاتب: يعمل Colin Walls في صناعة الإلكترونيات لأكثر من ثلاثين عامًا ، ويكرس معظم وقته للبرامج الثابتة. وهو الآن مهندس برامج ثابتة في Mentor Embedded (قسم من Mentor Graphics). غالبًا ما يتحدث كولين وولز في المؤتمرات والندوات ، مؤلف العديد من المقالات الفنية وكتابين عن البرامج الثابتة. يعيش في المملكة المتحدة. مدونة Colin Professional ، البريد الإلكتروني: colin_walls@mentor.com

Source: https://habr.com/ru/post/ar422615/


All Articles