اینترنت اشیا IOT سیستم عامل FreeRTOS

ایجاد چندین پایه به صورت وقفه برای برد آردوینو به کمک FreeRTOS

interrupt-arduino-programming-with-freertos-digispark
نوشته شده توسط معین صابری

وقفه ها یکی از مهم ترین سیگنال های کنترلی در سیستم های دیجیتال به شمار می‌روند. به کمک این سیگنال برنامه از حالت عادی خارج شده و تابع مربوط به سیگنال، اجرا می‌شود. در حقیقت یک سیگنال وقفه هنگام تولید پالس، برنامه اصلی را متوقف کرده و برنامه مربوط به روال وقفه را اجرا می‌کند. به کمک وقفه‌ها می‌توان از اتلاف زمان جلوگیری نمود. در این حالت هرگاه که وقفه رخ دهد، تابع آن اجرا می‌شود. بدین ترتیب نیاز به انتظار برای رخداد وقفه نیست. وقفه‌ها دارای منابع داخلی و خارجی هستند. در منابع خارجی، یک وقفه زمانی رخ می‌دهد که بر روی پایه GPIO مربوط به آن، سیگنال یا پالسی قرار گیرد. در این حالت تابع مربوط به آن اجرا می‌شود. اما اجرای توابع وقفه دارای محدودیت‌هایی است. در آموزش وقفه با FreeRTOS قصد داریم تا به کمک سیستم عامل FreeRTOS، از این محدودیت ها کاسته و پایه‌های بیشتری را به عنوان وقفه برای آردوینو تعریف کنیم. در ادامه با مرجع تخصصی سیستم عامل FreeRTOS به زبان فارسی، دیجی اسپارک همراه باشید.

 


تعریف و کاربرد وقفه


وقفه ها یکی از مهم ترین ابزارها در سیستم های میکروکنترلری به شمار می‌روند. وقفه، همانطور که از نام آن پیداست؛ سبب ایجاد توقف در اجرای برنامه می شود. پس از توقف اجرای برنامه، دستورات مربوط به وقفه اجرا شده و پس از پایان آن، برنامه روال عادی خود را از سر خواهد گرفت. تا کنون راجع به وقفه آموزش‌های زیادی در دیجی اسپارک منتشر شده است.

 

در یک میکروکنترلر، وقفه ها به دو صورت داخلی و یا خارجی تعریف می شوند. وقفه های داخلی مربوط به عملیات داخلی میکروکنترلر نظیر تایمرها و ارتباط سریال هستند. در وقفه خارجی، پایه های GPIO، هرگاه که به صورت LOW یا HIGH یا به صورت های مختلف دیگر تغییر وضعیت دهند، وقفه رخ خواهد داد. یک وقفه دارای تابع مختص به خود است. این تابع زمانیکه وقفه رخ دهد، اجرا خواهد شد. به این تابع در اصطلاح روتین سرویس وقفه یا ISR گفته می شود. عبارت ISR مخفف عبارت Interrupt Service Routine است. هنگا وقوع وقفه، روال عادی اجرا برنامه متوقف شده و تابع وقفه اجرا می شود. پس از اتمام اجرا تابع وقفه، برنامه به روال عادی بازخواهد گشت. در رابطه با تابع وقفه، موارد زیر حائز اهمیت است.

۱-وقفه ها دارای شماره اولیت هستند، هر چه شماره یک وقفه بالاتر باشد، اولویت بیشتری در اجرا دارد. در صورتیکه دو وقفه همزمان رخ دهند، ابتدا وقفه با اولویت بالاتر و سپس وقفه با اولویت پایین تر اجرا می شود.

۲-در صورتیکه هنگام اجرای یک وقفه، وقفه دیگری رخ دهد، وقفه دیگر از بین خواهد رفت.

۳-تعداد پایه های وقفه های خارجی محدود است. به عنوان مثال در برد آردینو UNO تنها ۲ پایه وقفه وجود دارد.

