في واحدة من الملاحظات السابقة ، حاول المؤلف أن يجادل بأنه عند برمجة المتحكم الدقيق ، سيكون التبديل البسيط للمهمة مفيدًا في الحالات التي يكون فيها استخدام نظام التشغيل في الوقت الفعلي كبيرًا للغاية ، وتكون الحلقة الشاملة لجميع الإجراءات المطلوبة قليلة جدًا ( قال ، مثل الكونت دي لا فير). بتعبير أدق ، ليس قليلًا جدًا ، لكن مرتبكًا جدًا.
في ملاحظة لاحقة ، كان من المخطط تبسيط الوصول إلى الموارد التي تشترك فيها عدة مهام باستخدام قوائم الانتظار استنادًا إلى المخازن المؤقتة للحلقات (FIFOs) ومهمة منفصلة مخصصة لهذا الغرض. بعد تشتيت المهام المختلفة تلك الإجراءات التي لا ترتبط ببعضها البعض ، يحق لنا أن نتوقع رمزًا أكثر وضوحًا. وإذا حصلنا في الوقت نفسه على بعض الراحة والبساطة ، فلماذا لا نجربها؟
من الواضح أن المتحكم الدقيق غير مصمم لحل أي مهمة يمكن تصورها للمستخدم. بعد ذلك ، ربما ، سيثبت وحدة تبديل المهام هذه أنها كافية تمامًا في العديد من الحالات. باختصار ، من غير المحتمل أن تتأذى تجربة صغيرة. لذلك ، لكي لا يكون بلا أساس ، قرر خادمك المتواضع أن يكتب شيئًا وأن يختبر خبرائه.
في المتحكمات الدقيقة ، لا بد لي من القول ، إن الشرط الواجب حسابه مع مرور الوقت باعتباره شيئًا مهمًا ومتشددًا أكثر شيوعًا من أجهزة الكمبيوتر متعددة الأغراض. تجاوز الإطار في الحالة الأولى يعادل عدم قابلية التشغيل ، وفي الحالة الثانية ، يؤدي فقط إلى زيادة في وقت الانتظار ، وهو أمر مقبول تمامًا إذا كانت الأعصاب في حالة جيدة. هناك حتى فترتان "الوقت الحقيقي الناعم" و "الوقت الحقيقي الصعب".
اسمحوا لي أن أذكرك ، كنا نتحدث عن وحدات التحكم مع كورتيكس- M3،4،7 الأساسية. اليوم هي عائلة شائعة جدا. في الأمثلة أدناه ، استخدمنا متحكم STM32F303 ، وهو جزء من لوحة STM32F3DISCOVERY.
رمز التبديل هو ملف مجمع واحد.
المجمع لا يخاف المؤلف ، ولكن على العكس من ذلك ، يلهم الأمل في تحقيق أقصى سرعة.
في البداية ، تم التخطيط لأبسط منطق لعملية التبديل ، وهو موضح في الشكل 1 لمدة ثماني مهام.

في هذا المخطط ، تستغرق المهام جزءًا من الوقت واحدًا تلو الآخر ، ويمكنها فقط إعطاء باقي علامة التجزئة ، وإذا لزم الأمر ، تخطي عددًا قليلاً من علامات التجزئة. أثبت هذا المنطق أنه جيد ، لأنه يمكن جعل حجم الكم صغيرًا. وهذا هو بالضبط ما هو مطلوب من أجل عدم إثارة مهمة على وجه السرعة وقع فيها انقطاع للتو ، وأيضًا رفعها ، ثم خفض أولوياتها. الحزمة التي تم استلامها للتو ستنتظر بهدوء 200-300 ميكروثانية حتى تستلم مهمتها علامة. وإذا كان لدينا Cortex-M7 يعمل بتردد قدره 216 ميجاهرتز ، فسيكون 20 ميكروثانية لكل علامة واحدة أمرًا معقولًا للغاية ، لأن الأمر سيستغرق أقل من نصف ميكروثانية للتبديل. ولن تكون أي مهمة من المثال أعلاه متأخرة أكثر من 140 ميكروثانية.
ومع ذلك ، مع زيادة عدد المهام ، حتى مع وجود حجم صغير للغاية من مقدار الوقت ، قد يتوقف التأخير في بدء نشاط المهمة المطلوبة عن السعادة. بناءً على ذلك ، ومع الأخذ في الاعتبار أن جزءًا صغيرًا فقط من المهام يتطلب وقتًا صعبًا في الوقت الحقيقي ، فقد تقرر تعديل منطق المفتاح قليلاً. يظهر في الشكل 2.

الآن نختار فقط جزءًا من المهام التي تتلقى كمية كاملة ، ونختار علامة واحدة فقط للباقي ، حيث يتناوبون في اللعبة. في هذه الحالة ، يتلقى روتين التهيئة الأولي معلمة إدخال ، وهي رقم الموضع ، بدءًا من جميع المهام التي ستتأثر بالحقوق وستشارك علامة واحدة. في الوقت نفسه ، ظل النظام القديم متاحًا ، ولهذا يكفي تعيين قيمة المعلمة على صفر أو إجمالي عدد المهام. زيادة تكاليف التحويل عن طريق عدد قليل من الإرشادات المجمّع.
يتم استخدام نظامين مماثلين للسماح بالوصول إلى الموارد المشتركة. الأول ، الذي تم ذكره في ملاحظة سابقة ، يستخدم العديد من FIFOs (أو المخازن المؤقتة الدائرية حسب عدد منتجي الرسائل) ومهمة مطابقة منفصلة. إنه مصمم للتواصل مع العالم الخارجي ولا يتطلب توقعات من المهام التي تولد الرسائل. من الضروري فقط التأكد من عدم ازدحام قوائم الانتظار.
يستخدم المخطط الثاني أيضًا مهمة منفصلة للسماح بالوصول ، ولكنه يقدم التوقعات لأنه يدير المورد الداخلي في كلا الاتجاهين. لا يمكن ربط هذه الإجراءات بالوقت. ويبين الشكل 3 مكونات الدائرة الثانية.

