الحقيقة كاملة حول RTOS. المادة رقم 31. التشخيص والخطأ التحقق من RTOS



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

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

سيتم مناقشة كل هذا في هذه المقالة ، إلى جانب بعض الأفكار المتعلقة بالتشخيص من قبل المستخدم.

المقالات السابقة في السلسلة:
المادة رقم 30. نواة SE التهيئة وإجراءات بدء التشغيل
المادة رقم 29. انقطاع في نواة SE
المادة رقم 28. توقيت البرمجيات
المادة رقم 27. وقت النظام
المادة رقم 26. القنوات: الخدمات المساعدة وهياكل البيانات
المادة رقم 25. قنوات البيانات: مقدمة والخدمات الأساسية
المادة رقم 24. قوائم الانتظار: الخدمات المساعدة وهياكل البيانات
المادة رقم 23. قوائم الانتظار: مقدمة والخدمات الأساسية
المادة رقم 22. صناديق البريد: الخدمات المساعدة وهياكل البيانات
المادة رقم 21 صناديق البريد: مقدمة والخدمات الأساسية
المادة رقم 20. Semaphores: الخدمات المساعدة وهياكل البيانات
المادة رقم 19. الإشارات: مقدمة والخدمات الأساسية
المادة رقم 18. مجموعات علم الحدث: خدمات المساعدة وهياكل البيانات
المادة رقم 17. مجموعات علم الحدث: مقدمة والخدمات الأساسية
المادة رقم 16. إشارات
المادة رقم 15. أقسام الذاكرة: الخدمات وهياكل البيانات
المادة رقم 14. أقسام الذاكرة: مقدمة والخدمات الأساسية
المادة رقم 13. بنيات بيانات المهمة ومكالمات API غير المدعومة
المادة رقم 12. خدمات للعمل مع المهام
المادة رقم 11. المهام: التكوين ومقدمة ل API
المادة رقم 10. المجدول: ميزات متقدمة والحفاظ على السياق
المادة رقم 9. المجدول: التنفيذ
المادة رقم 8. نواة SE: التصميم الداخلي والنشر
المادة رقم 7. نواة SE: مقدمة
المادة رقم 6. خدمات RTOS الأخرى
المادة رقم 5. مهمة التفاعل والتزامن
المادة رقم 4. المهام ، تبديل السياق ، و المقاطعات
المادة رقم 3. المهام والتخطيط
المادة رقم 2. RTOS: هيكل ووضع في الوقت الحقيقي
المادة رقم 1. RTOS: مقدمة.


تحقق من الإعدادات


تم تصميم Nucleus SE مع التركيز على قابلية تكوين المستخدم عالية ، والتي ينبغي أن تضمن الاستخدام الأمثل للموارد المتاحة. تعد هذه التكوينية مهمة معقدة ، حيث أن عدد المعلمات الممكنة والترابط بينها كبير. كما هو مذكور في العديد من المقالات السابقة ، يتم تنفيذ معظم خطوات المستخدم لتكوين Nucleus SE باستخدام توجيهات #define في ملف nuse_config.h .