۴-درون توابع وقفه نمی توان از تاخیر طولانی مدت و یا حلقه های تکرار بی نهایت استفاده نمود.

در این آموزش جهت غلبه بر مشکلات وقفه ها، روشی ارایه شده است. در این روش به کمک سیستم عامل FreeRTOS ضمن افزایش تعداد پایه ها برای وقفه، مشکلات تابع روتین وقفه را نیز پوشش می دهیم.

 


شماتیک و اتصالات وقفه با FreeRTOS


پس از آشنایی با روال کار، نوبت به شماتیک و اتصالات پروژه وقفه با FreeRTOS می رسد. در این پروژه ۳ کلید به عنوان وقفه تعریف شده است. شما البته می توانید کلیدهای بیشتری را نیز تعریف کنید. از طرف دیگر، برد آردوینو مشغول دریافت داده از سنسور دما NTC و نمایش آن در سریال مانیتور است. تصویر زیر فرم کلی اتصالات را نمایش می دهد.

اتصالات پروژه وقفه با FreeRTOS در آردوینو - دیجی اسپارک

 

 مطابق تصویر فوق، اتصالات به شیوه زیر ادامه می یابد.

  • اتصال یک طرف سنسور NTC به ۵ ولت
  • اتصال طرف دیگر سنسور NTC به مقاومت ۱۰ کیلو
  • اتصال طرف دیگر مقاومت ۱۰ کیلو به زمین
  • اتصال محل تلاقی سنسور و مقاومت به پایه A1

در رابطه با کلیدها، توجه داشته باشید که تمام پایه های مربوط به کلید به صورت داخلی پول آپ هستند. بنابراین کلیدها از یک طرف به پایه های ۴،۵ و ۶ متصل شده و از طرف دیگر به GND وصل خواهند شد. هرگاه کلیدها فشرده شوند، پایه ها از حالت ۱ به صفر تغییر وضعیت خواهند داد.

 


نصب کتابخانه های مورد نیاز


همانطور که اطلاع دارید، کتابخانه ها یکی از ابزارهای کلیدی و کاربردی در برنامه نویسی به شمار می روند. به کمک این ابزار، می توانیم توابع نوشته شده در فایلهایی به نام کتابخانه ذخیره کرده و سپس در پروژه های متعدد از آن استفاده کنیم.  همانطور که پیشتر گفته شد، برای راه اندازی و کار با سیستم عامل FreeRTOS کتابخانه توسعه داده شده است. برای استفاده از این کتابخانه، ابتدا باید آن را نصب کنیم. برای نصب کتابخانه در محیط آردویینو، ابتدا مطابق تصویر زیر بر روی گزینه Tools و سپس Manage Libraries کلیک کنید.

اصول نصب کتابخانه در آردوینو - دیجی اسپارک

 

پس از کلیک بر روی گزینه Manage Libraries، در صفحه ظاهر شده، در قسمت کادر جستجو، عبارت freertos را جستجو نموده و کتابخانه مشخص شده در تصویر زیر را نصب نمایید.

نصب کتابخانه وقفه با FreeRTOS در آردوینو - دیجی اسپارک

 

پس از نصب کتابخانه مربوط به سیستم عامل، نوبت به نصب کتابخانه سنسور دما می رسد. جهت نصب کتابخانه، در منوی جست و جوی کتابخانه ها عبارت thermistor را تایپ کنید. با تایپ این عبارت با تصویر زیر رو به رو خواهید شد. مطابق تصویر، کتابخانه مشخص شده با کادر قرمز رنگ را نصب نمایید.

نصب کتابخانه وقفه با FreeRTOS در آردوینو - دیجی اسپارک

 


کدهای پروژه وقفه با FreeRTOS


پس از نصب کتابخانه های مورد نیاز، نوبت به آپلود برنامه وقفه با FreeRTOS می رسد. کدهای زیر را بر روی برد آردوینو UNO خود آپلود نمایید.

