
تم ذكر الإشارات في إحدى المقالات السابقة (رقم 5). مهمتهم الرئيسية هي التحكم في الوصول إلى الموارد.
المقالات السابقة في السلسلة:
المادة رقم 18. مجموعات علامات الأحداث: خدمات المساعدة وهياكل البياناتالمادة رقم 17. مجموعات علامة الحدث: المقدمة والخدمات الأساسيةالمادة رقم 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 إشارة. إذا لم يتم تحديد الإشارات ، لا يتم تضمين رمز مكالمات الخدمة وهياكل البيانات في التطبيق.
الإشارة عبارة عن عداد من النوع
U8 ، يتم التحكم في الوصول إليه بطريقة يمكن استخدامها في العديد من المهام. يمكن أن تقلل المهمة من قيمة عداد الإشارة (الالتقاط) أو زيادتها (الإصدار). قد تؤدي محاولة التقاط إشارة مع قيمة صفر إلى حدوث خطأ أو تعليق مهمة ، اعتمادًا على معلمات استدعاء API المحددة وتكوين Nucleus SE.
إنشاء الإشارات
عدد الاشارة
كما هو الحال مع معظم كائنات Nucleus SE ، يتم تحديد إعداد الإشارات بواسطة توجيهات
#define في
nuse_config.h . المعلمة الرئيسية هي
NUSE_SEMAPHORE_NUMBER ، والتي تحدد عدد الإشارات في التطبيق. بشكل افتراضي ، يتم تعيين المعلمة على 0 (لا تستخدم الإشارات في التطبيق) ويمكن أن تأخذ أي قيم حتى 16. ستؤدي القيمة غير الصحيحة إلى خطأ في
الترجمة ، والذي سيتم إنشاؤه عن طريق التحقق في
nuse_config_check.h (هذا الملف مضمن في
nuse_config.c ، مما يعني أنه يجمع جنبا إلى جنب مع هذه الوحدة) ، ونتيجة لذلك ، سيتم توجيه # خطأ.
اختيار قيمة غير صفرية بمثابة المنشط الرئيسي للأشكال. يتم استخدام هذه المعلمة عند تحديد هياكل البيانات ويعتمد حجمها على قيمتها (لمزيد من التفاصيل ، انظر المزيد في هذه المقالة). بالإضافة إلى ذلك ، تعمل القيمة غير الصفرية على تنشيط إعدادات واجهة برمجة التطبيقات.
تنشيط مكالمات API
يتم تنشيط كل وظيفة API (استدعاء فائدة) في Nucleus SE بواسطة توجيه
#define في
nuse_config.h . بالنسبة إلى الإشارة ، تتضمن:
NUSE_SEMAPHORE_OBTAIN
NUSE_SEMAPHORE_RELEASE
NUSE_SEMAPHORE_RESET
NUSE_SEMAPHORE_INFORMATION
NUSE_SEMAPHORE_COUNT
بشكل افتراضي ، يتم تعيينها على
FALSE ، وبالتالي تعطيل كل استدعاء خدمة وحظر تضمين التعليمات البرمجية التي تنفذها. لإعداد الإشارات ، تحتاج إلى تحديد مكالمات API اللازمة وتعيين التوجيهات المقابلة إلى
TRUE .
ما يلي مقتطف من ملف
nuse_config.h الافتراضي.
#define NUSE_SEMAPHORE_NUMBER 0 #define NUSE_SEMAPHORE_OBTAIN FALSE #define NUSE_SEMAPHORE_RELEASE FALSE #define NUSE_SEMAPHORE_RESET FALSE #define NUSE_SEMAPHORE_INFORMATION FALSE #define NUSE_SEMAPHORE_COUNT FALSE
ستؤدي وظيفة API التي تم تنشيطها في حالة عدم وجود إشارات في التطبيق إلى خطأ في
الترجمة ( باستثناء
NUSE_Semaphore_Count () ، والذي يتم تمكينه دائمًا). إذا كان الرمز الخاص بك يستخدم استدعاء API لم يتم تنشيطه ، فسيحدث خطأ تخطيط لأن كود التنفيذ لم يتم تضمينه في التطبيق.
مكالمات إشارة فائدة
يدعم Nucleus RTOS ثماني مكالمات خدمة توفر الوظائف التالية:
- التقاط الإشارة. يتم تنفيذ Nucleus SE في دالة NUSE_Semaphore_Obtain () .
- تحرير إشارة. في Nucleus SE ، يتم تنفيذه في دالة NUSE_Semaphore_Release () .
- إعادة الإشارة إلى حالة غير مستخدمة مع تحرير جميع المهام المتوقفة مؤقتًا (إعادة التشغيل). يتم تنفيذ Nucleus SE في NUSE_Semaphore_Reset () .
- توفير معلومات حول إشارة معينة. يتم تنفيذ Nucleus SE في NUSE_Semaphore_Information () .
- إرجاع عدد الإشارات التي تم تكوينها في التطبيق. تم تنفيذ Nucleus SE في NUSE_Semaphore_Count () .
- إضافة إشارة جديدة إلى التطبيق. لم يتم تنفيذ Nucleus SE.
- إزالة الإشارة من التطبيق. لم يتم تنفيذ Nucleus SE.
- إرجاع المؤشرات إلى كافة الإشارات. لم يتم تنفيذ Nucleus SE.
يتم وصف تنفيذ كل مكالمة خدمة بالتفصيل أدناه.
مكالمات المساعدة لالتقاط وإصدار الإشارات
العمليات الأساسية التي يمكن إجراؤها على الإشارات هي التقاط وإطلاق (انخفاض وزيادة القيمة). يوفر Nucleus RTOS و Nucleus SE مكالمتين أساسيتين لواجهة برمجة التطبيقات لهذه العمليات.
التقاط الإشارة
إن استدعاء الأداة المساعدة Nucleus RTOS لالتقاط إشارة مرور مرنة للغاية ويسمح لك بإيقاف المهام مؤقتًا بشكل ضمني أو مع مهلة محددة إذا تعذر تنفيذ العملية في الوقت الحالي ، على سبيل المثال ، إذا حاولت التقاط إشارة مع قيمة صفرية. يوفر Nucleus SE نفس الميزات ، فقط التوقف المؤقت للمهمة هو اختياري ، ولا يتم تنفيذ المهلة.
تحدي التقاط الإشارة في Nucleus RTOSالنموذج الأولي لمكالمة الخدمة:
STATUS NU_Obtain_Semaphore (إشارة NU_SEMAPHORE * ، غير معلقة) ؛معلمات:
إشارة الإشارة - مؤشر إلى كتلة تحكم الإشارة التي يوفرها المستخدم ؛
الإيقاف - معلمة تعليق المهمة ، يمكن أن تأخذ القيم
NU_NO_SUSPEND أو
NU_SUSPEND ، بالإضافة إلى قيمة المهلة.
القيمة المعادة:
NU_SUCCESS - تم إكمال المكالمة بنجاح ؛
NU_UNAVAILABLE - الإشارة لها قيمة خالية ؛
NU_INVALID_SEMAPHORE - مؤشر غير صالح إلى إشارة ؛
NU_INVALID_SUSPEND - محاولة الإيقاف المؤقت من سلسلة
محادثات لا تتعلق بالمهمة ؛
NU_SEMAPHORE_WAS_RESET - تم إعادة ضبط الإشارة بينما تم تعليق المهمة.
تحدي التقاط الإشارة في Nucleus SEيدعم اتصال API هذا الوظائف الأساسية لـ Nucleus RTOS API.
النموذج الأولي لمكالمة الخدمة:
STATUS NUSE_Semaphore_Obtain (إشارة NUSE_SEMAPHORE ، تعليق U8) ؛معلمات:
إشارة - فهرس (معرف) الإشارة المستخدمة ؛
الإيقاف - معلمة تعليق المهمة ، يمكن أن تكون
NUSE_NO_SUSPEND أو
NUSE_SUSPEND .
القيمة المعادة:
NUSE_SUCCESS - تم إكمال المكالمة بنجاح ؛
NUSE_UNAVAILABLE - الإشارة لها قيمة خالية ؛
NUSE_INVALID_SEMAPHORE - فهرس إشارة غير صالح ؛
NUSE_INVALID_SUSPEND - محاولة للتوقف مؤقتًا من سلسلة
محادثات لا تتعلق بالمهمة أو عند تعطيل وظيفة حظر واجهة برمجة التطبيقات ؛
NUSE_SEMAPHORE_WAS_RESET - تم إعادة ضبط الإشارة بينما تم تعليق المهمة ؛
تنفيذ التقاط الإشارة في Nucleus SEيتم تحديد إصدار رمز الوظيفة
NUSE_Semaphore_Obtain () (بعد التحقق من المعلمات) باستخدام
الترجمة الشرطية اعتمادًا على ما إذا كان دعم مهام الحظر (الإيقاف المؤقت) نشطًا أم لا. فكر في كلا الخيارين.
إذا لم يتم تنشيط القفل ، فإن منطق استدعاء API هذا بسيط جدًا:
if (NUSE_Semaphore_Counter[semaphore] != 0) /* semaphore available */ { NUSE_Semaphore_Counter[semaphore]--; return_value = NUSE_SUCCESS; } else /* semaphore unavailable */ { return_value = NUSE_UNAVAILABLE; }
يتم التحقق من قيمة عداد الإشارة ، وإذا لم تكن تساوي الصفر ، تنخفض.
إذا تم تنشيط تأمين المهام ، يصبح المنطق أكثر تعقيدًا:
do { if (NUSE_Semaphore_Counter[semaphore] != 0) /* semaphore available */ { NUSE_Semaphore_Counter[semaphore]--; return_value = NUSE_SUCCESS; suspend = NUSE_NO_SUSPEND; } else /* semaphore unavailable */ { if (suspend == NUSE_NO_SUSPEND) { return_value = NUSE_UNAVAILABLE; } else { /* block task */ NUSE_Semaphore_Blocking_Count[semaphore]++; NUSE_Suspend_Task(NUSE_Task_Active, semaphore << 4) | NUSE_SEMAPHORE_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_SUCESS .
إذا كانت الإشارة فارغة ولا يتم تعيين متغير
التوقف المرحلي إلى
NUSE_NO_SUSPEND ، ترجع استدعاء API
NUSE_UNAVAILABLE . إذا تم ضبط التعليق على
NUSE_SUSPEND ، تتوقف المهمة مؤقتًا. بعد اكتمال المكالمة (على سبيل المثال ، عند استئناف المهمة) ، إذا كانت القيمة
المرجعة هي
NUSE_SUCCESS (مما يشير إلى أنه تم استئناف المهمة بعد تحرير الإشارة ، وليس بعد إعادة
التعيين ) ، تبدأ الدورة من البداية.
الافراج سيمافور
استدعاء الأداة المساعدة لـ Nucleus RTOS API لتحرير إشارة المرور بسيط للغاية: تزداد قيمة عداد الإشارة وتعاد رسالة النجاح. يوفر Nucleus SE نفس الميزات ، ولكن مع فحص إضافي للتدفق.
تحدي لإطلاق الإشارات في Nucleus RTOSالنموذج الأولي لمكالمة الخدمة:
STATUS NU_Release_Semaphore (NU_SEMAPHORE * semaphore) ،معلمات:
إشارة -
إشارة إلى كتلة تحكم إشارة يوفرها المستخدم.
القيمة المعادة:
NU_SUCCESS - تم إكمال المكالمة بنجاح ؛
NU_INVALID_SEMAPHORE - مؤشر إشارة
غير صالح .
تحدي لإطلاق إشارة في Nucleus SEيدعم اتصال API هذا الوظائف الأساسية لـ Nucleus RTOS API.
النموذج الأولي لمكالمة الخدمة:
STATUS NUSE_Semaphore_Release (إشارة NUSE_SEMAPHORE) ؛معلمات:
إشارة - فهرس (إشارة) الإشارة المحررة.
القيمة المعادة:
NUSE_SUCCESS - تم إكمال المكالمة بنجاح ؛
NUSE_INVALID_SEMAPHORE - فهرس إشارة غير صالح ؛
NUSE_UNAVAILABLE - إشارة الإشارة لها قيمة 255 ولا يمكن زيادتها.
تنفيذ إطلاق إشارة في Nucleus SEرمز الوظيفة
NUSE_Semaphore_Release () (بعد التحقق من المعلمات) شائع ، بغض النظر عما إذا كان قفل المهمة
نشطًا أم لا. يتم التحقق من قيمة عداد الإشارة ، وإذا كانت أقل من 255 ، فإنها تزداد.
يتم تحديد رمز إضافي باستخدام الترجمة الشرطية إذا تم تنشيط دعم مكالمات حظر API (تعليق المهمة):
NUSE_CS_Enter(); if (NUSE_Semaphore_Counter[semaphore] < 255) { NUSE_Semaphore_Counter[semaphore]++; return_value = NUSE_SUCCESS; #if NUSE_BLOCKING_ENABLE if (NUSE_Semaphore_Blocking_Count[semaphore] != 0) { U8 index; NUSE_Semaphore_Blocking_Count[semaphore]--; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_SEMAPHORE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == semaphore)) { NUSE_Task_Blocking_Return[index] = NUSE_SUCCESS; NUSE_Wake_Task(index); break; } } } #endif } else { return_value = NUSE_UNAVAILABLE; } NUSE_CS_Exit(); return return_value;
إذا تم تعليق أي مهام في هذه الإشارة ، يتم استئناف أولها.
تصف المقالة التالية مكالمات API الإضافية المرتبطة بالأشكال وبنى البيانات الخاصة بها.
نبذة عن الكاتب: يعمل Colin Walls في صناعة الإلكترونيات لأكثر من ثلاثين عامًا ، ويكرس معظم وقته للبرامج الثابتة. وهو الآن مهندس برامج ثابتة في Mentor Embedded (قسم من Mentor Graphics). غالبًا ما يتحدث كولين وولز في المؤتمرات والندوات ، مؤلف العديد من المقالات الفنية وكتابين عن البرامج الثابتة. يعيش في المملكة المتحدة.
مدونة كولين المهنية ، البريد الإلكتروني: colin_walls@mentor.com.