العناصر الرئيسية فيه هي مخزن مؤقت للطلبات ، وفقًا لعدد المهام المطلوبة ومؤشر وصول واحد. تشغيل هذا التصميم بسيط للغاية. ترسل المهمة الموجودة على اليسار طلب وصول إلى مكان مخصص له بشكل خاص (على سبيل المثال ، تكتب المهمة 2 من 1 إلى طلب 2). المهمة - يقوم المرسل بتحديد من يسمح له وكتابة رقم المهمة المحددة في علامة الدقة. المهمة التي حصلت على إذن بتنفيذ إجراءاتها وكتابة علامة نهاية الوصول إلى الطلب ، القيمة 0xFF. يقوم برنامج الجدولة ، الذي يرى أنه تم مسح الطلب ، بإعادة تعيين علامة الإذن ، وإعادة تعيين الطلب الأخير وإعادة تعيين الطلب من مهمة أخرى.
يمكن الاطلاع هنا على مشروعين للاختبار تحت IAR ووصف للوحة STM32F3DISCOVERY المستخدمة. في المشروع الأول ، فحص ATS303 ببساطة أدائه وتصحيحه. جميع المصابيح المثبتة في هذا المنتدى أصبحت في متناول اليدين. لم يصب أحد بأذى.
اختبر المسودة الثانية لـ BTS303 خياري تخصيص الموارد المذكورين. في ذلك ، تقوم المهام 1 و 2 بإنشاء رسائل اختبار يتلقاها المشغل. للتواصل مع المشغل ، اضطررت إلى إضافة وشاح بمنفذ TTL COM ، كما هو موضح في الصورة أدناه.

يستخدم المشغل المحاكي الطرفي. أعتقد أن القارئ سوف يعذر المؤلف عن لون الأنبوب الناعم. يبدو مثل هذا.

لبدء النظام بالكامل ، قبل حل الانقطاعات ، تكون الخطوات الأولية مطلوبة في نص مهمة صفر الرئيسية () ، والتي ترد أدناه.
void main_start_task_switcher(U8 border); U8 task_run_and_return_task_number((U32)t1_task); U8 task_run_and_return_task_number((U32)t2_task); U8 task_run_and_return_task_number((U32)t3_human_link); U8 task_run_and_return_task_number((U32)t4_human_answer); U8 task_run_and_return_task_number((U32)task_5); U8 task_run_and_return_task_number((U32)task_6); U8 task_run_and_return_task_number((U32)task_7);
في هذه السطور ، يبدأ المحول أولاً ، ثم ، بدوره ، المهام السبع المتبقية.
هنا هو الحد الأدنى لمجموعة من المكالمات المطلوبة لهذه المهمة.
void task_wake_up_action(U8 taskNumber);
يتم استخدام هذه المكالمة في مقاطعة من جهاز توقيت المستخدم. التحديات من المهام نفسها تتحدث عن نفسها.
void release_me_and_set_sleep_steps(U32 ticks); U8 get_my_number(void);
كل هذه الوظائف موجودة في ملف تبديل المجمّع. هناك العديد من الوظائف المفيدة للاختبار ، ولكنها غير مطلوبة.
في مشروع BTS303 ، تستقبل المهمة 3 أوامر المشغل من الخارج وترسل إليه الإجابات التي تأتي من المهمة 4. المهمة 4 تستقبل الأوامر من المشغل من المهمة 3 وتنفذها بالإجابات المحتملة. تستلم المهمة 3 أيضًا رسائل من المهمتين 1 و 2 وترسلها عبر UART إلى المحاكي الطرفي (على سبيل المثال ، المعجون).
المهمة 0 (الرئيسية) تقوم ببعض الأعمال المساعدة ، على سبيل المثال ، تتحقق من عدد الكلمات التي لم تتأثر في المنطقة المكدسة لكل مهمة. يمكن للمشغل طلب هذه المعلومات والحصول على فكرة عن استخدام المكدس. في البداية ، يتم تخصيص مساحة مكدس من 512 بايت (128 كلمة) لكل مهمة ومن الضروري مراقبة (على الأقل في مرحلة التصحيح) أن هذه المناطق لا تقترب من تجاوز السعة.
المهام 5 و 6 القيام بحسابات على بعض متغير الفاصلة العائمة الشائعة. للقيام بذلك ، يطلبون الوصول إليه من المهمة 7.
هناك ميزة إضافية أخرى يمكن رؤيتها في مشاريع الاختبار. تم تصميمه بحيث يمكنك إيقاظ المهمة ليس بعد انتهاء صلاحية عدد علامات التجزئة ، ولكن بعد وقت محدد ، ويبدو ذلك.
void wake_me_up_after_milliSeconds(U32 timeMS);
لتنفيذه ، يلزم أيضًا جهاز توقيت إضافي للأجهزة ، والذي يتم تنفيذه أيضًا في حالات الاختبار.
كما ترون ، فإن قائمة جميع المكالمات الضرورية يتم وضعها على صفحة واحدة.