
بعد استراحة قصيرة ، نواصل نشر ترجمات The Whole Truth About RTOS بواسطة Colin Walls. سنتحدث هذه المرة عن قنوات نقل البيانات (المشار إليها فيما يلي باسم القنوات) ، والتي سبق ذكرها في إحدى المقالات السابقة ، وهي بالتحديد
رقم 5 . توفر القنوات ، مقارنةً بصناديق البريد (
# 21 و
# 22 ) أو قوائم الانتظار (
# 23 و
# 24 ) ، طريقة أكثر مرونة لنقل الرسائل البسيطة بين المهام.
المقالات السابقة في السلسلة:
المادة رقم 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 ، يتم تحديد القنوات خلال مرحلة التجميع. يمكن أن يحتوي كل تطبيق على 16 قناة. إذا لم يتم تكوين أي قنوات في التطبيق ، فلن يتم تضمين بنيات البيانات أو رموز مكالمات الخدمة المتعلقة بالقنوات في التطبيق.
قناة نقل البيانات - مجموعة من المخازن ، يسمح لك حجم كل منها بوضع عنصر بيانات واحد بطول يحدده المستخدم بالبايت. يتم التحكم في الوصول إلى البيانات بطريقة يمكن للعديد من المهام استخدامها بأمان. يمكن للمهام كتابة البيانات إلى القناة حتى يتم ملء جميع المناطق. يمكن للمهام قراءة البيانات من القناة ، ويتم استلام البيانات وفقًا لمبدأ FIFO. قد تؤدي محاولة الكتابة إلى قناة مزدحمة أو القراءة من قناة فارغة إلى حدوث خطأ أو تعليق مهمة ، اعتمادًا على إعدادات مكالمة API المحددة وتهيئة Nucleus SE.
القنوات و قوائم الانتظار
يدعم Nucleus SE أيضًا قوائم الانتظار التي تمت مناقشتها بالتفصيل في المقالات السابقة (# 23 و # 24). الفرق الرئيسي بين القنوات وقوائم الانتظار هو حجم الرسالة. تحتوي قوائم الانتظار على رسائل تتكون من متغير واحد من نوع ADDR ، وعادةً ما تكون مؤشرات. تحتوي القناة على رسائل ذات حجم تعسفي ، فردية لكل قناة في التطبيق ويتم تخصيصها أثناء إعدادات المعلمة.
إعداد القناة
عدد القنوات
كما هو الحال مع معظم كائنات Nucleus SE ، يتم التحكم في تخصيص القناة بواسطة توجيهات
#define في
nuse_config.h . المعلمة الرئيسية هي
NUSE_PIPE_NUMBER ، والتي تحدد عدد القنوات التي تم تكوينها في التطبيق. بشكل افتراضي ، هذه القيمة هي صفر (أي ، لا توجد قنوات في التطبيق) ويمكن أن تأخذ قيمًا تصل إلى 16. ستؤدي قيمة غير صحيحة إلى حدوث خطأ في
الترجمة ، والتي سيتم إنشاؤها عن طريق التحقق من ملف
nuse_config_check.h (يتم تضمين هذا الملف في
nuse_config.c و compiles. جنبا إلى جنب مع ذلك) ، والتي سوف تؤدي إلى توجيه
الإرهاب # .
اختيار قيمة غير صفرية بمثابة المنشط الرئيسي للقنوات. يتم استخدام هذه المعلمة لتحديد بنيات البيانات وحجمها يعتمد على قيمتها (المزيد حول هذا الموضوع في المقالة التالية). بالإضافة إلى ذلك ، تعمل القيمة غير الصفرية على تنشيط إعدادات واجهة برمجة التطبيقات.
تفعيل مكالمات API
كل وظيفة من واجهات API (استدعاء الأداة المساعدة) في Nucleus SE تحتوي على توجيه تمكين
#define في
nuse_config.h . بالنسبة للقنوات ، هذه الرموز هي:
NUSE_PIPE_SENDNUSE_PIPE_RECEIVENUSE_PIPE_JAMNUSE_PIPE_RESETNUSE_PIPE_INFORMATIONNUSE_PIPE_COUNTبشكل افتراضي ، يتم ضبطها على
FALSE ، لذلك يتم تعطيل جميع مكالمات الخدمة ، مما يحظر إدراج الكود الذي يقوم بتنفيذها. لتكوين القنوات في التطبيق ، تحتاج إلى تحديد مكالمات خدمة API اللازمة وتعيينها على
TRUE .
فيما يلي مقتطف من الشفرة من ملف
nuse_config.h الافتراضي.
#define NUSE_PIPE_NUMBER 0 /* Number of pipes in the system - 0-16 */ /* Service call enablers */ #define NUSE_PIPE_SEND FALSE #define NUSE_PIPE_RECEIVE FALSE #define NUSE_PIPE_JAM FALSE #define NUSE_PIPE_RESET FALSE #define NUSE_PIPE_INFORMATION FALSE #define NUSE_PIPE_COUNT FALSE
إذا تم تنشيط وظائف واجهة برمجة التطبيقات ، ولكن لا توجد قنوات في التطبيق (باستثناء
NUSE_Pipe_Count () ، والذي يتم تمكينه دائمًا) ، فسيحدث خطأ في
التحويل البرمجي. إذا كان الرمز الخاص بك يستخدم مكالمة API لم يتم تنشيطها ، فسيحدث خطأ في التخطيط لأنه لم يتم تضمين رمز التنفيذ في التطبيق.
مكالمات قناة العلوية
يدعم Nucleus RTOS عشرة حملات قناة توفر الوظائف التالية:
- إرسال رسالة إلى القناة. يتم تطبيق Nucleus SE في دالة NUSE_Pipe_Send () .
- تلقي الرسائل من القناة. يتم تطبيق Nucleus SE في دالة NUSE_Pipe_Receive () .
- إرسال رسالة إلى الجزء العلوي من القناة. يتم تطبيق Nucleus SE في NUSE_Pipe_Jam () .
- استعادة القناة إلى حالة غير مستخدمة مع إطلاق جميع المهام المعلقة (إعادة الضبط). في Nucleus SE ، تم تنفيذه في NUSE_Pipe_Reset () .
- الحصول على معلومات حول قناة محددة. يتم تطبيق Nucleus SE باستخدام NUSE_Pipe_Information () .
- إرجاع عداد القنوات المكوّنة حاليًا في التطبيق. يتم تطبيق Nucleus SE باستخدام NUSE_Pipe_Count () .
- إضافة قناة جديدة إلى التطبيق (الإنشاء). غير مطبق في Nucleus SE.
- إزالة قناة من التطبيق. غير مطبق في Nucleus SE.
- إرجاع المؤشرات إلى جميع القنوات في التطبيق. غير مطبق في Nucleus SE.
- إرسال رسالة إلى جميع المهام المعلقة على القناة (البث). غير مطبق في Nucleus SE.
النظر في تنفيذ كل من هذه المكالمات الخدمة بمزيد من التفصيل.
خدمة المكالمات للكتابة والقراءة من القنوات
يتم تسجيل العمليات الأساسية التي يتم إجراؤها على القنوات (وتسمى أيضًا الإرسال) والقراءة (تُعرف أيضًا باسم تلقي الرسائل). بالإضافة إلى ذلك ، من الممكن تسجيل البيانات في بداية القناة (التشويش). يوفر Nucleus RTOS و Nucleus SE ثلاث دعوات API رئيسية لهذه العمليات ، والتي سيتم مناقشتها أدناه.
تسجيل القناة
تتميز الأداة المساعدة Nucleus RTOS API بالكتابة إلى القناة بمرونة كبيرة ، مما يسمح لك بتعليق المهام بشكل ضمني أو مع مهلة إذا لم يكن بالإمكان إتمام العملية على الفور (على سبيل المثال ، عند محاولة الكتابة إلى قناة مزدحمة). يحتوي Nucleus SE على تحدٍ مشابه ، ولكن توقف المهمة اختياري ولا يتم تنفيذ مهلة.
يوفر Nucleus RTOS أيضًا خدمة بث القناة ، لكنه غير معتمد على Nucleus SE. سيتم وصفه في قسم مكالمات API غير المحققة في المقالة التالية.
اتصل لإرسال رسائل إلى قناة في Nucleus RTOSنموذج استدعاء الخدمة:
STATUS NU_Send_To_Pipe (NU_PIPE * ماسورة ، رسالة VOID * ، حجم غير موقَّع ، معلق معلق) ؛المعلمات:
ماسورة - مؤشر إلى كتلة التحكم في القناة التي يوفرها المستخدم ؛
رسالة - مؤشر على الرسالة المراد إرسالها ؛
الحجم - عدد البايتات في الرسالة. إذا كانت القناة تدعم رسائل متغيرة الطول ، فيجب أن تكون هذه المعلمة مساوية أو أقل من طول الرسالة التي تدعمها القناة. إذا كانت القناة تدعم رسائل ذات طول ثابت ، فيجب أن تكون هذه المعلمة مساوية لحجم الرسالة التي تدعمها القناة ؛
تعليق - تحديد تعليق المهمة ، يمكن أن يأخذ القيم
NU_NO_SUSPEND ،
NU_SUSPEND أو قيمة المهلة.
قيمة الإرجاع:
NUSE_SUCCESS - تم إكمال المكالمة بنجاح ؛
NU_INVALID_PIPE - مؤشر غير صالح للقناة ؛
NU_INVALID_POINTER - مؤشر فارغ إلى رسالة (
NULL ) ؛
NU_INVALID_SIZE - حجم الرسالة غير متوافق مع حجم الرسالة الذي تدعمه القناة ؛
NU_INVALID_SUSPEND - محاولة التعليق من سلسلة رسائل غير مرتبطة بالمهمة ؛
NU_PIPE_FULL - القناة ممتلئة ولم يتم تحديد نوع تعليق المهمة ؛
NU_TIMEOUT - القناة ممتلئة حتى بعد تعليق المهمة لفترة زمنية محددة ؛
NU_PIPE_DELETED - تم حذف القناة أثناء تعليق المهمة ؛
NU_PIPE_RESET - تمت إعادة تعيين القناة أثناء تعليق المهمة.
اتصل لإرسال رسائل إلى قناة في Nucleus SEتدعم مكالمة خدمة API هذه الوظيفة الأساسية لـ Nucleus RTOS API.
نموذج استدعاء الخدمة:
STATUS NUSE_Pipe_Send (توجيه الإخراج NUSE_PIPE ، رسالة U8 * ، تعليق U8) ؛المعلمات:
مؤشر
الأنابيب (ID) للقناة المستخدمة ؛
message - مؤشر للرسالة المراد إرسالها (تسلسل من وحدات البايت للطول المسموح به لقناة معينة)
تعليق - مواصفات تعليق المهمة ، يمكن أن تأخذ القيم
NUSE_NO_SUSPEND و
NUSE_SUSPEND .
قيمة الإرجاع:
NUSE_SUCCESS - تم إكمال المكالمة بنجاح ؛
NUSE_INVALID_PIPE - فهرس قناة غير صالح ؛
NUSE_INVALID_POINTER - مؤشر فارغ إلى رسالة (
NULL )؛
NUSE_INVALID_SUSPEND - محاولة التعليق من سلسلة رسائل غير مرتبطة بالمهمة أو عند تعطيل قفل المهام ؛
NUSE_PIPE_FULL - القناة ممتلئة ولم يتم تحديد نوع تعليق المهمة ؛
NUSE_PIPE_WAS_RESET - تمت إعادة تعيين القناة أثناء تعليق المهمة.
تنفيذ نشر القناة في Nucleus SEيتم تحديد إصدار رمز دالة API
NUSE_Pipe_Send () (بعد التحقق من المعلمات) باستخدام
التحويل البرمجي الشرطي اعتمادًا على ما إذا كان دعم مكالمات واجهة برمجة التطبيقات
نشطًا لحظر (إيقاف مؤقت) المهام أم لا. أدناه نعتبر كلا الخيارين.
إذا تم تعطيل القفل ، فإن رمز مكالمة واجهة برمجة التطبيقات هذه بسيط جدًا:
if (NUSE_Pipe_Items[pipe] == NUSE_Pipe_Size[pipe]) /* pipe full */ { return_value = NUSE_PIPE_FULL; } else /* pipe element available */ { data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Head[pipe]]; for (i=0; i<msgsize; i++) { *data++ = *message++; } NUSE_Pipe_Head[pipe] += msgsize; if (NUSE_Pipe_Head[pipe] == (NUSE_Pipe_Size[pipe] * msgsize)) { NUSE_Pipe_Head[pipe] = 0; } NUSE_Pipe_Items[pipe]++; return_value = NUSE_SUCCESS; }
تتحقق الوظيفة من وجود مساحة خالية في القناة وتستخدم
الفهرس NUSE_Pipe_Head [] لوضع الرسالة في منطقة بيانات القناة.
في حالة تنشيط تأمين المهام ، يصبح الرمز أكثر تعقيدًا:
do { if (NUSE_Pipe_Items[pipe] == NUSE_Pipe_Size[pipe]) /* pipe full */ { if (suspend == NUSE_NO_SUSPEND) { return_value = NUSE_PIPE_FULL; } else { /* block task */ NUSE_Pipe_Blocking_Count[pipe]++; NUSE_Suspend_Task(NUSE_Task_Active, (pipe << 4) | NUSE_PIPE_SUSPEND); return_value = NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value != NUSE_SUCCESS) { suspend = NUSE_NO_SUSPEND; } } } else /* pipe element available */ { data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Head[pipe]]; for (i=0; i<msgsize; i++) { *data++ = *message++; } NUSE_Pipe_Head[pipe] += msgsize; if (NUSE_Pipe_Head[pipe] == (NUSE_Pipe_Size[pipe] * msgsize)) { NUSE_Pipe_Head[pipe] = 0; } NUSE_Pipe_Items[pipe]++; if (NUSE_Pipe_Blocking_Count[pipe] != 0) { U8 index; /* check whether a task is blocked on this pipe */ NUSE_Pipe_Blocking_Count[pipe]--; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_PIPE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == pipe)) { NUSE_Task_Blocking_Return[index] = NUSE_SUCCESS; NUSE_Wake_Task(index); break; } } } return_value = NUSE_SUCCESS; suspend = NUSE_NO_SUSPEND; } } while (suspend == NUSE_SUSPEND);
بعض التوضيحات قد تكون مفيدة.
يتم تضمين التعليمة البرمجية في
do ... أثناء حلقة ، والتي تعمل أثناء المعلمة وقفة المهمة
NUSE_SUSPEND .
إذا كانت القناة ممتلئة وكانت معلمة التوقف المرحلي هي
NUSE_NO_SUSPEND ، فإن استدعاء واجهة برمجة التطبيقات ينتهي بالقيمة
NUSE_PIPE_FULL . إذا كانت المعلمة
الإيقاف المرحلي هي
NUSE_SUSPEND ، فالمهمة تتوقف مؤقتًا. عند الانتهاء (أي عندما تستأنف المهمة) ، إذا كانت قيمة الإرجاع هي
NUSE_SUCCESS ، أي ، فقد تم استئناف المهمة بسبب قراءة الرسالة (وليس بسبب إعادة تعيين القناة) ، تُرجع التعليمة البرمجية إلى بداية الحلقة.
إذا لم تكن القناة ممتلئة ،
فسيتم حفظ الرسالة المقدمة باستخدام فهرس
NUSE_Pipe_Head [] في منطقة بيانات القناة. يتحقق لمعرفة ما إذا كانت القناة قد أوقفت المهام مؤقتًا (الرسائل المعلقة). إذا كان هناك مثل هذه المهام ، يستأنف أولها. تم تعيين متغير
التوقف المرحلي إلى
NUSE_NO_SUSPEND ، واستكمال استدعاء API بالقيمة
NUSE_SUCCESS .
قراءة من القناة
تتميز الأداة المساعدة Nucleus RTOS API للقراءة من القناة بمرونة كبيرة ، مما يسمح لك بإيقاف المهام بشكل ضمني أو مع مهلة إذا تعذر إكمال العملية على الفور (على سبيل المثال ، عند محاولة قراءة قناة فارغة). يحتوي Nucleus SE على مكالمة مساعدة مماثلة ، ولكن توقف المهام اختياري ولا يتم تنفيذ مهلة.
قناة قراءة التحدي في نواة RTOSنموذج استدعاء الخدمة:
STATUS NU_Receive_From_Pipe (NU_PIPE * ماسورة ، رسالة VOID * ، حجم غير موقَّع ، UNSIGNED * actual_size ، UNSIGNED Suspend) ؛المعلمات:
ماسورة - مؤشر إلى كتلة التحكم في القناة التي يوفرها المستخدم ؛
message - مؤشر إلى تخزين الرسالة المستلمة ؛
الحجم - عدد البايتات في الرسالة. يجب أن يتطابق مع حجم الرسالة المحدد عند إنشاء القناة ؛
تعليق - مواصفات تعليق المهمة ، يمكن أن تأخذ
NU_NO_SUSPEND ،
NU_SUSPEND أو قيم المهلة.
قيمة الإرجاع:
NU_SUCCESS - تم إكمال المكالمة بنجاح ؛
NU_INVALID_PIPE - مؤشر غير صالح للقناة ؛
NU_INVALID_POINTER - مؤشر فارغ إلى رسالة (
NULL ) ؛
NU_INVALID_SUSPEND - محاولة إيقاف مهمة مؤقتًا من سلسلة
رسائل غير مرتبطة بالمهمة ؛
NU_PIPE_EMPTY - القناة فارغة ، ولم يتم تحديد نوع تعليق المهمة ؛
NU_TIMEOUT - القناة فارغة حتى بعد تعليق المهمة لقيمة المهلة المحددة ؛
NU_PIPE_DELETED - تم حذف القناة أثناء تعليق المهمة ؛
NU_PIPE_RESET - تم حذف القناة أثناء تعليق المهمة.
قناة قراءة التحدي في نواة SEتدعم مكالمة خدمة API هذه الوظيفة الأساسية لـ Nucleus RTOS API.
نموذج استدعاء الخدمة:
STATUS NUSE_Pipe_Receive (توجيه الإخراج NUSE_PIPE ، رسالة U8 * ، تعليق U8) ؛المعلمات:
مؤشر
الأنابيب (ID) للقناة المستخدمة ؛
message - مؤشر إلى تخزين الرسالة المستلمة (تسلسل من البايتات ، يتزامن طوله مع حجم رسالة القناة) ؛
تعليق - مواصفات تعليق المهمة ، يمكن أن تأخذ القيم
NUSE_NO_SUSPEND و
NU_SUSPEND .
قيمة الإرجاع:
NUSE_SUCCESS - تم إكمال المكالمة بنجاح ؛
NUSE_INVALID_PIPE - فهرس قناة غير صالح ؛
NUSE_INVALID_POINTER - مؤشر فارغ إلى رسالة (
NULL )؛
NUSE_INVALID_SUSPEND - محاولة لتعليق مهمة من سلسلة
رسائل غير مرتبطة بالمهمة أو مع تعطيل تعليق المهمة ؛
NUSE_PIPE_EMPTY - القناة فارغة ، ولم يتم تحديد نوع تعليق المهمة ؛
NUSE_PIPE_WAS_RESET - تمت إعادة تعيين القناة أثناء تعليق المهمة.
تطبيق قارئ موجز في Nucleus SEيتم تحديد إصدار رمز دالة API
NUSE_Pipe_Receive () (بعد التحقق من المعلمات) عن طريق
الترجمة الشرطية ، اعتمادًا على ما إذا كان دعم API لمكالمات التأمين (تعليق المهمة) قد تم تنشيطه أم لا. سننظر في كلا الخيارين أدناه.
إذا تم تعطيل القفل ، فإن رمز مكالمة واجهة برمجة التطبيقات هذه بسيط جدًا:
if (NUSE_Pipe_Items[pipe] == 0) /* pipe empty */ { return_value = NUSE_PIPE_EMPTY; } else { /* message available */ data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Tail[pipe]]; for (i=0; i<msgsize; i++) { *message++ = *data++; } NUSE_Pipe_Tail[pipe] += msgsize; if (NUSE_Pipe_Tail[pipe] == (NUSE_Pipe_Size[pipe] * msgsize)) { NUSE_Pipe_Tail[pipe] = 0; } NUSE_Pipe_Items[pipe]--; *actual_size = msgsize; return_value = NUSE_SUCCESS; }
تقوم الوظيفة بالتحقق من وجود رسالة في القناة وتستخدم فهرس
NUSE_Pipe_Tail [] لاسترداد الرسالة من منطقة بيانات القناة وإرجاع البيانات من خلال مؤشر الرسالة.
في حالة تنشيط تأمين المهام ، يصبح الرمز أكثر تعقيدًا:
do { if (NUSE_Pipe_Items[pipe] == 0) /* pipe empty */ { if (suspend == NUSE_NO_SUSPEND) { return_value = NUSE_PIPE_EMPTY; } else { /* block task */ NUSE_Pipe_Blocking_Count[pipe]++; NUSE_Suspend_Task(NUSE_Task_Active, (pipe << 4) | NUSE_PIPE_SUSPEND); return_value = NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value != NUSE_SUCCESS) { suspend = NUSE_NO_SUSPEND; } } } else { /* message available */ data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Tail[pipe]]; for (i=0; i<msgsize; i++) { *message++ = *data++; } NUSE_Pipe_Tail[pipe] += msgsize; if (NUSE_Pipe_Tail[pipe] == (NUSE_Pipe_Size[pipe] * msgsize)) { NUSE_Pipe_Tail[pipe] = 0; } NUSE_Pipe_Items[pipe]--; if (NUSE_Pipe_Blocking_Count[pipe] != 0) { U8 index; /* check whether a task is blocked */ /* on this pipe */ NUSE_Pipe_Blocking_Count[pipe]--; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_PIPE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == pipe)) { NUSE_Task_Blocking_Return[index] = NUSE_SUCCESS; NUSE_Wake_Task(index); break; } } } *actual_size = msgsize; return_value = NUSE_SUCCESS; suspend = NUSE_NO_SUSPEND; } } while (suspend == NUSE_SUSPEND);
بعض التوضيحات قد تكون مفيدة.
يتم تضمين التعليمة البرمجية في
do ... أثناء حلقة ، والتي تعمل أثناء المعلمة وقفة المهمة
NUSE_SUSPEND .
إذا كانت القناة فارغة وكانت معلمة التوقف المرحلي هي
NUSE_NO_SUSPEND ، فإن استدعاء واجهة برمجة التطبيقات ينتهي بالقيمة
NUSE_PIPE_EMPTY . إذا كانت المعلمة الإيقاف المرحلي هي
NUSE_SUSPEND ، فالمهمة تتوقف مؤقتًا. عند الانتهاء (أي عندما تستأنف المهمة) ، إذا كانت قيمة الإرجاع هي
NUSE_SUCCESS ، أي ، فقد تم استئناف المهمة لأنه تم إرسال الرسالة (وليس بسبب إعادة تعيين القناة) ، فتعود التعليمة البرمجية إلى بداية الحلقة.
إذا كانت القناة تحتوي على رسائل ، فسيتم إرجاع الرسالة المخزنة باستخدام فهرس
NUSE_Pipe_Tail [] . يتم التحقق مما إذا كانت هناك أية مهام متوقفة مؤقتًا (في انتظار الإرسال) على هذه القناة. إذا كان هناك مثل هذه المهام ، يستأنف أولها. تم تعيين متغير التوقف المرحلي إلى
NUSE_NO_SUSPEND ، وتنتهي استدعاء API برمز
NUSE_SUCCESS .
سجل إلى بداية القناة
تتميز الأداة المساعدة Nucleus RTOS API بالكتابة إلى بداية القناة مرنة للغاية ، مما يسمح لك بإيقاف المهام بشكل ضمني أو مع مهلة إذا لم يكن بالإمكان إتمام العملية على الفور (على سبيل المثال ، عند محاولة الكتابة إلى قناة كاملة). يحتوي Nucleus SE على مكالمة مساعدة مماثلة ، ولكن توقف المهام اختياري ولا يتم تنفيذ مهلة.
اتصل بالكتابة إلى بداية القناة في Nucleus RTOSنموذج استدعاء الخدمة:
STATUS NU_Send_To_Front_Of_Pipe (NU_PIPE * ماسورة ، رسالة VOID * ، حجم غير موقَّع ، معلق غير مُعلق) ؛المعلمات:
ماسورة - مؤشر إلى كتلة التحكم في القناة التي يوفرها المستخدم ؛
رسالة - مؤشر على الرسالة المراد إرسالها ؛
الحجم - عدد البايتات في الرسالة. إذا كانت القناة تدعم رسائل متغيرة الطول ، فيجب أن تكون هذه المعلمة مساوية أو أقل من حجم الرسالة التي تدعمها القناة. إذا كانت القناة تدعم الرسائل ذات الطول الثابت ، فيجب أن تطابق هذه المعلمة حجم الرسالة الذي تدعمه القناة ؛
تعليق - مواصفات تعليق المهمة ، يمكن أن تأخذ
NU_NO_SUSPEND ،
NU_SUSPEND أو قيم المهلة.
قيمة الإرجاع:
NU_SUCCESS - تم إكمال المكالمة بنجاح ؛
NU_INVALID_PIPE - مؤشر غير صالح للقناة ؛
NU_INVALID_POINTER - مؤشر فارغ إلى رسالة (
NULL ) ؛
NU_INVALID_SIZE - حجم الرسالة غير متوافق مع حجم الرسالة الذي تدعمه القناة ؛
NU_INVALID_SUSPEND - محاولة تعليق من سلسلة
رسائل لا علاقة لها بالمهمة ؛
NU_PIPE_FULL - القناة ممتلئة ، ولم يتم تحديد نوع تعليق المهمة ؛
NU_TIMEOUT - القناة ممتلئة حتى بعد تعليق المهمة لفترة زمنية محددة ؛
NU_PIPE_DELETED - تم حذف القناة أثناء تعليق المهمة ؛
NU_PIPE_RESET - تمت إعادة تعيين القناة أثناء تعليق المهمة.
اتصل بالكتابة إلى بداية القناة في Nucleus SEتدعم مكالمة الأداة المساعدة هذه الوظيفة الأساسية لـ Nucleus RTOS API.
نموذج استدعاء الخدمة:
STATUS NUSE_Pipe_Jam (ماسورة NUSE_PIPE ، رسالة ADDR * ، تعليق U8) ؛المعلمات:
مؤشر
الأنابيب (ID) للقناة المستخدمة ؛
message - مؤشر للرسالة المراد إرسالها ، وهو سلسلة من البايت تساوي حجم الرسالة المكوّنة في القناة ؛
تعليق - يمكن أن تكون مواصفات تعليق المهمة ،
NUSE_NO_SUSPEND أو
NUSE_SUSPEND .
قيمة الإرجاع:
NUSE_SUCCESS - تم إكمال المكالمة بنجاح ؛
NUSE_INVALID_PIPE - فهرس قناة غير صالح ؛
NUSE_INVALID_POINTER - مؤشر فارغ إلى رسالة (
NULL )؛
NUSE_INVALID_SUSPEND - محاولة لتعليق مهمة من سلسلة
رسائل غير مرتبطة بالمهمة أو عند تعطيل قفل المهمة ؛
NUSE_PIPE_FULL - القناة ممتلئة ، ولم يتم تحديد نوع تعليق المهمة ؛
NUSE_PIPE_WAS_RESET - تمت إعادة تعيين القناة أثناء تعليق المهمة.
تنفيذ تسجيل دخول القناة في Nucleus SEيشبه رمز المتغير
للدالة NUSE_Pipe_Jam () إلى حد بعيد
NUSE_Pipe_Send () ، باستثناء أن الفهرس
NUSE_Pipe_Tail [] يستخدم لتخزين البيانات فيه ، وبالتالي:
if (NUSE_Pipe_Items[pipe] == NUSE_Pipe_Size[pipe]) /* pipe full */ { return_value = NUSE_PIPE_FULL; } else /* pipe element available */ { if (NUSE_Pipe_Tail[pipe] == 0) { NUSE_Pipe_Tail[pipe] = (NUSE_Pipe_Size[pipe] - 1) * msgsize; } else { NUSE_Pipe_Tail[pipe] -= msgsize; } data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Tail[pipe]]; for (i=0; i<msgsize; i++) { *data++ = *message++; } NUSE_Pipe_Items[pipe]++; return_value = NUSE_SUCCESS; }
في المقالة التالية ، سننظر في مكالمات الخدمة الإضافية المتعلقة بالقنوات ، وكذلك بنيات البيانات المقابلة.
نبذة عن الكاتب: يعمل Colin Walls في صناعة الإلكترونيات لأكثر من ثلاثين عامًا ، حيث خصص معظم وقته للبرامج الثابتة. وهو الآن مهندس برامج ثابتة في Mentor Embedded (قسم من Mentor Graphics). يتحدث Colin Walls غالبًا في المؤتمرات والندوات ، ومؤلف العديد من المقالات الفنية وكتابين عن البرامج الثابتة. يعيش في المملكة المتحدة.
مدونة كولن المهنية ، البريد الإلكتروني: colin_walls@mentor.com.