سیستم عامل FreeRTOS

سیستم عامل FREERTOS در بردهای ESP32 قسمت اول: معرفی RTOS

getting-started-with-free-rtos-in-esp32-part-one-introduce-digispark
نوشته شده توسط معین صابری

در ادامه مجموعه آموزش های سیستم عامل FREERTOS، این قسمت را به راه اندازی و کار با سیستم عامل FREERTOS در بردهای ESP32 اختصاص می دهیم. بردهای ESP32، آنطور که می دانید از مهم ترین بردها در زمینه پروژه های IOT به شمار می رود. در طرف دیگر، سیستم عامل  FREERTOS به عنوان یک سیستم عامل فوق العاده کاربردی، می تواند روی بردهای ESP32 نیز اجرا شود. در این آموزش به بررسی این سیستم عامل بر روی این برد می پردازیم. محور اصلی این آموزش، تعریف Task های ورودی/خروجی ساده است. پس از آشنایی با این مفاهیم، در قسمت های بعد مفاهیم بیشتری از سیستم عامل را مورد بررسی قرار خواهیم داد. بنابراین در ادامه آموزش با مرجع تخصصی سیستم عامل FreeRTOS به زبان فارسی، دیجی اسپارک همراه باشید.

 


تعریف سیستم عامل


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

تعریف سیستم عامل در میکروکنترلر - دیجی اسپارک

 

سیستم عامل FreeRTOS، یک سیستم عامل رایگان برای میکروکنترلرها و به به طور کلی امبدد سیستم هاست. این سیستم عامل بر روی پردازنده ESP32 قابلیت اجرا دارد. زمانیکه شما هسته نرم افزاری آردوینو برای ESP32 را دانلود می کنید، کتابخانه سیستم عامل در هسته تعبیه شده است.  به کمک سیستم عامل FreeRTOS، شما می توانید چندین برنامه داشته باشید. در حالت عادی شما تنها یک برنامه می توانید برای برد ESP32 بنویسید. اما به کمک سیستم عامل و تعریف Task، چندین برنامه قابلیت اجرا روی پردازنده خواهند داشت. این برنامه ها دارای حلقه های تکرار بی نهایت هستند، گویی که هر کدام یک تابع void loop باشند. بنابراین شما می توانید تعدادی void loop در برنامه خود داشته باشید. روال تعریف بسیار شبیه به سیستم عامل در بردهای آردوینو است. شما می توانید با کلیک بر روی این لینک، آموزش های سیستم عامل را مطالعه کنید.

 


معرفی FREERTOS


FreeRTOS (Real-Time Operating System) یک سیستم عامل برای سیستم‌های تعبیه شده است که با هدف ارائه یک محیط عامل ساده و کارآمد برای برنامه‌نویسی و اجرای برنامه‌های زمان‌واقع استفاده می‌شود. این سیستم عامل برای سیستم‌های تعبیه شده با منابع محدود طراحی شده است که نیازمندی‌های زمان‌واقع را دارند. FreeRTOS متن‌باز است و در سال ۲۰۰۳ توسط Richard Barry توسعه داده شد. طراحی آن سبک و ساده است و با استفاده از زبان C نوشته شده است. FreeRTOS معماری تکرار‌پذیری را به خوبی پشتیبانی می‌کند و قابل استفاده در محیط‌های مختلفی از جمله میکروکنترلرها، میکروپروسسورها و SoC (سیستم‌های-در-یک-تراشه) می‌باشد.ویژگی‌های اصلی FreeRTOS شامل موارد زیر است:

  • تعامل با چندین وظیفه به صورت همزمان (Multitasking): FreeRTOS اجازه می‌دهد چندین وظیفه را به صورت همزمان اجرا کنید و ترتیب اجرای آن‌ها را کنترل کنید.
  • برنامه‌نویسی با استفاده از وظیفه‌ها (Task-based Programming): در FreeRTOS، برنامه‌ها با استفاده از وظیفه‌ها (Tasks) تعریف می‌شوند. هر وظیفه مستقلی است که دارای کد اجرایی و منابع مشخص خود می‌باشد.
  • برنامه‌نویسی همروند (Concurrency): FreeRTOS اجازه می‌دهد تا بخش‌های مختلف برنامه به صورت همروند اجرا شوند و برای هماهنگی بین آن‌ها از مکانیزم‌هایی مانند صف (Queue) و سمافور (Semaphore) استفاده می‌کند.
  • مدیریت منابع: FreeRTOS قابلیت‌های مدیریت منابعی مانند مدیریت حافظه، سمافورها و صف‌ها را فراهم می‌کند.
  • پشتیبانی از تایمرها (Timers): FreeRTOS امکان تنظیم و استفاده از تایمرها را به منظور اجرای وظایف در بازه‌های زمانی مشخص فراهم می‌کند.
  • حالت خوابیدن پایین برق (Low Power Mode): FreeRTOS قابلیت ورود به حالت‌های خوابیدن پایین برق را برای سیستم‌های تعبیه شده که نیازمندی‌های کم برق دارند، فراهم می‌کند.

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

 


