تدوينات مصغرةلغة سي و متحكمات

حيلة أردوينو: كيفية مشاركة برنامج خدمة المقاطعة ISR بين المكاتب والكود الرئيسي

المشكلة

أحد المحدوديات التي يسببها استخدام لغة وبيئة الأردوينو للتطوير SDK هي التضارب الذي قد يحصل عند استخدام المكاتب وتحديداً تضارب استخدام المقاطعات ISR (Interrupt Service Routine)، حيث تقوم كل مكتبة بتعريف define المقاطعة في ملف الكود المصدري ولاحقاً قد يحتاج المطور في الكود الرئيسي للبرنامج لاستخدام نفس هذه المقاطعة مما يؤدي إلى خطأ في الترجمة compilation بسبب تعريف نفس المقاطعة مرتين

(.text+0x0): multiple definition of `__vector_x

على سبيل المثال: إذا تم استخدام المكتبة المضمنة في نواة بيئة الأردوينو Arduino core والمسماة SoftwareSerial فلن يستطيع المطور لاحقاً استخدام أي من المقاطعات الثلاثة المتوفرة للوحدة PCINT (Pin Change Interrupt) (في متحكم Atmega328 على سبيل المثال) والتي تستخدم لاكتشاف تغير السوية المنطقية لإشارات الدخل. بالرغم من حاجة المطور للمكتبة وأيضاً المقاطعات بنفس الوقت. إن أمثلة أخرى كثيرة يمكن ذكرها لمثل هذه الحالة ومنها مقاطعات المؤقتات Timers.

في هذه التدوينة المصغرة سوف نناقش حل مقترح بحيث نحافظ على روح البساطة التي تقدمها بيئة التطوير أردوينو وبنفس الوقت إمكانية الاستفادة من المقاطعات لأغراض غير المكتبة. هذا الحل يمكن تطبيقه في المكاتب التي تأتي مضمنة مع البرنامج أردوينو أو من أجل مكاتب طرف ثالث يتم تطويرها مستقبلاً.

 

الحل المقترح: استخدام توابع التوسيع handler (Hook) Functions

قد لا يكون من المناسب أن يقوم المطور بتعريف المقاطعات في الكود الرئيسي حيث أن المكاتب تقدم حل متكامل وجاهز للاستخدام مباشرة. الفكرة المقترحة تعتمد على طريقة لتوسيع المقاطعة لاحقاً بإضافة توابع تسمى Handler وتسمى أحياناً اصطلاحاً hook أو call-back. هذا يمكن أن يتم بإضافة هذه التوابع على أن يتم ربطها لاحقاً بتوابع أخرى يتم تعريفها من قبل المطور.

من أجل توضيح الحل المقترح سنكتب مكتبة كمثال لدارة Arduino UNO بحيث يتم تعريف المقاطعة TIMER1_COMPA_vect للمؤقت Timer1. سوف نعرف المقاطعة ونضيف شيء ما سنراه لاحقاً لإضافة ميزة التوسيع. سيتم هذا من خلال ميزة في لغة السي تسمى function pointer، وهو مؤشر ولكن ليس مؤشر لمتحول وإنما مؤشر لتابع. لمعرفة المزيد عن مؤشرات التوابع يمكن قراءة المقدمة الجيدة من موقع Geeksforgeeks.

لإضافة هذا إلى المكتبة سنتبع الخطوات التالية:

1- إضافة تعريف لمؤشر لتابع في الملف الرأسي للمكتبة

2- إضافة method من أجل إسناد التابع الذي يكتبه المطور إلى المؤشر الذي تم تعريفه سابقاً.

3- استدعاء المؤشر للتابع في جسم برنامج المقاطعة

مثال المكتبة كاملاً

demoLib.h

demoLib.cpp

Application.ino

أمثلة حقيقية

  • مكتبة Wire التي تأتي مع برنامج الأردوينو تستخدم نفس الطريقة لكي تتيح للمطور تعريف توابع خاصة بأحداث on receive/request على مسرى النقل I2C. اطلع على: Wire.onReceive(handler) & Wire.onRequest(handler).

  • مكتبات من تطوير طرف ثالث مثل Timer library والتي تستخدم لكتابة مجدول مهام بسيط scheduler. إن الفكرة الأساسية من هذه المكتبة هو إضافة مؤشرات لتوابع في المقاطعة لكل مهمة task وفي المقاطعة يتم تحديد أي مهمة يجب أن تنفذ الآن.

Yahya Tawil

مهندس نظم مضمّنة مهتم بالعتاد مفتوح المصدر وولد في نفس العام الذي ولد فيه نظام تشغيل لينكس. يحيى هو مدير التحرير في عتاديات ويؤمن بأهمية المحتوى المكتوب المجاني والنوعي والعملي. خبرته في مجال النظم المضمّنة تتركز في كتابة البرامج المضمنة وتصميم الدارات المطبوعة والنظرية وإنشاء المحتوى.

مقالات ذات صلة

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

This site uses Akismet to reduce spam. Learn how your comment data is processed.