الحقيقة الكاملة عن RTOS. المادة رقم 16. الإشارات



ستبحث هذه المقالة في الإشارات ، وهي أبسط آليات التفاعل بين المهام في Nucleus SE. أنها توفر طريقة منخفضة التكلفة لنقل الرسائل البسيطة بين المهام.


المقالات السابقة في السلسلة:
المادة رقم 15. أقسام الذاكرة: الخدمات وهياكل البيانات
المادة رقم 14. أقسام الذاكرة: المقدمة والخدمات الأساسية
المادة رقم 13. هياكل بيانات المهام ومكالمات API غير مدعومة
المادة رقم 12. خدمات للعمل مع المهام
المادة رقم 11. المهام: التكوين والمقدمة لواجهة برمجة التطبيقات
المادة رقم 10. المجدول: الميزات المتقدمة والحفاظ على السياق
المادة رقم 9. المجدول: التنفيذ
المادة رقم 8. Nucleus SE: التصميم الداخلي والنشر
المادة رقم 7. Nucleus SE: مقدمة
المادة رقم 6. خدمات RTOS الأخرى
المادة رقم 5. تفاعل المهام والمزامنة
المادة رقم 4. المهام وتبديل السياق والمقاطعات
المادة رقم 3. المهام والتخطيط
المادة رقم 2. RTOS: البنية ووضع الوقت الحقيقي
المادة رقم 1. RTOS: مقدمة.

باستخدام الإشارات


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

يمكن لأي مهمة تعيين إشارات لمهمة أخرى. لا يمكن قراءة الإشارات إلا من قبل مالك الإشارة. أثناء القراءة ، يتم إعادة تعيين الإشارات. لا يمكن للمهام قراءة الإشارات من المهام الأخرى أو إعادة تعيينها.

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

إعداد الإشارة


كما هو الحال مع معظم كائنات Nucleus SE ، يتم ضبط توليف الإشارة بواسطة توجيهات #define في nuse_config.h . المعلمة الرئيسية هي NUSE_SIGNAL_SUPPORT ، التي تنشط دعم الوظائف (لجميع المهام في التطبيق). مسألة الإشارة إلى عدد الإشارات لا تستحق ذلك: يتم تخصيص 8 أعلام لكل مهمة.

يعمل إعداد معلمة التمكين هذه كمنشط للإشارة الرئيسية. وهذا يوفر بنية بيانات محددة جيدًا ذات حجم مناسب. بالإضافة إلى ذلك ، ينشط هذا الخيار إعدادات API.

تنشيط مكالمات API


يتم تنشيط كل وظيفة API (استدعاء فائدة) في Nucleus SE بواسطة توجيه #define في nuse_config.h . بالنسبة للإشارات ، تتضمن هذه:

NUSE_SIGNALS_SEND NUSE_SIGNALS_RECEIVE 

بشكل افتراضي ، يتم تعيينها على FALSE ، وبالتالي تعطيل كل مكالمة خدمة ومنع تشغيل الرمز الذي ينفذها. لتكوين الإشارات في التطبيق ، تحتاج إلى تحديد مكالمات API اللازمة وتعيين التوجيهات المقابلة إلى TRUE .

ما يلي مقتطف من ملف nuse_config.h الافتراضي:

 #define NUSE_SIGNAL_SUPPORT FALSE /* Enables support for signals */ #define NUSE_SIGNALS_SEND FALSE /* Service call enabler */ #define NUSE_SIGNALS_RECEIVE FALSE /* Service call enabler */ 

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

إشارات المكالمة


يدعم Nucleus RTOS أربعة مكالمات عامة تتعلق بالإشارة توفر الوظائف التالية:

  • إرسال إشارات لمهمة معينة. يتم تنفيذ Nucleus SE في دالة NUSE_Signals_Send () .
  • استقبال الإشارات. يتم تنفيذ Nucleus SE في دالة NUSE_Signals_Receive () .
  • تسجيل معالج الإشارة. لم تنفذ في Nucleus SE.
  • تشغيل / إيقاف إشارات (التحكم). لم تنفذ في Nucleus SE.

تمت مناقشة تنفيذ كل من هذه التحديات بالتفصيل أدناه.

خدمات التشوير والاستقبال


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

نظرًا لأن الإشارات هي بتات ، فمن الأفضل تصورها كأرقام ثنائية. نظرًا لأن المعيار C لم يدعم تاريخيًا تمثيل الثوابت الثنائية (فقط الثماني والسداسي العشري) ، فإن Nucleus SE يحتوي على ملف رأس مفيد nuse_binary.h يحتوي على #define أحرف مثل b01010101 لجميع قيم 256 بت 8. ما يلي مقتطف من ملف nuse_binary.h :

 #define b00000000 ((U8) 0x00) #define b00000001 ((U8) 0x01) #define b00000010 ((U8) 0x02) #define b00000011 ((U8) 0x03) #define b00000100 ((U8) 0x04) #define b00000101 ((U8) 0x05) 

إرسال الإشارات


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

اتصل لإرسال إشارات إلى Nucleus RTOS
النموذج الأولي لمكالمة الخدمة:
STATUS NU_Send_Signals (NU_TASK * مهمة ، إشارات غير موقعة) ؛

معلمات:

مهمة - مؤشر إلى وحدة التحكم في المهمة التي تنتمي إليها إشارات الإشارة المضبوطة ؛
الإشارات - قيمة إشارات الإشارة المضبوطة.

القيمة المعادة:

NU_SUCCESS - تم إكمال المكالمة بنجاح ؛
NU_INVALID_TASK - مؤشر غير صالح للمهمة ؛