کاربرد FREERTOS


 FreeRTOS قابلیت پورتابلیته را دارد، به این معنی که می‌توان آن را بر روی انواع میکروکنترلرها و پلتفرم‌های سخت‌افزاری مختلف اجرا کرد. توسعه‌دهندگان می‌توانند FreeRTOS را به صورت سفارشی بر روی سیستم‌های مورد نظر خود پورت کنند.FreeRTOS امکان ورود به حالت‌های خوابیدن پایین برق را برای سیستم‌های تعبیه شده که نیازمندی‌های کم برق دارند، فراهم می‌کند. این ویژگی بسیار مهم است زیرا به میکروکنترلرها کمک می‌کند تا در مدت زمان غیرفعالی برق مصرفی کمتری داشته باشند و عمر باطری را بطور قابل توجهی افزایش دهند.FreeRTOS از مکانیزم‌های ارتباطی مختلف بین وظایف پشتیبانی می‌کند. این شامل صف‌ها، سمافورها، برقراری ارتباط مستقیم (Direct Task Notification)، انتقال داده به صورت محافظت شده (Protected Data Transfer) و ارسال و دریافت سریالی داده (Serial Data Stream) است. این ویژگی‌ها به برنامه‌نویس امکان ایجاد ارتباطات موثر و هماهنگی بین وظایف را می‌دهد.FreeRTOS ابزارهایی برای توسعه، اشکال‌زدایی و مدیریت سیستم‌های تعبیه شده فراهم می‌کند. این ابزارها شامل ابزارهای ردیابی (trace tools)، ابزارهای اشکال‌زدایی (debugging tools) و ابزارهای مدیریت پورتابلیته (porting tools) است. این ابزارها به توسعه‌دهندگان کمک می‌کنند تا عملکرد و عیب‌یابی سیستم‌های تعبیه شده را بهبود بخشند. FreeRTOS یک جامعه فعال و پرشور از توسعه‌دهندگان دارد و اطلاعات و تجربیات زیادی در مورد استفاده و توسعه این سیستم عامل در دسترس است. همچنین، شرکتهایی نیز وجود دارند که ارائه‌دهنده خدمات پشتیبانی و سازگاری برای FreeRTOS هستند.

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

 


دستورات سیستم: معرفی Task  به برنامه


در یک سیستم عامل، با مجموعه ای از Task ها رو به رو هستیم. هر Task یک برنامه دیده می شود. در حقیقت درون هر Task، یک حلقه تکرار بی نهایت قرار می گیرد. این حلقه تکرار بی نهایت در حقیقت نقش تابع void loop را بازی می کند. شما می توانید تعداد زیادی Task یا همان void loop تعریف نمایید. به همین منظور، به صورت global، باید Task ها را تعریف کنید. شیوه تعریف Task ها مشابه تعریف توابع است. به عنوان مثال فرض کنید یک Task به اسم A داریم. این Task به صورت زیر تعریف می شود.