#include <Arduino_FreeRTOS.h>   //اضافه کردن کتابخانه سیستم عامل
#include "thermistor.h"  //کتابخانه سنسور NTC
#define NTC_PIN               A1  //پایه آنالوگ ورودی برای خواندن مقدار سنسور NTC
THERMISTOR thermistor(NTC_PIN,        // پایه آنالوگ ورودی
                      ۱۰۰۰۰,          // مقاومت سنسور به اهم در دمای ۲۵ درجه
                      ۳۹۵۰,           // پارامتر بتای سنسور
                      ۱۰۰۰۰);         // مقدار مقاومت سری شده با سنسور به کیلو اهم
uint16_t temp;  //متغیر خواندن دما 
//تعریف توابعی که توسط سیستم عامل باید اجرا شوند. توابع KEY1 الی key4 وظیفه کنترل اجرای روتین وقفه و خواندن دما را بر عهده  دارند. همچنین این توابع ورودی ندارند به همین دلیل در ورودی ازمقدار پیش تعریف شده //استفاده شده است.void k1( void *pvParameters );
void k2( void *pvParameters );
void k3( void *pvParameters );
void k4( void *pvParameters );
//تعریف پایه های کلیدها
#define KEY1 5
#define KEY2 6
#define KEY3 7
void setup() {

  Serial.begin(9600);
  //تعریف پایه های به عنوان  ورودی
  pinMode(KEY1, INPUT_PULLUP);
  pinMode(KEY2, INPUT_PULLUP);
  pinMode(KEY3, INPUT_PULLUP);
  //توجه: به کمک تابع xtaskCreate توابعی که سیستم عامل باید به صورت همزمان اجرا کند، به سیستم عامل معرفی می شود.
  xTaskCreate(
    k1   //نام تابع
    ,  "KEY11"   // یک نام دلخواه جهت اختصاص دادن به تابع
    ,  ۱۲۸  // میزان حافظه به بایت که تابع نیاز دارد
    ,  NULL  //در صورتیکه تابع ورودی داشته باشد در این قسمت درج می شود اما از آنجاییکه ورودی ندارد NULL تعیین می گردد.
    ,  ۳  //تععین شماره اولویت اجرا، در سیستم عامل FreeRTOS توابع یا Task ها از لحاظ اولیت اجرا بین ۰ الی ۳ شماره گذاری می شوند. هرچه عدد بیشتر شود اولویت بالاتر خواهد بود.
    ,  NULL //در صورتیکه handler تعریف شده باشد، در این جا آدرس تابع handler مشخص می شود. تابع handler تابعی خارج از تابع Task بوده که به اجرای آن در مواقع خاص کمک می کند. چون در اینجا این تابع وجود ندارد ورودی NULL می شود.
  );

  xTaskCreate(
    k2
    ,  "KEY2 2"
    ,  ۱۲۸
    ,  NULL
    ,  ۳
    ,  NULL );
  xTaskCreate(
    k3
    ,  "KEY3 3"
    ,  ۱۲۸
    ,  NULL
    ,  ۳
    ,  NULL );
  xTaskCreate(
    k4
    ,  "KEY 4"
    ,  ۱۲۸
    ,  NULL
    ,  ۳
    ,  NULL );
    // هر ۴ تابع دارای اولیت اجرای یکسان هستند، بدین ترتیب با هم اجرا می شوند.

}

void loop()
{
  //در سیستم عامل تابع LOOP خالی بوده و توابع task اجرا می شوند.
}

//در این جا، هیچ کدام از توابع اجرایشان تداخلی در اجرای دیگر تابع ایجاد نمی کند. در این حالت اگر هر سه کلید با هم فشرده شوند، تابع هایشان نیز با هم اجرا می شوند.
void k1(void *pvParameters)  // تابع b1
{
  (void) pvParameters;  //پاارمترهای ورودی که NULL هستند.


  for (;;) // توجه: یک تابع در سیستم عامل که با Task هم شناخته می شود، همواره به صورت دائم باید اجرا گردد. در حقیقت شما در سیستم عامل ، هر تابع یا Task مثل تابع void loop آردوینو باید همیشه اجرا شود.
  {
    if (digitalRead(KEY1) == LOW) {  //در صورتیکه کلید فشرده شد،  تابع روتین وقفه اجرا می شود. شما در این جا می توانید کدهای خود را قرار دهید. با توجه به حلقه تکرار، کدها تا زمانیکه کلید فشرده شود، اجرا می شود
      Serial.println("KEY1 SERVICE ROUTINE");
      vTaskDelay(15);
    }
  }
}