اتصل لإرسال إشارات إلى Nucleus SE
يدعم اتصال API هذا الوظائف الأساسية لـ Nucleus RTOS API.

النموذج الأولي لمكالمة الخدمة:

STATUS_NUSE_Signals_Send (NUSE_TASK مهمة ، إشارات U8) ؛

معلمات:

مهمة - فهرس (ID) للمهمة التي تنتمي إليها إشارات الإشارة المضبوطة ؛
الإشارات - قيمة إشارات الإشارة المضبوطة.

القيمة المعادة:

NUSE_SUCCESS - تم إتمام مكالمة الخدمة بنجاح ؛
NUSE_INVALID_TASK - فهرس مهمة غير صالح.

تنفيذ التشوير في Nucleus SE
فيما يلي الكود الكامل للدالة NUSE_Signals_Send ():

 STATUS NUSE_Signals_Send(NUSE_TASK task, U8 signals) { #if NUSE_API_PARAMETER_CHECKING if (task >= NUSE_TASK_NUMBER) { return NUSE_INVALID_TASK; } #endif NUSE_CS_Enter(); NUSE_Task_Signal_Flags[task] |= signals; NUSE_CS_Exit(); return NUSE_SUCCESS; } 

الكود بسيط جدا بعد أي تحقق من المعلمات ، تمر قيم الإشارة من خلال عملية OR على أعلام الإشارة للمهمة المحددة. لا يؤثر قفل المهام على الإشارات.

استقبال الإشارات


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

اتصل لتلقي الإشارات في Nucleus RTOS
النموذج الأولي لمكالمة الخدمة:
NU_Receive_Signals (VOID) غير الموقعة ؛

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

القيمة المعادة:
قيم إشارة الإشارة.

اتصل لتلقي الإشارات في Nucleus SE
يدعم اتصال API هذا الوظائف الأساسية لـ Nucleus RTOS API.

النموذج الأولي لمكالمة الخدمة:
U8 NUSE_Signals_Receive (void)؛

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

القيمة المعادة:
قيم إشارة الإشارة.

تنفيذ استقبال إشارة Nucleus SE
التالي هو رمز كامل للدالة NUSE_Signals_Receive () :

 U8 NUSE_Signals_Receive(void) { U8 signals; NUSE_CS_Enter(); Signals = NUSE_Task_Signal_Flags[NUSE_Task_Active]; NUSE_Task_Signal_Flags[NUSE_Task_Active] = 0; NUSE_CS_Exit(); return signals; } 

الكود بسيط جدا يتم نسخ قيمة العلامات ، وتتم إعادة تعيين القيمة الأولية ، ويتم إرجاع النسخة بواسطة وظيفة API. لا يؤثر قفل المهام على الإشارات.

هياكل البيانات


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

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

هيكل البيانات الموضوعة في ذاكرة الوصول العشوائي


هيكل البيانات:
NUSE_Task_Signal_Flags [] - صفيف من النوع U8 مع إدخال واحد لكل مهمة مكونة ، يتم تخزين إشارات الإشارة في هذا الصفيف.

تتم تهيئة بنية البيانات هذه إلى أصفار بواسطة الدالة NUSE_Init_Task () عند تحميل Nucleus SE.

هيكل البيانات الموضوعة في ROM


تفتقر الإشارات إلى هياكل البيانات في ROM.

كميات الذاكرة لتخزين بيانات الإشارة


كما هو الحال مع جميع العناصر الأساسية لـ Nucleus SE ، يمكن توقع مقدار الذاكرة المطلوبة للإشارات.

كمية البيانات في ROM لجميع الإشارات في التطبيق هي 0.

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

مكالمات API غير محققة


لم يتم تنفيذ مكالمتين تشوير Nucleus RTOS API في Nucleus SE:

تسجيل معالج الإشارة


يقوم استدعاء API هذا بإعداد إجراء (وظيفة) معالجة الإشارات للمهمة الحالية. لا يحتاج Nucleus SE إلى هذا لأن معالجات الإشارة غير مدعومة.

النموذج الأولي لمكالمة الخدمة:
STATUS NU_Register_Signal_Handler (VOID (* signal_handler) (غير موقّع)) ؛

معلمات:
signal_handler - وظيفة يجب استدعاؤها عند استقبال الإشارات

القيمة المعادة:
NU_SUCCESS - تم إكمال المكالمة بنجاح ؛
NU_INVALID_POINTER - مؤشر فارغ لمعالج الإشارة ( NULL )

التحكم في (تنشيط / تعطيل) الإشارات


تعمل هذه الخدمة على تنشيط و / أو إلغاء تنشيط الإشارات للمهمة الحالية. لكل مهمة ، تتوفر 32 إشارة. يتم تمثيل كل إشارة بقليل في قناع للإشارة . إضافة القليل من قناع الإشارة_قابلة للتمكين للإشارة المقابلة ، وحذف البت يعطلها.

النموذج الأولي لمكالمة الخدمة:
UNSIGNED NU_Control_Signals (UNSIGNED enable_signal_mask) ؛

معلمات:
enable_signal_mask - نمط بت يمثل الإشارات الصحيحة.

القيمة المعادة:
قناع لتنشيط / إلغاء تنشيط الإشارة السابقة.

متوافق مع Nucleus RTOS


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

معالجات الإشارة


في Nucleus SE ، لا يتم تنفيذ معالجات الإشارة لتبسيط الهيكل العام.

توافر الإشارة وكميتها


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

مكالمات API غير محققة


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

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

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


All Articles