void A( void *pvParameters )

 

 مطابق دستور فوق، یک تابع تعریف شده است. این تابع خروجی void دارد؛ چراکه قرار نیست از این تابع به دلیل حلقه تکرار خارج شویم. در طرف دیگر، این تابع می تواند یک ورودی داشته باشد. اما در حالت عادی، ورودی NULL است. ورودی void* به معنای NULL است. اما این تابع می تواند ورودی هایی هم داشته باشد. ورودی های این تابع، ورودی های عادی نیست. این ورودی ها بین Task ها جا به جا می شوند. در آینده راجع به این ورودی ها صحبت خواهیم کرد. ورودی Task ها در حقیقت سیگنال داده بین Task های مختلف بوده که با نام صف شناخته می شوند.

 


تعریف Task


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

 

شرح خصوصیت
تابع Task TaskFunction_t pvTaskCode
تعریف یک نام دلخواه برای Task const char *const pcName
حجم Task const uint32_t usStackDepth
ورودی های Task void *const pvParameters,
اولویت Task UBaseType_t uxPriority
تابع Handle برای Task TaskHandle_t *const pvCreatedTask,
نام CORE برای اجرای Task const BaseType_t xCoreID

 

برای تعریف یک Task، از تابع   xTaskCreatePinnedToCoreاستفاده می کنیم. این تابع ورودی های جدول فوق را به ترتیب در خود جای می دهد. به عنوان مثال، تابع زیر را در نظر بگیرید.

xTaskCreatePinnedToCore(f1,”f1 function”,۱۰۲۴,NULL,1,NULL, ARDUINO_RUNNING_CORE)

 

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

void TaskBlink(void *pvParameters)  // This is a task.
{
  (void) pvParameters;  //بدون ورودی 

  pinMode(LED_BUILTIN, OUTPUT);

  for (;;) //اجرای مداوم Task
  {
    digitalWrite(LED_BUILTIN, HIGH);   // روشن کردن LED روی برد
    vTaskDelay(100);  // تاخیر حدودا ۱۵ میلی ثانیه ای
    digitalWrite(LED_BUILTIN, LOW);    // خاموش کردن LED
    vTaskDelay(100);  // 
  }
}

 

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

 


اجرای یک مثال با FreeRTOS


در این قسمت از FreeRTOS در ESP32 به یک نمونه برنامه می پردازیم. در این برنامه یک ورودی آنالوگ و یک ورودی دیجیتال به صورت مداوم خوانده می شوند.

#if CONFIG_FREERTOS_UNICORE 
#define ARDUINO_RUNNING_CORE 0
#else
#define ARDUINO_RUNNING_CORE 1
#endif

#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif

//معرفی Task ها
void TaskBlink( void *pvParameters );
void TaskAnalogReadA3( void *pvParameters );
void setup() {
  
  // 
  Serial.begin(115200);
  
  //تعریف Task شماره ۱ به همراه ورودی ها
  xTaskCreatePinnedToCore(
    TaskBlink  //تابع Task
    ,  "TaskBlink"   // تعریف نام دلخواه برای Task
    ,  ۱۰۲۴  //حجم Task
    ,  NULL
    ,  ۲  // اولویت اجرا
    ,  NULL 
    ,  ARDUINO_RUNNING_CORE);

  xTaskCreatePinnedToCore(
    TaskAnalogReadA3
    ,  "AnalogReadA3"
    ,  ۱۰۲۴  //
    ,  NULL
    ,  ۱  //
    ,  NULL 
    ,  ARDUINO_RUNNING_CORE);

  //
}