//*****************************************************************************
void k2(void *pvParameters)
{
  (void) pvParameters;
  for (;;)
  {
    if (digitalRead(KEY2) == LOW) {
      Serial.println("KEY2 SERVICE ROUTINE");
      vTaskDelay(15);
    }
  }
}
//*****************************************************************************
void k3(void *pvParameters)
{
  (void) pvParameters;

  for (;;)
  {
    if (digitalRead(KEY3) == LOW) {
      Serial.println("KEY3 SERVICE ROUTINE");
      vTaskDelay(15);
    }
  }
}
//*****************************************************************************
void k4(void *pvParameters)  //تابع خواندن و نمایش دما
{
  (void) pvParameters;

  for (;;)
  {
    temp = thermistor.read();   // Read temperature
    Serial.print("Temp in ºC : ");
    Serial.println(temp/10);
   vTaskDelay(15);
}
}

 


اجرای پروژه و مزایای این روش در روال وقفه


پس از اجرای پروژه وقفه با FreeRTOS، در حالت عادی بر روی سریال مانیتور مقدار دمای اندازه گیری شده توسط سریال مانیتور نمایش داده می شود.

 

 در هنگامی که دما بر روی سریال مانیتور در حال نمایش است، در صورتیکه کلیدی فشرده شود، روتین وقفه مربوط به آن اجرا خواهد شد.

 

در این روش، مزایای بسیاری در اجرای تابع روتین وقفه وجود دارد. در زیر به این مزایا اشاره می کنیم.

۱-قابلیت اجرای همزمان توابع وقفه

۲-قابلیت تعریف تاخیر در توابع وقفه بدون اثر گذاری در سایر توابع وقفه

۳-قابلیت تعریف حلقه تکرار بی نهایت در توابع روتین وقفه

 


لوازم مورد نیاز


سنسور دمای NTC

 لینک خرید برد آردوینو UNO، کلیک کنید

لینک خرید مقاومت ۱۰ کیلو اهمی، کلیک کنید

 


جمع بندی


وقفه ها یکی از مهم ترین ابزارهای کنترلی در میکروکنترلرها به شمار می روند. به کمک این ابزار می توان از اتلاف توان CPU جلوگیری نمود. اجرای یک وقفه همراه با تابع آن است. اما توابع وقفه دارای محدودیت هایی در اجرا هستند. در این آموزش به کمک سیستم عامل FreeRTOS، اقدام به افزاش تعداد پایه های وقفه خارجی برد آدروینو نمودیم. به کمک این آموزش، می توانید بدون محدودیت های تابع روتین وقفه نظیر اولویت، روتین های وقفه خارجی دلخواه خود را برای برد آردوینو ایجاد کنید.

 

چنانچه در مراحل راه اندازی و انجام این پروژه با مشکل مواجه شدید، بدون هیچ نگرانی در انتهای همین پست، به صورت ثبت نظر سوالتان را مطرح کنید. من در سریع‌ترین زمان ممکن پاسخ رفع مشکل شما را خواهم داد. همچنین اگر ایرادی در کدها و یا مراحل اجرایی وجود دارند می‌توانید از همین طریق اطلاع رسانی کنید.

 

درباره نویسنده

معین صابری

کارشناسی ارشد رشته معماری سیستم های کامپیوتری

مالي که ز تو کس نستاند، علم است
حرزي که تو را به حق رساند، علم است
جز علم طلب مکن تو اندر عالم
چيزي که تو را ز غم رهاند، علم است
(شیخ بهایی)

تبادل نظر و رفع عیب با ثبت دیدگاه