
سبق ذكر مجموعات من علامات الحدث في إحدى المقالات السابقة (رقم 5). في Nucleus SE ، تشبه الإشارات ، ولكنها أكثر مرونة. توفر طريقة منخفضة التكلفة ومرنة لنقل الرسائل البسيطة بين المهام.
المقالات السابقة في السلسلة:
المادة رقم 16. الإشاراتالمادة رقم 15. أقسام الذاكرة: الخدمات وهياكل البياناتالمادة رقم 14. أقسام الذاكرة: المقدمة والخدمات الأساسيةالمادة رقم 13. هياكل بيانات المهام ومكالمات API غير مدعومةالمادة رقم 12. خدمات للعمل مع المهامالمادة رقم 11. المهام: التكوين والمقدمة لواجهة برمجة التطبيقاتالمادة رقم 10. المجدول: الميزات المتقدمة والحفاظ على السياقالمادة رقم 9. المجدول: التنفيذالمادة رقم 8. Nucleus SE: التصميم الداخلي والنشرالمادة رقم 7. Nucleus SE: مقدمةالمادة رقم 6. خدمات RTOS الأخرىالمادة رقم 5. تفاعل المهام والمزامنةالمادة رقم 4. المهام وتبديل السياق والمقاطعاتالمادة رقم 3. المهام والتخطيطالمادة رقم 2. RTOS: البنية ووضع الوقت الحقيقي
المادة رقم 1. RTOS: مقدمة.
باستخدام أعلام الأحداث
في Nucleus SE ، يتم تحديد علامات الأحداث أثناء مرحلة البناء. الحد الأقصى لعدد مجموعات علامات الأحداث في التطبيق هو 16. إذا لم يتم تحديد مجموعات علامات الأحداث ، فلن يتم تضمين الرمز المتعلق بهياكل البيانات واستدعاءات الخدمة لمجموعات علامات الأحداث في التطبيق.
مجموعة من علامات الأحداث - مجموعة من إشارات ثمانية بت ، يتم تنظيم الوصول إليها بحيث يمكن للعديد من المهام استخدام علامة واحدة بأمان. يمكن لمهمة واحدة تعيين أو مسح أي مجموعة من علامات الأحداث. مهمة أخرى هي قراءة مجموعة من العلامات في أي وقت ، ويمكنها أيضًا انتظار تسلسل معين من العلامات (عن طريق الاستطلاع أو مع توقف مؤقت).
تكوين مجموعات علامات الأحداث
عدد مجموعات علامة الحدث
كما هو الحال مع معظم كائنات Nucleus SE ، يتم تحديد تكوين مجموعات
علامات الأحداث من خلال توجيهات
#define في
nuse_config.h . المعلمة الرئيسية هي
NUSE_EVENT_GROUP_NUMBER ، والتي تحدد عدد مجموعات علامات الأحداث التي سيتم تحديدها في التطبيق. بشكل افتراضي ، يتم تعيين هذه المعلمة على 0 (أي ، لا يتم استخدام مجموعات من علامات الأحداث) ويمكن أن يكون لها أي قيمة حتى 16. ستؤدي القيمة غير الصحيحة إلى خطأ في
الترجمة ، والذي سيتم إنشاؤه عن طريق التحقق في
nuse_config_check.h (يتم تمكينه بواسطة
nuse_config.c ، مما يعني أنه يجمع مع هذه الوحدة) ، ونتيجة لذلك ، سيعمل التوجيه
#error . يعمل تحديد قيمة غير صفرية كمنشط رئيسي لمجموعات علامات الحدث. يتم استخدام هذه المعلمة عند تحديد هياكل البيانات ويعتمد حجمها على قيمتها (المزيد عن هذا في المقالات التالية). بالإضافة إلى ذلك ، تعمل القيمة غير الصفرية على تنشيط إعدادات واجهة برمجة التطبيقات.
تنشيط مكالمات API
يتم تنشيط كل وظيفة API (استدعاء فائدة) في Nucleus SE بواسطة توجيه
#define في
nuse_config.h . بالنسبة لمجموعات علامات الأحداث ، تتضمن ما يلي:
NUSE_EVENT_GROUP_SET
NUSE_EVENT_GROUP_RETRIEVE
NUSE_EVENT_GROUP_INFORMATION
NUSE_EVENT_GROUP_COUNT
بشكل افتراضي ، يتم تعيينها على
FALSE ، وبالتالي تعطيل كل استدعاء خدمة وحظر تضمين التعليمات البرمجية التي تنفذها. لتكوين مجموعات من علامات الأحداث ، تحتاج إلى تحديد مكالمات API اللازمة وتعيين التوجيهات المقابلة إلى
TRUE .
ما يلي مقتطف من ملف nuse_config.h الافتراضي.
#define NUSE_EVENT_GROUP_NUMBER 0 #define NUSE_EVENT_GROUP_SET FALSE #define NUSE_EVENT_GROUP_RETRIEVE FALSE #define NUSE_EVENT_GROUP_INFORMATION FALSE #define NUSE_EVENT_GROUP_COUNT FALSE
ستؤدي وظيفة واجهة برمجة التطبيقات (API) التي تم تنشيطها في حالة عدم وجود مجموعات
علامات للأحداث في التطبيق إلى خطأ في
الترجمة ( باستثناء
NUSE_Event_Group_Count () ، الذي يتم تمكينه دائمًا). إذا كان الرمز الخاص بك يستخدم استدعاء API لم يتم تنشيطه ، فسيحدث خطأ تخطيط لأن كود التنفيذ لم يتم تضمينه في التطبيق.
مكالمات الأداة المساعدة لحدث الحدث
يدعم Nucleus RTOS سبع مكالمات مفيدة توفر الوظائف التالية:
- تعيين علامات الحدث. يتم تنفيذ Nucleus SE في دالة NUSE_Event_Group_Set () .
- قراءة أعلام الحدث. في Nucleus SE ، تم التنفيذ في NUSE_Event_Group_Retrieve () .
- توفير معلومات حول مجموعة معينة من علامات الأحداث. في Nucleus SE ، تم التنفيذ في NUSE_Event_Group_Information () .
- إرجاع عدد مجموعات علامات الأحداث التي تم تكوينها حاليًا في التطبيق. في Nucleus SE ، تم التنفيذ في NUSE_Event_Group_Count () .
- إضافة مجموعة جديدة من علامات الأحداث إلى التطبيق. لم يتم تنفيذ Nucleus SE.
- إزالة مجموعة من علامات الحدث من التطبيق. لم يتم تنفيذ Nucleus SE.
- إرجاع المؤشرات إلى جميع مجموعات علامات الأحداث في التطبيق. لم يتم تنفيذ Nucleus SE.
تمت مناقشة تنفيذ كل من هذه المكالمات العامة بالتفصيل أدناه.
تجدر الإشارة إلى أنه لا توجد وظيفة إعادة تعيين في Nucleus RTOS أو Nucleus SE. يتم ذلك عمدا. تشير وظيفة إعادة الضبط إلى انتشار الحالة الخاصة للأعلام. بالنسبة لمجموعات علامات الأحداث ، فإن الحالة "الخاصة" الوحيدة هي إعادة تعيين جميع العلامات ، والتي يمكن القيام بها باستخدام
NUSE_Event_Group_Set () .
تستدعي الخدمة لإعداد وقراءة مجموعات علامات الأحداث
تحدد العمليات الأساسية التي يمكن إجراؤها على مجموعة من علامات الأحداث قيمة علامة واحدة أو أكثر ، بالإضافة إلى قراءة قيم العلامة الحالية. يوفر Nucleus RTOS و Nucleus SE أربع مكالمات API أساسية لهذه العمليات.
نظرًا لأن أعلام الأحداث هي بتات ، فمن الأفضل تصورها كأرقام ثنائية. نظرًا لأن المعيار C لم يدعم تاريخيًا تمثيل الثوابت الثنائية (فقط الثماني والسداسي العشري) ، فإن Nucleus SE يحتوي على ملف رأس مفيد
nuse_binary.h يحتوي على
#define أحرف مثل
b01010101 لجميع قيم 256 بت 8.
تعيين علامات الأحداث
إن استدعاء الأداة المساعدة Nucleus RTOS API للإبلاغ يتسم بالمرونة للغاية ويسمح لك بتعيين قيم العلامات ومسحها باستخدام عمليات
AND و
OR . يوفر Nucleus SE وظائف مماثلة ، ولكن التوقف المؤقت للمهمة اختياري.
اتصل لتعيين الأعلام في Nucleus RTOSالنموذج الأولي لمكالمة الخدمة:
STATUS NU_Set_Events (NU_EVENT_GROUP * group، UNSIGNED event_flags، OPTION operation)؛معلمات:
مجموعة - مؤشر إلى كتلة تحكم مقدمة من قبل المستخدم لمجموعة من علامات الأحداث ؛
event_flags - قيمة قناع البتات لمجموعة العلم ؛
العملية -
العملية التي سيتم تنفيذها ،
NU_OR (لإعداد الأعلام) أو
NU_AND (
لمسح الأعلام).
القيمة المعادة:
NU_SUCCESS - تم إكمال المكالمة بنجاح ؛
NU_INVALID_GROUP - مؤشر غير صالح لمجموعة من علامات الأحداث ؛
NU_INVALID_OPERATION - تختلف العملية المحددة عن
NU_OR و
NU_AND .
دعوة لوضع الأعلام في Nucleus SEيدعم اتصال API هذا الوظائف الأساسية لـ Nucleus RTOS API.
النموذج الأولي لمكالمة الخدمة:
STATUS NUSE_Event_Group_Set (مجموعة NUSE_EVENT_GROUP ، U8 event_flags ، عملية OPTION) ؛معلمات:
مجموعة - الفهرس (ID) لمجموعة الأحداث التي تم تعيين / مسح أعلامها ؛
event_flags - قيمة البتات
القصوى لمجموعة من الأعلام ؛
العملية -
العملية التي سيتم تنفيذها ،
NUSE_OR (
لتعيين الأعلام) أو
NUSE_AND (
لمسح الأعلام).
القيمة المعادة:
NUSE_SUCCESS - تم إكمال المكالمة بنجاح ؛
NUSE_INVALID_GROUP - فهرس غير صالح لمجموعة من علامات الأحداث ؛
NUSE_INVALID_OPERATION - تختلف العملية المحددة عن
NUSE_OR و
NUSE_AND .
تنفيذ تركيب أعلام الأحداث في Nucleus SEيعد الرمز الأولي
لوظيفة NUSE_Event_Group_Set () API عامًا (بعد التحقق من المعلمات) ، بغض النظر عما إذا كان دعم API لحظر المكالمات (تعليق المهمة) قد تم تنشيطه أم لا. المنطق بسيط جدا:
NUSE_CS_Enter(); if (operation == NUSE_OR) { NUSE_Event_Group_Data[group] |= event_flags; } else /* NUSE_AND */ { NUSE_Event_Group_Data[group] &= event_flags; }
يتم
وضع قناع البت event_flags متراكب (باستخدام العملية
AND أو
OR ) على قيمة مجموعة علامات الحدث المحددة.
لا يتم تمكين الرمز المتبقي إلا عند تنشيط تأمين المهام:
#if NUSE_BLOCKING_ENABLE while (NUSE_Event_Group_Blocking_Count[group] != 0) { U8 index; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_EVENT_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == group)) { NUSE_Task_Blocking_Return[index] = NUSE_SUCCESS; NUSE_Task_Status[index] = NUSE_READY; break; } } NUSE_Event_Group_Blocking_Count[group]--; } #if NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER NUSE_Reschedule(NUSE_NO_TASK); #endif #endif NUSE_CS_Exit(); return NUSE_SUCCESS;
إذا تم إيقاف أي مهام مؤقتًا (للقراءة) من هذه المجموعة من العلامات ، فسيتم استئنافها. عندما تتاح لهم الفرصة لمواصلة التنفيذ (يعتمد ذلك على المجدول) ، يمكنهم تحديد ما إذا كانت شروط استئنافهم مستوفاة أم لا (انظر إشارات حدث القراءة).
قراءة أعلام الحدث
تعد مكالمات الأداة المساعدة Nucleus RTOS API للقراءة مرنة للغاية وتسمح لك بإيقاف المهام مؤقتًا إلى أجل غير مسمى أو مع مهلة محددة إذا تعذر تنفيذ العملية على الفور (على سبيل المثال ، إذا حاولت قراءة تسلسل معين من علامات الأحداث التي لا تمثل الحالة الحالية). يوفر Nucleus SE نفس الميزات ، والإيقاف المؤقت للمهمة فقط اختياري ، ولم يتم تنفيذ المهلة.
تحدي الأعلام في Nucleus RTOSالنموذج الأولي لمكالمة الخدمة:
STATUS NU_Retrieve_Events (NU_EVENT_GROUP * group، UNSIGNED required_events، OPTION operation، UNSIGNED * extractified_events، UNSIGNED suspend)؛معلمات:
مجموعة - مؤشر إلى كتلة تحكم مقدمة من قبل المستخدم لمجموعة من علامات الأحداث ؛
required_events - قناع بت يحدد الأعلام المطلوب قراءتها ؛
العملية - تتوفر أربع
عمليات :
NU_AND و
NU_AND_CONSUME و
NU_OR و
NU_OR_CONSUME . تشير
عمليتا NU_AND و
NU_AND_CONSUME إلى أن جميع العلامات المطلوبة مطلوبة. تشير
عمليتا NU_OR و
NU_OR_CONSUME إلى أن واحدة أو أكثر من العلامات المطلوبة كافية. تقوم المعلمة
CONSUME بمسح العلامات الموجودة تلقائيًا بعد نجاح الطلب ؛
extracteved_events - مؤشر التخزين لقيم إشارات الحدث المقروء ؛
تعليق - مواصفات
لإيقاف المهام مؤقتًا ؛ يمكن أن تأخذ القيم
NU_NO_SUSPEND أو
NU_SUSPEND ، أو قيمة المهلة في علامات التجزئة
لمؤقت النظام (من 1 إلى 4،294،967،293).
القيمة المعادة:
NU_SUCCESS - تم إكمال المكالمة بنجاح ؛
NU_NOT_PRESENT - العملية المحددة لم تُرجع الأحداث (وليس حدثًا واحدًا في حالة NU_OR وليس كل الأحداث في حالة NU_AND) ؛
NU_INVALID_GROUP - مؤشر غير صالح لمجموعة من علامات الأحداث ؛
NU_INVALID_OPERATION - العملية المحددة غير صحيحة ؛
NU_INVALID_POINTER - مؤشر فارغ إلى مخزن إشارات الحدث (NULL) ؛
NU_INVALID_SUSPEND - محاولة الإيقاف المؤقت من سلسلة
محادثات لا تتعلق بالمهمة ؛
NU_TIMEOUT - لم يتم تعيين مجموعة علامات الحدث المطلوبة حتى بعد المهلة المحددة ؛
NU_GROUP_DELETED - تم حذف مجموعة علامات الحدث أثناء تعليق المهمة.
تحدي الأعلام في Nucleus SEيدعم اتصال API هذا الوظائف الأساسية لـ Nucleus RTOS API.
النموذج الأولي لمكالمة الخدمة:
STATUS NUSE_Event_Group_Retrieve (NUSE_EVENT_GROUP group، U8 required_events، OPTION operation، U8 * Retired_events، U8 suspend)؛معلمات:
مجموعة - فهرس (ID) لمجموعة قراءة إشارات الحدث ؛
required_events - قناع بت يحدد الأعلام المطلوب قراءتها ؛
العملية - مواصفات تشير إلى عدد الأعلام المطلوبة:
NUSE OR (بعض الأعلام) أو
NUSE AND (جميع الأعلام) ؛
extracteved_events - مؤشر إلى المتجر للقيم الفعلية لأعلام حدث القراءة (مع عملية
NUSE_AND ، سيكون هذا هو نفسه الذي تم تمريره في معلمة
required_events ) ؛
تعليق - مواصفات
لإيقاف مهمة مؤقتًا ؛ يمكن أن تأخذ القيم
NUSE_NO_SUSPEND أو
NUSE_SUSPEND .
القيمة المعادة:
NUSE_SUCCESS - تم إكمال المكالمة بنجاح ؛
NUSE_NOT_PRESENT - العملية المحددة لم تُرجع الأحداث (وليس حدثًا واحدًا في حالة
NUSE_OR وليس كل الأحداث في حالة
NUSE_AND ) ؛
NUSE_INVALID_GROUP - فهرس غير صالح لمجموعة من علامات الأحداث ؛
NUSE_INVALID_OPERATION - تختلف العملية المحددة عن
NUSE_OR أو
NUSE_AND ؛
NUSE_INVALID_POINTER - مؤشر فارغ إلى متجر إشارات الحدث المقروء (
NULL ) ؛
NUSE_INVALID_SUSPEND - محاولة للإيقاف المؤقت من تدفق غير مهمة أو عندما يتم تعطيل دعم حظر مكالمات API.
تنفيذ قراءة إشارة الحدث في Nucleus SEيتم تحديد إصدار رمز وظيفة واجهة برمجة التطبيقات
NUSE_Event_Group_Retrieve () (بعد التحقق من المعلمات) أثناء
الترجمة الشرطية اعتمادًا على ما إذا كان دعم مكالمات API لحظر (التوقف المرحلي) يتم تنشيطه أم لا. دعونا نفكر في هذين الخيارين بشكل منفصل.
إذا تم تعطيل القفل ، فسيبدو الرمز الكامل لاستدعاء API هذا كما يلي:
temp_events = NUSE_Event_Group_Data[group] & requested_events; if (operation == NUSE_OR) { if (temp_events != 0) { return_value = NUSE_SUCCESS; } else { return_value = NUSE_NOT_PRESENT; } } else /* operation == NUSE_AND */ { if (temp_events == requested_events) { return_value = NUSE_SUCCESS; } else { return_value = NUSE_NOT_PRESENT; } }
يتم تحديد علامات الحدث المطلوبة من مجموعة علامة الحدث المحددة. تتم مقارنة القيمة بالأحداث المطلوبة ، مع الأخذ بعين الاعتبار عملية
AND / OR ، بالإضافة إلى النتيجة التي تم إرجاعها والقيم الفورية للأعلام المطلوبة.
إذا تم تنشيط تأمين المهام ، يصبح الرمز أكثر تعقيدًا:
do { temp_events = NUSE_Event_Group_Data[group] & requested_events; if (operation == NUSE_OR) { if (temp_events != 0) { return_value = NUSE_SUCCESS; } else { return_value = NUSE_NOT_PRESENT; } } else { if (temp_events == requested_events) { return_value = NUSE_SUCCESS; } else { return_value = NUSE_NOT_PRESENT; } } if (return_value == NUSE_SUCCESS) { suspend = NUSE_NO_SUSPEND; } else { if (suspend == NUSE_SUSPEND) { NUSE_Event_Group_Blocking_Count[group]++; NUSE_Suspend_Task(NUSE_Task_Active, (group << 4) | NUSE_EVENT_SUSPEND); return_value = NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value != NUSE_SUCCESS) { suspend = NUSE_NO_SUSPEND; } } } } while (suspend == NUSE_SUSPEND);
يتم وضع الكود في حلقة
do ... while ، والتي تعمل بينما تكون معلمة
الإيقاف المؤقت NUSE_SUSPEND .
تتم قراءة علامات الحدث المطلوبة كما لو تم استدعاؤها دون حظر. إذا لم تنجح القراءة وكانت معلمة
التوقف المرحلي NUSE_NO_SUSPEND ، يتم تعيين استدعاء API إلى
NUSE_NOT_PRESENT . إذا تم تعيين معلمة
التوقف المرحلي إلى
NUSE_SUSPEND ، تتوقف المهمة مؤقتًا. عند العودة (عند استئناف المهمة) ، إذا كانت القيمة
المرجعة هي
NUSE_SUCCESS ، مشيرة إلى أنه تم استئناف المهمة لأنه تم تعيين أو مسح علامات الحدث في هذه المجموعة ، تبدأ الدورة من البداية ، ويتم قراءة العلامات وفحصها. نظرًا لعدم وجود وظيفة API لإعادة تعيين مجموعات
علامات الأحداث ، فهذا هو السبب الوحيد لاستئناف المهمة ، ولكن تم ترك عملية التحقق
NUSE_Task_Blocking_Return [] على النظام لتوافق التحكم في القفل مع أنواع أخرى من الكائنات.
تصف المقالة التالية مكالمات API الإضافية المرتبطة بمجموعات علامات الأحداث ، بالإضافة إلى هياكل البيانات الخاصة بها.
نبذة عن الكاتب: يعمل Colin Walls في صناعة الإلكترونيات لأكثر من ثلاثين عامًا ، ويكرس معظم وقته للبرامج الثابتة. وهو الآن مهندس برامج ثابتة في Mentor Embedded (قسم من Mentor Graphics). غالبًا ما يتحدث كولين وولز في المؤتمرات والندوات ، مؤلف العديد من المقالات الفنية وكتابين عن البرامج الثابتة. يعيش في المملكة المتحدة.
مدونة كولين المهنية ، البريد الإلكتروني: colin_walls@mentor.com.