void loop()
{
  // در تابع loop هیچ چیز اجرا نمی شود. فقط Task ها اجرا می شوند.
}


void TaskBlink(void *pvParameters)  // This is a task.
{
  (void) pvParameters;  //بدون ورودی 

  pinMode(LED_BUILTIN, OUTPUT);

  for (;;) //اجرای مداوم Task
  {
    digitalWrite(LED_BUILTIN, HIGH);   // روشن کردن LED روی برد
    vTaskDelay(100);  // تاخیر حدودا ۱۵ میلی ثانیه ای
    digitalWrite(LED_BUILTIN, LOW);    // خاموش کردن LED
    vTaskDelay(100);  // 
  }
}

void TaskAnalogReadA3(void *pvParameters)  // This is a task.
{
  (void) pvParameters;
  

  for (;;)
  {
    // read the input on analog pin A3:
    int sensorValueA3 = analogRead(A3);
    // print out the value you read:
    Serial.println(sensorValueA3);
    vTaskDelay(10);  
  }
}

 


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


لینک خرید برد ESP32، کلیک کنید.

 


جمع بندی


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

 

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

 

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

معین صابری

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

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

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

۱۴ دیدگاه

  • عرض سلام و تشکر از اطلاعات بسیار خوبی که ارائه نمودید.
    بنده یک ESP32 را در مود WiFi AP برنامه ریزی نمودم و میتوانم به آن وصل شوم ولی فرمانی از من نمیگیردحتی در مد WEB server نیز صفحه وب در کامپیوتر و یا موبایل قابل روءیت نیست، از طرف دیگر وقتی برنامه را عوض میکنم و موبایل را در وضعیت Hotspot قرار میدهم به آن وصل نمیشود. برنامه های استفاده شده از مثال های Arduini IDE بوده اند. لطفاً در صورت امکان راهنمایی فرمائید.

  • من سیستم عامل FreeRTOS رو از سایتش دانلود کردم. چجوری باید به IDE آردوینو اضافه اش کنم. کدم ارور FQBN میده. سرچ کردم ولی نتونستم حلش کنم گفتم شاید بخاطر اضافه نکردن FreeRTOS باشه.

    • سلام
      لطفا مطابق اموزش، از طری قخود نرم افزار آردوینو سیستم عامل را دانلود کنید.

  • سلام، عالی بود مطلب شما، من این را روی pico اجرا کردم و جواب گرفتم و دو led رو جداگانه هر کدام را با یک هسته کنترل کردم، سوالی که برام پیش اومده این هست… آیا چون pico دو هسته داره فقط دو برنامه رو میتونیم همزمان اجرا کنیم؟ یا امکان اجرای ۳ یا ۴ تا هم هست؟ اگر امکان اجرای بیشتر از دو هسته هست میشه توضیح بدید چطور امکان پذیر هست؟

  • سلام.
    این کدها روی ESP-12E کار میکنه؟
    تاحالا موفق نشدم روی ماژول Nodemcu این آموزش اجرا کنم.
    لطفا راهنمایی کنید

      • میشه بگین برای اجرای FreeRTOS از کدوم کتابخانه در esp8266 12E استفاده کنم؟!
        انگار کتابخونه خاص خودش داره.

          • خیر. اجرای FreeRTOS روی esp8266 متفاوت از سایر espهاست.
            کدهایی که توی آموزش‌‌های شماست روی esp32 آپلود و اجرا شد، ولی همین کد روی esp8266 موقع کامپایل خطا میداد.
            نمیدونم چرا FreeRTOS روی esp8266 اجرا نمیشن.

            • سلام مجدد
              بردهای esp به صورت پیشفرض قابلیت free rtos را دارند. ممکن است فریمور برد شما متفاوت باشد و یا اینکه مستندات اولیه به درستی روی سیستم نصب نشده اند. از همه مهمتر اینکه کدهای esp32 قرار نیست روی esp8266 کار کنند.