
تواصل هذه المقالة مراجعة علب البريد التي بدأت في المقالة السابقة في سلسلة "الحقيقة حول RTOS".
المقالات السابقة في السلسلة:
المادة رقم 21. صناديق البريد: المقدمة والخدمات الأساسيةالمادة رقم 20. الإشارات: الخدمات المساعدة وهياكل البياناتالمادة رقم 19. الإشارات: المقدمة والخدمات الأساسيةالمادة رقم 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 RTOS على أربعة مكالمات API توفر وظائف مساعدة تتعلق بصناديق البريد: تفريغ صندوق بريد ، واسترداد معلومات حول صندوق بريد ، واسترداد عدد صناديق البريد في تطبيق ، واسترداد مؤشرات إلى جميع صناديق البريد في التطبيق. يتم تنفيذ أول ثلاث من هذه الميزات في Nucleus SE.
إعادة تعيين علبة البريد
يقوم استدعاء خدمة API هذا بإعادة تعيين صندوق البريد إلى حالته الأولية غير المستخدمة. ستفقد الرسالة المخزنة في صندوق البريد. سيتم استئناف أي مهام معلقة في صندوق البريد برمز الإرجاع
NUSE_MAILBOX_WAS_RESET .
اتصل لإعادة ضبط صندوق بريد في Nucleus RTOSالنموذج الأولي لمكالمة الخدمة:
STATUS NU_Reset_Mailbox (صندوق بريد NU_MAILBOX *) ؛معلمات:
صندوق البريد - مؤشر إلى وحدة التحكم في صندوق البريد.
القيمة المعادة:
NU_SUCCESS - تم إكمال المكالمة بنجاح ؛
NU_INVALID_MAILBOX - مؤشر صندوق بريد غير صالح.
استدعاء لإعادة تعيين صندوق بريد في Nucleus SEيدعم استدعاء خدمة API هذا الوظائف الأساسية لـ Nucleus RTOS API.
النموذج الأولي لمكالمة الخدمة:
STATUS NUSE_Mailbox_Reset (صندوق بريد NUSE_MAILBOX) ؛معلمات:
صندوق البريد - فهرس (معرف) صندوق البريد الذي تم تفريغه.
القيمة المعادة:NUSE_SUCCESS - تم إكمال المكالمة بنجاح ؛
NUSE_INVALID_MAILBOX - فهرس صندوق بريد غير صالح.
تنفيذ إعادة تعيين صندوق البريد في Nucleus SEيتم تحديد متغير
رمز وظيفة
NUSE_Mailbox_Reset (بعد التحقق من المعلمات) باستخدام
الترجمة الشرطية ، اعتمادًا على ما إذا كان دعم مهام الحظر (الإيقاف المؤقت) نشطًا أم لا. سننظر في كلا هذين الخيارين.
إذا لم يتم تنشيط القفل ، فإن كود وظيفة واجهة برمجة التطبيقات هذه بسيط جدًا. تم وضع علامة على صندوق البريد على أنه غير مستخدم عن طريق تعيين المعلمة
NUSE_Mailbox_Status [] على
FALSE .
إذا تم تنشيط القفل ، يصبح الرمز أكثر تعقيدًا:
while (NUSE_Mailbox_Blocking_Count[mailbox] != 0) { U8 index; /* check whether any tasks are blocked */ /* on this mailbox */ for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_MAILBOX_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == mailbox)) { NUSE_Task_Blocking_Return[index] = NUSE_MAILBOX_WAS_RESET; NUSE_Task_Status[index] = NUSE_READY; break; } } NUSE_Mailbox_Blocking_Count[mailbox]--; } #if NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER NUSE_Reschedule(NUSE_NO_TASK); #endif
يتم إعادة تعيين صندوق البريد إلى الحالة "Empty".
يتم تعيين الحالة "جاهزة" لكل مهمة معلقة في صندوق البريد برمز الإرجاع
NUSE_MAILBOX_WAS_RESET . بعد اكتمال هذه العملية ، إذا تم استخدام جدولة الأولوية ، يتم
إجراء استدعاء خدمة
NUSE_Reschedule () ، حيث يمكن أن تصبح مهمة أو أكثر ذات أولوية أعلى جاهزة وتنتظر حتى يتم الحصول على إذن للتنفيذ.
استرداد معلومات صندوق البريد
يوفر استدعاء الخدمة هذا مجموعة من معلومات صندوق البريد. يختلف تنفيذ هذه المكالمة في Nucleus SE عن Nucleus RTOS في أنها تُرجع معلومات أقل ، لأن تسمية الكائن وترتيب الإيقاف المؤقت غير مدعومين ، ويمكن تعطيل الإيقاف المؤقت للمهمة.
اتصل للحصول على معلومات صندوق بريد Nucleus RTOSيدعم اتصال API هذا الوظائف الأساسية لـ Nucleus RTOS API.
النموذج الأولي لمكالمة الخدمة:
STATUS NU_Mailbox_Information (NU_MAILBOX * صندوق بريد ، اسم CHAR ، OPTION * suspend_type ، DATA_ELEMENT * message_present ، UNSIGNED * task_waiting ، NU_TASK ** first_task) ؛معلمات:
صندوق البريد - مؤشر إلى وحدة التحكم في صندوق البريد ؛
name - مؤشر من 8 أحرف لاسم صندوق البريد. البايتات الفارغة النهائية مدرجة أيضًا في هذا المجال ؛
suspend_type - مؤشر للمتغير الذي يتم فيه تخزين نوع تعليق المهمة. يمكن أن تأخذ القيم
NU_FIFO و
NU_PRIORITY ؛
message_present - مؤشر لمتغير يأخذ القيمة
NU_TRUE أو
NU_FALSE ، اعتمادًا على ما إذا كان صندوق البريد ممتلئًا أم لا ؛
task_waiting - مؤشر إلى متغير يأخذ عدد المهام المعلقة في صندوق البريد هذا ؛
first_task - مؤشر إلى مؤشر مهمة يأخذ المؤشر إلى أول مهمة متوقفة مؤقتًا.
القيمة المعادة:
NU_SUCCESS - تم إكمال المكالمة بنجاح ؛
NU_INVALID_MAILBOX - مؤشر صندوق بريد غير صالح.
اتصل للحصول على معلومات صندوق بريد Nucleus SEيدعم استدعاء خدمة API هذا الوظائف الأساسية لـ Nucleus RTOS API.
النموذج الأولي لمكالمة الخدمة:
STATUS NUSE_Mailbox_Information (NUSE_MAILBOX mailbox، U8 * message_present، U8 * task_waiting، NUSE_TASK * first_task) ؛معلمات:
صندوق البريد - فهرس صندوق البريد الذي يتم طلب المعلومات حوله ؛
message_present - مؤشر لمتغير يأخذ القيمة
TRUE أو
FALSE ، اعتمادًا على ما إذا كان صندوق البريد ممتلئًا أم لا ؛
task_waiting - مؤشر إلى متغير يأخذ عدد المهام المعلقة في صندوق البريد هذا (لا يتم إرجاع أي شيء إذا تم تعطيل تعليق المهمة) ؛
first_task - مؤشر لمتغير من نوع
NUSE_TASK ، والذي سيأخذ فهرس المهمة الأولى المعلقة (لا يتم إرجاع أي شيء إذا تم تعطيل تعليق المهمة).
القيمة المعادة:
NUSE_SUCCESS - تم إكمال المكالمة بنجاح ؛
NUSE_INVALID_MAILBOX - فهرس صندوق بريد غير صالح ؛
NUSE_INVALID_POINTER - معلمة مؤشر أو أكثر غير صحيحة.
تنفيذ معلومات صندوق البريد في Nucleus SEتنفيذ استدعاء API هذا بسيط للغاية:
*message_present = NUSE_Mailbox_Status[mailbox]; #if NUSE_BLOCKING_ENABLE *tasks_waiting = NUSE_Mailbox_Blocking_Count[mailbox]; if (NUSE_Mailbox_Blocking_Count[mailbox] != 0) { U8 index; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_MAILBOX_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == mailbox)) { *first_task = index; break; } } } else { *first_task = 0; } #else *tasks_waiting = 0; *first_task = 0; #endif return NUSE_SUCCESS;
تقوم الوظيفة بإرجاع حالة صندوق البريد. بعد ذلك ، إذا تم تنشيط مكالمات الخدمة لحظر المهام ، فسيتم إرجاع عدد المهام المعلقة وفهرس المهمة الأولى (وإلا ، يتم تعيين هذه المعلمات إلى 0).
الحصول على عدد صناديق البريد
تقوم استدعاء الأداة المساعدة هذه بإرجاع عدد علب البريد الموجودة في التطبيق. بينما في Nucleus RTOS ، قد يتغير عددها مع مرور الوقت ، وستُظهر القيمة المرتجعة العدد الحالي لصناديق البريد ، في Nucleus SE يتم تعيين عدد صناديق البريد في مرحلة الإنشاء ولا يمكن تغييرها.
استدعاء عداد علبة البريد في Nucleus RTOSيدعم اتصال API هذا الوظائف الأساسية لـ Nucleus RTOS API.
النموذج الأولي لمكالمة الخدمة:
NU_Established_Mailboxes (VOID) غير الموقعة ؛معلمات:
غائبون.
القيمة المعادة:
عدد صناديق البريد التي تم إنشاؤها في التطبيق.
استدعاء عداد علبة البريد في Nucleus SEيدعم اتصال API هذا الوظائف الأساسية لـ Nucleus RTOS API.
النموذج الأولي لمكالمة الخدمة:
U8 NUSE_Mailbox_Count (لاغ) ؛معلمات:
غائبون.
القيمة المعادة:
عدد صناديق البريد التي تم تكوينها في التطبيق.
تنفيذ عداد صندوق البريد في Nucleus SEتنفيذ استدعاء API هذا بسيط للغاية: تم
إرجاع قيمة
#define NUSE_MAILBOX_NUMBER التوجيه.
هياكل البيانات
تستخدم صناديق البريد صفيفين أو ثلاثة من هياكل البيانات (كلها موجودة في ذاكرة الوصول العشوائي) ، والتي ، مثل كائنات Nucleus SE الأخرى ، هي مجموعة من الجداول التي يعتمد حجمها على عدد صناديق البريد التي تم تكوينها ومعلماتها.
أوصي بشدة ألا يستخدم رمز التطبيق الوصول المباشر إلى هياكل البيانات هذه ، ولكنه يشير إليها من خلال وظائف واجهة برمجة التطبيقات المتوفرة. هذا يتجنب عدم التوافق مع الإصدارات المستقبلية من Nucleus SE والآثار الجانبية غير المرغوب فيها ، كما يبسط نقل التطبيق إلى Nucleus RTOS. فيما يلي نظرة عامة تفصيلية على هياكل البيانات لفهم أفضل لكيفية عمل رمز مكالمة الخدمة وللتصحيح.
بيانات ذاكرة الوصول العشوائي
تحتوي هذه البيانات على البنية التالية:
NUSE_Mailbox_Data [] - صفيف من نوع
ADDR يحتوي على إدخال واحد لكل صندوق بريد تم تكوينه ، يقوم بتخزين بيانات صندوق البريد.
NUSE_Mailbox_Status [] هو مصفوفة
U8 لها إدخال واحد لكل صندوق بريد تم تكوينه ، وهي تراقب استخدام صناديق البريد. تشير القيمة غير الصفرية (
TRUE ) إلى أن صندوق البريد ممتلئ.
NUSE_Mailbox_Blocking_Count [] - صفيف من النوع
U8 ، يحتوي على عداد المهام المحظورة لكل صندوق بريد. يتم إنشاء هذا الصفيف فقط إذا تم تنشيط وظيفة حظر مكالمة API.
تتم تهيئة هياكل البيانات هذه
بالأصفار في
دالة NUSE_Init_Mailbox () عند بدء تشغيل Nucleus SE. هذا أمر منطقي ، حيث يتم إنشاء كل صندوق بريد فارغ (غير مستخدم).
فيما يلي تعريفات هياكل البيانات هذه من ملف
nuse_init.c .
RAM ADDR NUSE_Mailbox_Data[NUSE_MAILBOX_NUMBER]; RAM U8 NUSE_Mailbox_Status[NUSE_MAILBOX_NUMBER]; #if NUSE_BLOCKING_ENABLE RAM U8 NUSE_Mailbox_Blocking_Count[NUSE_MAILBOX_NUMBER]; #endif
بيانات ROM
لتنفيذ صناديق البريد ، لا يتم استخدام البيانات في ROM.
مقدار الذاكرة لصناديق البريد
كما هو الحال مع جميع كائنات Nucleus SE kernel ، فإن مقدار الذاكرة المطلوبة لصناديق البريد معروف مسبقًا.
مقدار الذاكرة للبيانات في ROM لجميع علب البريد في التطبيق هو 0.
يمكن حساب كمية البيانات في ذاكرة الوصول العشوائي لجميع صناديق البريد في التطبيق (بالبايت) مع مكالمات API التي تم تنشيطها لحظر المهام على النحو التالي:
NUSE_MAILBOX_NUMBER * (حجم (ADDR) +2)خلاف ذلك:
NUSE_MAILBOX_NUMBER * (حجم (ADDR) +1)مكالمات API غير محققة
لم يتم تنفيذ مكالمات الأداة المساعدة الأربعة التي يمكن العثور عليها في Nucleus RTOS في Nucleus SE.
إنشاء صندوق بريد
يقوم استدعاء خدمة API هذا بإنشاء صندوق بريد. لا يحتاج Nucleus SE إلى ذلك ، حيث يتم إنشاء صناديق البريد بشكل ثابت.
النموذج الأولي لمكالمة الخدمة:
STATUS NU_Create_Mailbox (صندوق بريد NU_MAILBOX * ، اسم CHAR ، خيار غير موقوف suspend_type) ؛معلمات:
صندوق البريد - مؤشر لوحدة تحكم صندوق البريد المقدمة من قبل المستخدم ؛ تُستخدم لإدارة صناديق البريد في مكالمات API الأخرى
name - مؤشر
لاسم مكون من 7 أحرف لصندوق البريد بدون بايت إنهاء ؛
suspend_type - يشير إلى مبدأ تعليق مهمة في صندوق بريد. يمكن أن تأخذ القيم
NU_FIFO و
NU_PRIORITY ، والتي تعني مبدأ FIFO (First-In-First-Out) أو مبدأ أولوية تعليق المهام ، على التوالي.
القيمة المعادة:
NU_SUCCESS - تم إكمال المكالمة بنجاح ؛
NU_INVALID_MAILBOX - مؤشر فارغ لوحدة التحكم في صندوق البريد (
NULL ) ، أو أن المؤشر قيد الاستخدام بالفعل ؛
NU_INVALID_SUSPEND - معلمة
suspend_type غير صالحة.
حذف صندوق بريد
تحذف استدعاء خدمة API صندوق بريد تم إنشاؤه مسبقًا. لا يحتاج Nucleus SE إلى هذا ، لأنه يتم إنشاء صناديق البريد بشكل ثابت ولا يمكن حذفها.
النموذج الأولي لمكالمة الخدمة:
STATUS NU_Delete_Mailbox (صندوق بريد NU_MAILBOX *) ؛معلمات:
صندوق البريد - مؤشر إلى وحدة التحكم في صندوق البريد.
القيمة المعادة:
NU_SUCCESS - تم إكمال المكالمة بنجاح ؛
NU_INVALID_MAILBOX - مؤشر صندوق بريد غير صالح.
مؤشرات صندوق البريد
تشكل مكالمة API هذه قائمة متسلسلة من المؤشرات لجميع صناديق البريد على النظام. لا يحتاج Nucleus SE إلى ذلك ، حيث يتم تحديد صناديق البريد من خلال فهرس بسيط ، وليس مؤشر.
النموذج الأولي لمكالمة الخدمة:
NU_Mailbox_Pointers غير موقعة (NU_MAILBOX ** pointer_list ، غير موقعة الحد الأقصى).معلمات:
pointer_list - المؤشر على مجموعة من المؤشرات
NU_MAILBOX ؛ سيتم ملء هذا الصفيف بمؤشرات صناديق البريد التي تم إنشاؤها في النظام ؛
max_pointers - الحد الأقصى لعدد المؤشرات في المصفوفة.
القيمة المعادة:
عدد مؤشرات
NU_MAILBOX في الصفيف.
تسجيل رسالة في صندوق البريد لتسليمها لجميع المستلمين
يرسل استدعاء الخدمة هذا رسالة إلى جميع المهام التي تنتظر رسائل من صندوق بريد محدد. في Nucleus SE ، لم يتم تنفيذ استدعاء الأداة المساعدة هذا ، لأنه سيضيف تعقيدًا غير ضروري.
النموذج الأولي لمكالمة الخدمة:
STATUS NU_Broadcast_To_Mailbox (صندوق بريد NU_MAILBOX * ، رسالة VOID ، تعليق غير موقَّع) ؛معلمات:
صندوق البريد - مؤشر إلى وحدة التحكم في صندوق البريد ؛
رسالة - مؤشر الرسالة المرسلة ؛
تعليق - يشير إلى ما إذا كان سيتم تعليق مهمة الاتصال إذا كان صندوق البريد يحتوي بالفعل على رسالة ؛ يمكن أن يكون
NU_NO_SUSPEND أو
NU_SUSPEND أو قيمة مهلة.
القيمة المعادة:
NU_SUCCESS - تم إكمال المكالمة بنجاح ؛
NU_INVALID_MAILBOX - مؤشر صندوق البريد غير صالح ؛
NU_INVALID_POINTER - مؤشر فارغ لرسالة (
NULL ) ؛
NU_INVALID_SUSPEND - محاولة التعليق من سلسلة رسائل غير متعلقة بالمهمة ؛
NU_MAILBOX_FULL - صندوق البريد يحتوي بالفعل على رسالة ؛
NU_TIMEOUT - بعد انتهاء المهلة ، لا يزال صندوق البريد ممتلئًا ؛
NU_MAILBOX_DELETED - تم حذف صندوق البريد أثناء تعليق المهمة.
NU_MAILBOX_RESET - تم إعادة ضبط صندوق البريد أثناء تعليق المهمة.
متوافق مع Nucleus RTOS
كما هو الحال مع جميع كائنات Nucleus SE الأخرى ، كان هدفي هو زيادة توافق رمز التطبيق إلى أقصى حد مع Nucleus RTOS. صناديق البريد ليست استثناء ، ومن وجهة نظر المستخدم ، يتم تنفيذها بنفس الطريقة كما في Nucleus RTOS. هناك أيضًا عدم توافق معين ، والذي اعتبرته مقبولًا نظرًا لحقيقة أنه نتيجة لذلك ، ستصبح الشفرة أكثر قابلية للفهم وأكثر كفاءة من حيث حجم الذاكرة المطلوبة. خلاف ذلك ، يمكن نقل مكالمات Nucleus RTOS API مباشرة إلى Nucleus SE.
معرفات الكائن
في Nucleus RTOS ، يتم وصف جميع الكائنات من خلال هياكل البيانات (وحدات التحكم) من نوع معين. يعمل مؤشر وحدة التحكم هذه كمعرف لصندوق البريد. قررت أنه في Nucleus SE ، هناك حاجة إلى نهج مختلف للاستخدام الفعال للذاكرة: يتم وصف جميع كائنات النواة من خلال مجموعة من الجداول في ذاكرة الوصول العشوائي و / أو ROM. يتم تحديد حجم هذه الجداول من خلال عدد الكائنات المكونة لكل نوع. معرف كائن معين هو الفهرس في هذا الجدول. لذا قمت بتعريف
NUSE_MAILBOX كمكافئ لـ
U8 ، وهو متغير (وليس مؤشر) من هذا النوع يعمل
كمعرف لصندوق البريد. من السهل معالجة هذا التعارض البسيط إذا تم نقل الرمز من Nucleus SE إلى Nucleus RTOS والعكس صحيح. عادةً ، لا يتم تنفيذ أي عمليات على معرفات الكائنات بخلاف النقل والتخزين.
يدعم Nucleus RTOS أيضًا تسمية صندوق البريد. يتم استخدام هذه الأسماء فقط لتصحيح الأخطاء. لقد استبعدتهم من Nucleus SE لتوفير الذاكرة.
حجم الرسالة ونوعها
في Nucleus RTOS ، تتكون رسالة صندوق البريد من أربع كلمات 32 بت. في Nucleus SE ، قررت تقليل هذه القيمة إلى متغير واحد من نوع
ADDR . يؤدي هذا التغيير إلى توفير كبير في الذاكرة وتقليل وقت تنفيذ المهام. وتقترح أيضًا أن الاستخدام المعتاد لصندوق البريد هو إعادة توجيه المعلومات من مهمة إلى أخرى. لن يسبب عدم التوافق هذا مشكلات كبيرة عند نقل التطبيقات إلى Nucleus RTOS. يمكن تعديل Nucleus SE إذا كانت هناك حاجة إلى تنسيق رسالة مختلف.
مكالمات API غير محققة
يدعم Nucleus RTOS تسعة مكالمات مكتبية لصندوق البريد. لم يتم تنفيذ أربعة منها في Nucleus SE. تم وصف تفاصيل هذه التحديات ، بالإضافة إلى أسباب استبعادها من Nucleus SE ، أعلاه.
ستنظر المقالة التالية في قوائم الانتظار.
نبذة عن الكاتب: يعمل Colin Walls في صناعة الإلكترونيات لأكثر من ثلاثين عامًا ، ويكرس معظم وقته للبرامج الثابتة. وهو الآن مهندس برامج ثابتة في Mentor Embedded (قسم من Mentor Graphics). غالبًا ما يتحدث كولين وولز في المؤتمرات والندوات ، مؤلف العديد من المقالات الفنية وكتابين عن البرامج الثابتة. يعيش في المملكة المتحدة.
مدونة كولين المهنية ، البريد الإلكتروني: colin_walls@mentor.com.