المكتبة Syra uOS هي نظام غير متزامن تعتمد على مبدأ الأحداث . وهي مصممة لبناء تطبيقات قابلة للتوسع للمعالجات التحكمية.
تكلمنا في المرحلة السابقة عن سبب تصميم هذه المكتبة . وما تقدمه من حلول وتسهيلات في بناء تطبيقات المعالجات التحكمية .
ويمكن الاطلاع على الجزء السابق من الرابط التالي :
المكتبة Syra uOS للمعالجات التحكمية – المقدمة
في البداية نذكر لمحة بسيطة عن مكونات المكتبة وكيفية استخدامها.
يمكن تحميل نسخة من هذه المكتبة للمعالج المطلوب التعامل معه من الرابط التالي :
Syra_uOS_Downloads
تتكون هذه المكتبة من مجموعة من الملفات المتوافقة مع بعضها والموزعة بالشكل التالي :
- مجموعة من الملفات الرئيسية هي inc.h, main.c, config.h تم تجهيزها لتكون وسيلة الربط بين المبرمج والمكتبة .
- ومجلد إسمه SMF ، يحتوي باقي أجزاء المكتبة . وتمثل نواة النظام . لا تحتاج تعديل من المبرمج ، أو لا يجب ان يتم التعديل بها ، لأنها تعمل بشكل متوافق مع بعضها .
- الملف main.c : في هذا الملف يتم تسجيل المهام ليقوم النظام بتنفيذها ، ويتضمن هذا الملف ثلاثة أقسام أساسية :
- – التابع onReset . في هذا التابع نكتب ما نريد من المعالج أن ينفذه في بداية التشغيل . أي بعد توصيل الكهرباء مباشرة .
– التابع onBoot . وفيه يتم كتابة الجزء الذي يريد المبرمج ان يتم تنفيذه عند مرحلة الاقلاع BOOT . أو بعد الخروج من وضع الاستعداد أو وضع توفير الطاقة .
– التابع onSleep . ويمثل مرحلة ماقبل الدخول في وضع توفير الطاقة . حيث يمكن كتابة الأوامر التي نريد تنفيذها قبل أن يتوقف المعالج عن العمل والدخول في وضع الاستعداد . - – التابع Main_Task . وهو المهمة الافتراضية , التي تم إنشائها لتكون المهمة الأولى في النظام وهي مسجلة مسبقا ولا تحتاج تعريف أو تسجيل . ويتم تنفيذ هذه المهمة بشكل متكرر طوال فترة عمل المعالج ضمن نواة النظام .
ويمكن الاكتفاء بها إذا كان المشروع لا يحتاج الكثير من المهام .
- الملف config.h : يستخدم لكتابة معلومات الإعدادات للمشروع ، مثل تحديد عدد المهام وغيرها من الاعدادات لكامل المشروع.
- الملف inc.h : هذا الملف هو وسيلة الربط بين أجزاء المكتبة وباقي الملفات في المشروع ، وفيه يتم تعريف كل الملفات التي نضيفها في المشروع . فإذا قمنا بإنشاء ملف جديد في المشروع , نقوم بإضافته لهذا الملف.
والشكل التالي يوضح مخطط عمل النظام في المكتبة :
حيث عند توصيل الكهرباء Power ON يبدأ المعالج بالعمل . وهنا يتم تنفيذ التابع onReset .
ثم ينتقل التنفيذ لنواة النظام . حيث يبدأ في تهيئة النظام للعمل والدخول في مرحلة الإقلاع . وهنا يتم تنفيذ التابع onBoot .
وبعدها ينتقل النظام لتنفيذ المهام المكتوبة واحدة تلو الأخرى . وذلك ضمن ما نسميه بحلقة المهام . وفي البداية لدينا المهمة الافتراضية المتمثلة بالتابع Main_Task .
ويستمر النظام بتنفيذ هذه المهام واحدة تلو الأخرى بشكل متكرر . حتى يتم الطلب بالدخول في وضع الاستعداد أو توفير الطاقة .
فإذا تم طلب الدخول في وضع توفير الطاقة يتم تنفيذ التابع OnSleep . ثم يتوقف المعالج عن العمل .
ويبقى المعالج في وضع توفير الطاقة ينتظر الأمر بالعودة لمرحلة الإقلاع من جديد وإعادة المراحل السابقة .
أما عن كيفية الطلب من النظام الإنتقال من وضع العمل إلى وضع الاستعداد وتوفير الطاقة . فسيتم شرحه بالتفصيل لاحقاً.
إنشاء مشروع في بيئة البرمجة Microchip Studio :
لنقوم الآن بالتطبيق العملي . حيث نحتاج بيئة البرمجة ATMEL Studio , وهي من تصميم شركة ATMEL التي أصبحت ملكاً لشركة Microchip . وهي مجانية ومتاحة للجميع . ولكن تم تغيير إسم البرنامج ليصبح Microchip Studio .
يمكن تحميل بيئة البرمجة هذه من الرابط التالي:
Microchip Studio for AVR® and SAM Devices
لنبدأ بإنشاء مشروع جديد في بيئة العمل Microchip Studio . وذلك من القائمة File , نختار New , ثم Project . كما في الشكل :
ثم تظهر لنا نافذة الإعداد . نكتب فيها إسم المشروع وليكن SuF_Example . ونحدد مكان حفظ المشروع وكذلك نوع المشروع .
كما في الشكل التالي :
بعدها تظهر شاشة جديدة نختار منها المعالج الذي نريد كتابة البرنامج من أجله , وليكن مثلا ATxmega16A4U .
ثم بالضغط على OK يتم إنشاء المشروع . والذي في البداية يتضمن فقط ملف واحد إسمه main.c . وفيه مكتوب برنامج إفتراضي بسيط .
وما علينا الآن هو أن نقوم بإضافة المكتبة Syra uOS إلى هذا المشروع وذلك كما يلي .
أولا بشكل عام . من شريط الأدوات نقوم بتغيير وضعية العمل من Debug إلى Release .
ثانيا نقوم بحذف الملف main.c الذي تم إنشائه تلقائيا .
نقوم بتحميل المكتبة . والتي متوفرة على الرابط التالي : Syra_uOS_XMEGA_R1.4.0
هذا الرابط خاص بالمعالجات XMEGA , ويمكن تحميل النسخة التي تتوافق مع أي معالج أخر مدعوم من صفحة التحميل
Syra_uOS_Download
تكون ملفات المكتبة مضغوطة في ملف zip . نفك ضغط هذا الملف في مجلد المشروع .
ثم نذهب إلى بيئة البرمجة Microchip Studio . ونقوم بإضافة ملفات المكتبة للمشروع وذلك كما يلي :
– من النافذة Solution Explorer نحدد المشروع . ثم نضغط على زر إظهار جميع الملفات كما في الشكل :
فتظهر جميع الملفات التي تم نسخها إلى مجلد المشروع . ثم نقوم بتحديد ملفات المكتبة جميعها .
ونضغط نقرة باليمين على الملفات المحددة ، فتظهر قائمة نختار منها Include in Project :
وبذلك تصبح جميع الملفات جزء من المشروع . ثم بعدها نعيد إخفاء باقي الملفات من العرض بنفس الطريقة التي قمنا بإظهارها فيها .
وبهذا الشكل يصبح المشروع جاهز للعمل و إضافة المهام التي نريدها .
طريقة استخدام المكتبة
بشكل افتراضي كل شيء جاهز ولا يحتاج تعديل . ويمكن البدء مباشرة بكتابة أول مهمة . وبما أنه يوجد مهمة افتراضية تم إنشائها مسبقا . سوف نستخدمها في هذه المرحلة .
كل ما علينا فعله هو فتح الملف main.c والنظر في داخله فنجد التوابع التالية .
/* // main.c الملف */ //------------------- // هنا هذا السطر هو تعريف ملف الربط #include "inc.h" //------------------- // هذا التابع يتم تنفيذه مرة واحدةعند تشغيل المعالج مباشرة void OnReset() { } //------------------- // هذا التابع يتم تنفيذه في مرحلة الاقلاع void OnBoot() { } //------------------- // هذا التابع يتم تنفيذه قبل الدخول في وضع الاستعداد void OnSleep() { } //------------------- // هذا التابع هو المهمة الافتراضية void Main_Task() { }
كتابة التعليمات لتشغيل ضوء متقطع
لنفرض نريد استخدام المهمة الإفتراضية لتقوم بتشغيل ضوء LED بشكل متقطع . وليكن مرة كل ثانية .
كما بدأنا الشرح بإنشاء مشروع لكتابة برنامج لمعالج من نوع XMEGA . سوف نكمل المثال هذا لنفس المعالج .
ولكن هذه الطريقة يمكن تطبيقها للعمل مع أي نوع من المعالجات التي تدعمها هذه المكتبة .
لنفرض الضوء موصول مع المعالج على الطرف الأول PIN0 المرتبطة بالبوابة A .
وبالتالي الخطوات المطلوبة هي التالي :
– أولا أن نحدد إتجاه هذا الطرف . وهنا نحتاج أن يكون هذا الطرف عبارة عن خرج . وهذا يجب أن يتم في مرحلة الإقلاع قبل تنفيذ المهمة . لذلك نكتب التعليمة الخاصة بذلك في التابع OnBoot .
– ثانياً نكتب تعليمات تشغيل و إطفاء الضوء في التابع Main_Task . لأنه هو تابع المهمة الذي يعمل خلال فترة التفيذ المستمر .
فيصبح البرنامج بالشكل التالي :
// تابع الإقلاع void OnBoot() { // تحديد إتجاه الطرف PORTA_DIRSET = PIN0_bm ; } // تابع المهمة void Main_Task() { // تعليمة تغيير حالة الطرف PORTA_OUTTGL = PIN0_bm ; // تعليمة الانتظار TaskWait(500); }
البرنامج السابق واضح وبسيط ولكن سنشرح التعليمات .
التعليمة PORTA_DIRSET = PIN0_bm مهماتها تحديد إتجاه الطرف الأول من البوابة A على أنها خرج .
التعليمة PORTA_OUTTGL = PIN0_bm مهمتها تغيير أو قلب حالة الطرف . فإذا كان 1 منطقي يصبح 0 . والعكس بالعكس . وبذلك يتغير الجهد الكهربائي المطبق على الضوء ويتغير بين حالة إضائة و عدم إضائة .
الجديد هنا هو التعليمة TaskWait . وهي من أوامر المكتبة . حيث من خلالها يتم الطلب من النظام أن ينتظر لمدة زمنية تقدر بواحدة الميلي ثانية قبل إعادة تنفيذ هذه المهمة من جديد . وهنا في حالتنا الفترة اخترناها 500 ميلي ثانية .
وبذلك يمكن أن نتخيل أن هذه المهمة ستتكرر بعد نصف ثانية . ويتكرر معها تنفيذ تعليمة تغيير إضائة الضوء .
وبذلك لا نحتاج أن نستخدم أي نوع من توابع التأخير delay أو أي حلقة متكررة تستهلك من طاقة المعالج .
وإنما ينتقل المعالج لتنفيذ باقي العمليات . بينما هذه المهمة في حالة انتظار .
قواعد هامة
نلاحظ أننا استخدمنا تعليمة جديدة للتعامل مع الزمن وهي TaskWait . ولم نستخدم حلقات التأخير .
يجب أن يتم الانتباه بعدم استخدام الحلقات الغير منتهية . وعدم استخدام توابع التأخير الزمني delay إلا عند الضرورة .
وإذا اضطر الأمر لاستخدامها يجب الأخذ بعين الاعتبار أن جميع المهام متوقفة بانتظار هذه الحلقة حتى تنتهي .
قلنا في البداية أن هذه المكتبة هي عبارة عن نظام غير متزامن تعتمد على مبدأ الأحداث . أي أن تتابع عمليات البرنامج تتم على أساس وجود حدث معين . ومن يقوم بإدارة هذه الأحداث هو نواة النظام .
لذلك يجب عدم تأخير نواة النظام عن معالجة الأحداث وإدارة باقي العمليات بالمشروع .
وما تقدمه المكتبة من ميزات وتسهيلات ومرونة . يتم القضاء عليه بالاستخدام الخاطئ والإكثار من حلقات التأخير الغير مبررة .
فالمكتبة توفر بديل أفضل لإدارة الزمن . مما يسمح باستخدام موارد المعالج بالشكل الأمثل .
المثال التالي هو استخدام خاطئ ويستهلك طاقة المعالج بدون فائدة . ويبطل عمل النظام :
void Main_Task() { // هذا استخدام خاطئ // وفيه ضياع للطاقة while(1) { PORTA_OUTTGL = PIN0_bm ; _delay_ms(1000); } }
هذا الاستخدام الخاطئ يجعل المعالج يدور في حلقة لا نهائية بدون فائدة . وتتعطل جميع المهام الباقية عن العمل .
فالاستخدام الصحيح يتطلب الابتعاد عن هذا النوع من الحلقات . إلا في بعض الحالات التي تكون مدروسة بعناية .
حيث يتم انتظار حدث ما لفترة قصيرة جدا غير ملحوظة . عندها لابأس باستخدام الحلقات .
وهكذا نكون قد انتهينا من التعريف بالمكتبة Syra uF و كتابة أول برنامج بسيط بالاعتماد عليها.
في المرحلة القادمة سوف نتعرف على كيفية كتابة مهام إضافية غير المهمة الأساسية Main_Task . وسنتعرف على كيفية تسجيل هذه المهام في النظام ليتمكن من تنفيذها حسب المطلوب .