للمساعدة في تحديد أخطاء التكوين ، يتم تضمين ملف nuse_config_check.h في ملف nuse_config.c من خلال #include ، والذي ينفذ اختبارات التكامل على توجيهات #define . فيما يلي مقتطف من هذا الملف:
/*** Tasks and task control ***/ #if NUSE_TASK_NUMBER < 1 || NUSE_TASK_NUMBER > 16 #error NUSE: invalid number of tasks - must be 1-16 #endif #if NUSE_TASK_RELINQUISH && (NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER) #error NUSE: NUSE_Task_Relinquish() selected - not valid with priority scheduler #endif #if NUSE_TASK_RESUME && !NUSE_SUSPEND_ENABLE #error NUSE: NUSE_Task_Resume() selected - task suspend not enabled #endif #if NUSE_TASK_SUSPEND && !NUSE_SUSPEND_ENABLE #error NUSE: NUSE_Task_Suspend() selected - task suspend not enabled #endif #if NUSE_INITIAL_TASK_STATE_SUPPORT && !NUSE_SUSPEND_ENABLE #error NUSE: Initial task state enabled - task suspend not enabled #endif /*** Partition pools ***/ #if NUSE_PARTITION_POOL_NUMBER > 16 #error NUSE: invalid number of partition pools - must be 0-16 #endif #if NUSE_PARTITION_POOL_NUMBER == 0 #if NUSE_PARTITION_ALLOCATE #error NUSE: NUSE_Partition_Allocate() enabled – no partition pools configured #endif #if NUSE_PARTITION_DEALLOCATE #error NUSE: NUSE_Partition_Deallocate() enabled – no partition pools configured #endif #if NUSE_PARTITION_POOL_INFORMATION #error NUSE: NUSE_Partition_Pool_Information() enabled – no partition pools configured #endif #endif 

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

في جميع الحالات ، يؤدي اكتشاف الأخطاء إلى تنفيذ توجيه #error عند التحويل البرمجي. يؤدي هذا عادةً التحويل البرمجي لإيقاف وعرض الرسالة المطابقة.

لا يضمن هذا الملف استحالة إنشاء تكوين / تكوين غير صحيح ، ولكنه يجعله غير مرجح للغاية.

التحقق من إعدادات API


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

يتم تنشيط التحقق من المعلمة عن طريق تعيين المعلمة NUSE_API_PARAMETER_CHECKING في ملف nuse_config.h إلى TRUE . هذا يؤدي إلى تجميع التعليمات البرمجية الإضافية المطلوبة. فيما يلي مثال على التحقق من معلمات دالة API:
 STATUS NUSE_Mailbox_Send(NUSE_MAILBOX mailbox, ADDR *message, U8 suspend) { STATUS return_value; #if NUSE_API_PARAMETER_CHECKING if (mailbox >= NUSE_MAILBOX_NUMBER) { return NUSE_INVALID_MAILBOX; } if (message == NULL) { return NUSE_INVALID_POINTER; } #if NUSE_BLOCKING_ENABLE if ((suspend != NUSE_NO_SUSPEND) && (suspend != NUSE_SUSPEND)) { return NUSE_INVALID_SUSPEND; } #else if (suspend != NUSE_NO_SUSPEND) { return NUSE_INVALID_SUSPEND; } #endif #endif 

قد يؤدي التحقق من المعلمات إلى حقيقة أن استدعاء API سينتج رمز خطأ. إنها قيمة سالبة للنموذج NUSE_INVALID_xxx (على سبيل المثال ، NUSE_INVALID_POINTER ) - يتم تضمين مجموعة كاملة من التعريفات في الملف nuse_codes.h .

لمعالجة قيم الخطأ ، يمكن إضافة رمز تطبيق إضافي (ربما تم إنشاؤه باستخدام الترجمة الشرطية) ، ومع ذلك ، للكشف عنها ، فمن الأفضل استخدام أدوات مراقبة البيانات الخاصة بمصححات البرامج الثابتة الحديثة.

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

التحقق من كومة المهمة


إلى أن يتم استخدام Run to Schedule Scheduler ، يوفر Nucleus SE القدرة على التحقق من رصة المهام ، والتي تشبه وظيفة مشابهة في Nucleus RTOS وتُظهر المساحة المتبقية على الرصة. تم وصف استدعاء الأداة المساعدة API ( NUSE_Task_Check_Stack () ) بالتفصيل في مقالة سابقة (# 12). يتم توفير بعض الأفكار للتحقق من أخطاء المكدس لاحقًا في هذه المقالة في قسم التشخيصات المخصصة.

معلومات الإصدار


Nucleus RTOS و Nucleus SE لديهم وظيفة API تقوم ببساطة بإرجاع معلومات إصدار / بناء kernel.

نواة RTOS API دعوة


نموذج استدعاء الخدمة:
CHAR * NU_Release_Information (VOID) ؛

المعلمات: لا شيء.

قيمة الإرجاع:
مؤشر إلى سلسلة تحتوي على معلومات الإصدار تنتهي بـ بايت فارغة.

Nucleus SE API Call


تدعم مكالمة API هذه الوظيفة الأساسية لـ Nucleus RTOS API.

نموذج استدعاء الخدمة:
char * NUSE_Release_Information (void)؛

المعلمات: لا شيء.

قيمة الإرجاع:
مؤشر إلى سلسلة تحتوي على معلومات الإصدار تنتهي بـ بايت فارغة.

إجراء مكالمة للحصول على معلومات التجميع Nucleus SE


تطبيق استدعاء API هذا بسيط جدًا. يتم إرجاع مؤشر إلى السطر الثابت NUSE_Release_Info ، الذي يتم تعريفه وتهيئته في الملف nuse_globals.c .

يحتوي هذا الخط على شكل Nucleus SE - Xyymmmdd ، حيث:
X - حالة البناء: A = alpha؛ ب = بيتا ؛ ص = الافراج
سنة - سنة الإصدار
مم - شهر الإفراج
يوم الإفراج يوم

نواة RTOS متوافق


Nucleus RTOS يحتوي على دعم اختياري لمجلة السجل. تسجل النواة تفاصيل إجراءات النظام المختلفة. هناك وظائف API التي تسمح للبرامج بـ:
  • تنشيط / إلغاء تنشيط التسجيل ؛
  • إنشاء إدخال دفتر اليومية.
  • الحصول على دخول مجلة.

هذه الميزة غير مدعومة في Nucleus SE.

يحتوي Nucleus RTOS أيضًا على وحدات ماكرو متعددة لإدارة الأخطاء تتيح لك إجراء أي تأكيدات للأخطاء (ASSERT) وتوفر إمكانية الاتصال بوظائف الخطأ الحاسم المعرفة من قبل المستخدم. يتم تضمينها اختياريا في التجمع OS. Nucleus SE لا يدعم هذه الوظيفة.

تشخيص المستخدم


حتى الآن في هذه المقالة ، لقد بحثنا في أدوات التشخيص والتحقق من الأخطاء التي توفرها Nucleus SE نفسها. تجدر الإشارة الآن إلى كيفية تنفيذ أدوات التشخيص التي وضعها المستخدم أو توجيهها إلى تطبيق معين باستخدام الأدوات التي يوفرها kernel و / أو معرفتنا بهيكلها الداخلي وتنفيذها

التشخيصات الخاصة بالتطبيق


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

الشيكات الذاكرة


من الواضح أن تشغيل الذاكرة المناسبة أمر مهم لسلامة أي نظام للمعالج. ليس أقل وضوحًا أن الخطأ الحاسم لن يسمح لك بالتشغيل ، وليس فقط التشخيصات ، بل منتج البرنامج بالكامل ككل ( ملاحظة المترجم: بالمناسبة ، هذه هي الحالة التي درسناها في مقالة "Fake Blue Pill" ). ومع ذلك ، هناك حالات عندما يظهر خطأ معين ، وهو سبب خطير للقلق ، ولكن لا يتعارض مع تنفيذ التعليمات البرمجية. يعد اختبار الذاكرة موضوعًا معقدًا إلى حد ما خارج نطاق هذه المقالة ، لذلك سأقدم فقط بعض الأفكار العامة.

الأخطاء الأكثر شيوعًا التي تحدث في RAM هي:
  • "البتات اللاصقة" عندما تكون قيمة البتة 0 أو 1 ، والتي لا يمكن تغييرها ؛
  • "Crosstalk" عندما تتسبب البتات المجاورة في التداخل مع بعضها البعض.

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

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

خطأ في الذاكرة عنونة المنطق يمكن أن يؤثر على كل من ذاكرة الوصول العشوائي وذاكرة الوصول العشوائي. يمكنك تطوير فحص خاص لهذا الخطأ ، ولكن على الأرجح سيتم اكتشافه كجزء من عمليات الفحص الموضحة أعلاه.

اختبار الأجهزة الطرفية


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

الوكالة الدولية للطاقة الخدمة


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

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

كومة تجاوز السعة الاختيار


إذا لم تستخدم Run to Scheduler ، فسيتم إنشاء مكدس لكل مهمة في تطبيق Nucleus SE. تكامل هذه المكدسات مهم للغاية ، ولكن من المحتمل أن تكون كمية ذاكرة الوصول العشوائي محدودة ، لذلك من المهم جعل حجم التطبيق مثاليًا. من الممكن التنبؤ بشكل ثابت بمتطلبات رصة كل مهمة ، ولكنها صعبة للغاية. يجب أن تكون المجموعة كبيرة بما يكفي حتى بالنسبة للوظائف الأكثر تداخلًا ، جنبًا إلى جنب مع معالج المقاطعة الأكثر تطلبًا. سيكون اتباع نهج أبسط لحل هذه المشكلة هو استخدام اختبار وقت التشغيل الشامل.

بشكل عام ، هناك طريقتان للتحقق من المكدس. إذا كنت تستخدم مصحح أخطاء برنامج مضمن متطور ، يمكن مراقبة حدود المكدس ، وسيتم الكشف عن جميع الانتهاكات. يتوفر موقع وحجم مكدسات Nucleus SE في بنيات بيانات ROM العامة: NUSE_Task_Stack_Base [] و NUSE_Task_Stack_Size [] .

البديل هو اختبار وقت التشغيل. تتمثل الطريقة الشائعة في استخدام "كلمات الحماية" في نهاية كل مكدس ، وعادةً ما يكون العنصر الأول من كل منطقة من بيانات المكدس. تتم تهيئة هذه الكلمات بقيمة غير صفرية معترف بها. تقوم مهمة الخدمة / التشخيص بالتحقق مما إذا كانت هذه الكلمات قد تغيرت ، وتقوم بتنفيذ الإجراءات المناسبة. لا يعني هش كلمة الأمان أن رصة ممتلئة ، ولكن يشير إلى أن هذا على وشك الحدوث. لذلك ، قد يستمر البرنامج في العمل ، فقد تحتاج إلى اتخاذ إجراءات تصحيحية أو الإبلاغ عن خطأ للمستخدم.

مهمة المشرف


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

فيما يلي مثال لكيفية عمل مهمة مماثلة.

تُستخدم إشارات إشارة مهمة المرسل لتتبع تشغيل ست مهام مهمة للنظام. تستخدم كل من هذه المهام علامة محددة (من بت 0 إلى 5 بت) ويجب أن تضبطها بانتظام. تعمل مهمة المرسل على إعادة تعيين جميع الإشارات ، ثم إيقاف عملها لفترة زمنية معينة. عندما تستأنف عملها ، تتوقع أن يتم فحص "المهام" الستة جميعها عن طريق تعيين العلامة المناسبة ، ثم تبحث عن تطابق تام بقيمة b00111111 (من الملف nuse_binary.h ). إذا كان كل شيء يفي بالمتطلبات ، فإنه يعيد تعيين الأعلام ويتوقف مؤقتًا مرة أخرى. إذا لم يكن كذلك ، فإنه يستدعي روتين معالجة الأخطاء الحرجة ، والتي بدورها يمكن ، على سبيل المثال ، إعادة تشغيل النظام.

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

تتبع والتنميط


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

  2. المهمة المخصصة لإلغاء تحميل مخزن معلومات ملف التعريف إلى وحدة التخزين الخارجية ، عادةً إلى الكمبيوتر المضيف.

يتطلب تحليل البيانات التي تم الحصول عليها بهذه الطريقة بعض العمل ، لكنه ليس أكثر تعقيدًا من استخدام جدول بيانات Excel عادي.

في المقالة التالية ، سنبحث بالتفصيل مدى توافق Nucleus SE و Nucleus RTOS.

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

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


All Articles