0% found this document useful (0 votes)
14 views67 pages

Learn RTOS Programming Easymcu Org

Rtos programing

Uploaded by

n4v8wvbxch
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views67 pages

Learn RTOS Programming Easymcu Org

Rtos programing

Uploaded by

n4v8wvbxch
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 67

‫شناسنامه کتاب‬

‫نام کتاب‪ :‬برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫نویسنده‪ :‬مرتضی زندی‬

‫تاریخ نشر‪ :‬بهار ‪9911‬‬

‫ناشر‪ :‬گروه آموزشی ایزی‪.‬ام‪.‬سی‪.‬یو‬

‫قیمت‪ :‬رایگان‬

‫تعداد صفحات‪76 :‬‬

‫تماس با ناشر‪[email protected] :‬‬

‫وبسایت‪www.EasyMCU.org :‬‬
‫آشنایی با مرتضی زندی‬

‫مدیر وبسایت ‪www.EasyMCU.org‬‬ ‫‪‬‬


‫برنامه نویس و محقق در زمینه سیستم های نهفته و ‪IOT‬‬ ‫‪‬‬
‫بیش از ‪ 7‬سال فعالیت حرفه ای در زمینه الکترونیک‪ ،‬کامپیوتر و‬ ‫‪‬‬
‫پیاده سازی پروژه های متعدد‬
‫جزء مقام های برتر در مسابقات ملی فناورد دانشگاه شریف و‬ ‫‪‬‬
‫مسابقات بین المللی ایران اپن‬
‫مدرس و طراح آموزشی‬ ‫‪‬‬
‫سابقه سال ها فعالیت در تیم های تحقیق و توسعه )‪ (R&D‬به عنوان‬ ‫‪‬‬
‫مهندس ارشد سیستم های نهفته‬
‫‪4‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫فهرست مطالب‬
‫مقدمه ‪5...........................................................................................................................‬‬
‫برنامه نویسی‪ ،‬امری خداگونه!‪01 ...........................................................................................‬‬
‫سبک های برنامه نویسی؟ ‪00.................................................................................................‬‬
‫سیستم عامل ‪ RTOS‬چیست؟ ‪01 .........................................................................................‬‬
‫سیستم عامل ‪05............................................................................................... FreeRTOS‬‬
‫میکرو ‪05.............................................................................................................. STM32‬‬
‫انواع ‪ abstraction‬های موجود ‪01 .......................................................................................‬‬
‫دلیل استفاده از سیستم عامل جهت میکروکنترلرها ‪01...............................................................‬‬
‫سبک سیستم عامل چه مزایایی دارد ‪01 .................................................................................‬‬
‫در پس پرده ی سیستم عامل چه می گذرد؟ ‪01 ........................................................................‬‬
‫محدودیت های سبک کد نویسی معمولی‪01 ..........................................................................‬‬
‫مزایای سبک کد زنی سیستم عامل ‪00 ....................................................................................‬‬
‫از کجا شروع کنیم ‪02 ..........................................................................................................‬‬
‫‪ CMSIS-RTOS‬و ‪01 ....................................................................................... FreeRTOS‬‬
‫بیایید شروع کنیم ‪01 ..........................................................................................................‬‬
‫آموزش نرم افزار ‪01 ................................................................................. STM32cubeMX‬‬
‫تعریف اولین پروژه‪11 .........................................................................................................‬‬
‫تنظیمات پروژه در محیط ‪10..................................................................... STM32cubeMX‬‬
‫توسعه پروژه در محیط ‪22 ............................................................................................ Keil‬‬
‫تابع )(‪51.......................................................................................................... osDelaly‬‬
‫اولویت ‪51........................................................................................................... Priority‬‬
‫تعریف دومین پروژه ‪51 .......................................................................................................‬‬
‫سخن پایانی ‪11 .................................................................................................................‬‬

‫‪www.EasyMCU.org‬‬
‫‪5‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫مقدمه‬
‫روز به روز ترانزیستورها کوچکتر می شوند و سخت افزارها و نرم افزارها پیچیده تر‪.‬‬
‫با همه گیر شدن اینترنت و ظهور ایدهی اینترنت اشیاء (‪ ، )IoT‬از میکروکنترلرهای‬
‫سادهی امروزه هم انتظار میرود که به اینترنت متصل شده و بتوانند تبادل اطالعات‬
‫داشته باشند‪.‬‬

‫به بیان دیگر این انتظارات جزء انتظارات و نیازهای اولیهی خیلی از پروژههاست‪،‬‬
‫حال آنکه کار به همینجا ختم نمیشود و این شروعی برای پیادهسازی عملکردهای‬
‫خاص پروژه است‪ .‬بنابراین میتوان ادعا کرد که با توجه به پیچیدهتر شدن سخت‪-‬‬
‫افزار و نرمافزار و از همه مهمتر انتظارات کاربران‪ ،‬برنامهنویسان نیاز دارند روز به روز‬
‫توانایی پیادهسازی قابلیتهای بیشتری را داشته باشند‪ .‬چرا که معموال کاربرانی که‬
‫از محصوالت ما استفاده میکنند‪ ،‬ترجیح میدهند کارهای بسیار پیچیده را تنها با‬
‫استفاده از یک دکمه اجرا کنند‪ ،‬به عبارت دیگر‪ ،‬هرچه عملیات اجرا سادهتر‪ ،‬کار‬
‫طراحی و پیادهسازی آن توسط برنامهنویسان پیچیدهتر خواهد بود‪.‬‬

‫در زمان بسیار کوتاهی صنعت برنامهنویسی میکروکنترلرها‪ ،‬مانند دیگر صنایع‪،‬‬
‫دارای تحوالت جدی بوده است‪ ،‬با ورود میکروکنترلرهای ‪ ARM‬به بازار و تالش‬
‫شرکت های مختلف برای ارائه محصوالت متنوع متناسب با نیاز روز بازار‪ ،‬نوشتن‬
‫برنامه در سطح رجیستر که روزگاری سبک مرسومی برای برنامهنویسی پردازندهها‬
‫و میکروکنترلرها به شمار میرفت‪ ،‬امروزه در قیاس با گذشته طرفدار کمتری دارد‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪6‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫البته برنامه نویسی در سطح رجیستر هنوز از ضروریتهای هر برنامهنویسی است‬


‫که در حوزه ی امبدد سیستم ها فعالیت می کند‪ .‬همونطور که گفته شد انتظارات‬
‫از سختافزارها به طرز چشمگیری در دهههای اخیر دچار تحوالت جدی شده است‪،‬‬
‫این به این معنی است که همانطور که سختافزارهای امروزه‪ ،‬دیگر سختافزارها‬
‫و پردازندههای ساده گذشته نیستند‪ ،‬به منظور پیادهسازی پروژههای بزرگ امروزه‬
‫نیاز به سبکهای جدیدتر برنامهنویسی است‪ .‬روشهایی که بتوانند معادل با نیاز‬
‫بازار پیش بروند‪ ،‬در غیر اینصورت محکوم به شکست خواهند بود‪.‬‬

‫یکی از مهمترین اصلها در ارائه محصوالت به بازار ‪ ،‬زمان تحویل محصول به بازار‬
‫است‪ .‬این زمان اگر از حدی طوالنیتر شود به این مفهوم است که ایدهی ساخت‬
‫محصول از زمانی به بعد دیگر ایدهی جدیدی در نظر گرفته نمیشود و تاریخ انقضای‬
‫آن میگذرد‪ ،‬همینطور دیگر رقبا نیز در تالش برای پیادهسازی ایدههای جدیدتر و‬
‫خالقانه تر هستند‪ ،‬به بیانی دیگر اگر زمان بگذرد‪ ،‬بازار دیگر نیازی به آن محصول‬
‫نخواهد داشت‪.‬‬

‫خیلی از برنامهنویسان هنوز اصرار به نوشتن برنامه در سطح زبان و کد ماشین دارند‬
‫چرا که این روش را بهینه ترین روش در پیادهسازی کدها میدانند‪ .‬احتماال با خیلی‬
‫افراد برخورد کرده باشید که با زبان اسمبلی برنامهنویسی میکنند‪ ،‬زمانی که پیش‬
‫این برنامهنویسان از زبان ‪ C‬سخن به میان آید‪ ،‬زبان ‪ C‬در قیاس با زبان اسمبلی‬
‫یک زبان غیر بهینه مورد خطاب قرار می گیرد‪.‬‬

‫این وضعیت برای برنامه نویسانی که با ‪ C‬برنامهنویسی میکنند نیز صادق است‪،‬‬
‫اگر برنامهنویسی با زبان ‪ ، Basic ، C++‬پایتون پیش آنها عنوان شود‪ ،‬احتماال‬

‫‪www.EasyMCU.org‬‬
‫‪7‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫موضع یکسانی مشاهده خواهد شد‪ " ،‬این زبانها نامناسب هستند و به اندازه ‪C‬‬
‫بهینه نیستند! "‪.‬‬

‫بله‪ ،‬البته که منظور از قشر برنامهنویسان یاد شده‪ ،‬برنامهنویسان متعصب است‪،‬‬
‫همهی برنامهنویسان اینطور فکر نمیکنند‪ .‬البته نظر چنین برنامهنویسانی از نظر‬
‫بهینه بودن برنامههای نوشته شده تا حد زیادی درست است‪ ،‬اما مسئله از اینجا‬
‫شروع می شود که تنها مشکل در زمینهی امبدد سیستمها‪ ،‬بحث بهینه بودن‬
‫کدهای نوشته شده‪ ،‬نیست‪ ،‬بلکه همواره فاکتورهای دیگری برای تولید محصول‬
‫وجود دارد که باید مورد نظر قرار گیرد‪ .‬اگر بخواهیم مسائل را تنها با عینک بهینه‬
‫بودن کدها بررسی کنیم‪ ،‬جزء آن دسته از تیمهایی خواهیم بود که محصول را به‬
‫موقع نمیتوانند به بازار ارائه کنند!‬

‫ممکنه االن با خودتان بگویید که دارم در مورد چه چیزی حرف میزنم! همه چیز را‬
‫زیر سوال می برم و منکر قدرت زبانها و روشهای سنتی میشوم؟ً!‬

‫باید بگویم‪ ،‬مطلقا همچین هدفی را دنبال نمیکنم‪ ،‬علی رغم اینکه تغییر‪ ،‬کار بسیار‬
‫سختی برای نوع بشر است‪ ،‬از همهی همکاران و دوستان عزیزم دعوت میکنم که‬
‫بیایید در امر بهینهسازی‪ ،‬کامل گرایی نکنیم‪ ،‬چرا که در این صورت خیلی فاکتورهای‬
‫مهمتر دیگر را نمی توان رعایت کرد و نتیجه در مجموع مطلوب نخواهد بود‪ .‬البته‬
‫از آن طرف بوم هم نیفتیم که آنقدر به پلتفرم هایی نظیر آردوینو و ‪ ...‬رو بیاریم که‬
‫ابزار پرست بشویم و متکی‪ ،‬حالتی که اگر بعضی ابزارها از ما گرفته شود دیگر‬
‫نتوانیم برنامه نویسی کنیم!‬

‫‪www.EasyMCU.org‬‬
‫‪8‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

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

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

‫حالت دیگر این است که با گذشت زمان یک ماهه و بیشتر از زمانی که پروژه خاتمه‬
‫یافته است‪ ،‬زمانی که برنامه نویس به کدهای خود بر می گردد دیگر نمی تواند از‬
‫کدهای خود سر در بیاورد و قابلیت های جدید را پیاده ساز ی کند‪.‬‬

‫به عنوان حالتی دیگر در نظر بگیرید که کار برنامهنویسی تمام شده است و برنامه‪-‬‬
‫نویس دیگری می خواهد کار را در دست بگیرد و پروژه را ادامه دهد‪ ،‬منتها نمی‬
‫تواند با کدهای نوشته شده ا رتباط برقرار کند‪ ،‬از این جهت که ساختار خاصی برای‬
‫کدهای نوشته شده وجود ندارد! و ‪. ...‬‬

‫از این دست مثال ها زیاد است‪ ،‬و این موارد برنامهنوسان حرفهای را از مابقی‬
‫برنامه نویسان جدا می کند‪ .‬قابلیت خوانایی‪ ،‬قابلیت نگهداری و ‪ ...‬موارد ضروری‬
‫هستند که در زمان برنامهنویسی باید در نظر گرفته شود‪ .‬خیلی جاها ممکن است‬

‫‪www.EasyMCU.org‬‬
‫‪9‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫به دلیل خوانایی بیشتر کد بخواهیم از پیادهسازی پیچیده و بهینه بودن کد چشم‬
‫پوشی کنیم‪ ،‬چرا که اگر پیادهسازی پیچیده‪ ،‬ولو اینکه بهینه باشد‪ ،‬در صورتی که‬
‫قدرت خوانایی را بگیرد ارزشی نخواهد داشت‪.‬‬

‫عالقهمندید در مورد روشهای برنامهنویسی بیشتر بدانید؟ پس خواندن این کتاب‬


‫را ادامه دهید‪ ،‬چرا که در کتاب الکترونیکی پیش رو مقدمهای از روش کدنویسی به‬
‫سبک ‪ RTOS‬را عنوان خواهم کرد‪ RTOS ،‬مخفف عبارت ‪Real Time Operating‬‬
‫‪ System‬می باشد که معادل فارسی آن به سیستم عامل بالدرنگ ترجمه شده‬
‫است‪ .‬اگر در این رابطه اطالعاتی ندارید‪ ،‬یا صرفا نام آن را شنیده اید‪ ،‬نگران نباشید‪.‬‬
‫در این کتاب با استفاده از میکروکنترلر ‪ STM32‬و سیستمعامل بالدرنگ‬
‫‪ FreeRTOS‬در کنار هم یاد می گیریم که چطور می توان یک پروژه ساده را بر این‬
‫مبنا پیاده سازی کرد و این موارد را گام به گام با یکدیگر پیش خواهیم رفت‪.‬‬
‫امیدوارم حسابی لذت ببرید‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪10‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫برنامه نویسی‪ ،‬امری خداگونه!‬


‫اگر شما خواننده این مطلب هستید احتماال از قبل با پردازنده و میکروکنترلر آشنا‬
‫هستید‪ ،‬بنابراین در این بخش صرفا به یک مرور کلی بسنده می کنم‪ .‬همونطور که‬
‫می دونید دنیای میکروکنترلر دنیای ‪ 0‬و ‪ 1‬است‪ ،‬یک پردازنده در بعد سخت افزاری‬
‫معادل مغز در بدن انسان است‪ .‬روح این بدن‪ ،‬برنامه ایست که توسط برنامه‬
‫نویس نوشته می شود و بر روی میکروکنترلر برنامه ریزی می شود‪ .‬خاطرات این‬
‫برد‪ ،‬حافظه های به کار رفته در میکروکنترلر و سخت افزار آن می باشد‪ .‬دست و‬
‫پای این بدن‪ ،‬عملگرهای سخت افزاری از قبیل رله و ‪ ...‬ها هستند‪ ،‬سیستم عصبی‬
‫و ماهیچه های این بدن معادل ترانزیستورها و ‪ ...‬به کار رفته در سخت افزار می‬
‫باشد‪ .‬بنابراین گویی دنیای الکترونیک و سخت افزار از زاویه دیدی دیگر‪ ،‬شباهت‬
‫هایی با ما انسان ها دارد‪ ،‬حاال یک قدم به درک این موجود دوست داشتنی نزدیکتر‬
‫شده ایم‪.‬‬

‫با این تفاصیل پر واضح است که هدف ما در استفاده از میکروکنترلر در مدارات‬


‫الکترونیکی‪ ،‬دادن قدرت تصمیم گیری به سخت افزار است‪ .‬اما به خودی خود‬
‫میکروکنترلر و در نتیجه سخت افزار آن گویی تنها یک جسد بی جان و بی روح‬
‫است‪ .‬به بیان دیگر میکروکنترلر به خودی خود هیچ اراده ای از خود ندارد و از نظر‬
‫کاربردی مثل یک جسد است‪ ،‬با پاره آجر تفاوتی ندارد!‬

‫اینجاست که برنامه نویس ایفای نقش می کند و برنامه نویسی مفهوم پیدا میکند‬
‫و بدین سبب یک لوح پاک در اختیار برنامهنویس قرار میگیرد و اینجاست که‬

‫‪www.EasyMCU.org‬‬
‫‪11‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫برنامهنویس با قلم خود به این موجود بی جان روح میبخشد و سرنوشت آن را‬
‫قلم میزند‪ .‬گویی برنامهنویسی امریست خدا گونه‪ ،‬چرا که سراسر خلق مخلوق‬
‫است! هر برنامهای یک خلقت جدید و هر پروژهای یک مخلوق جدید!‬

‫شمایی که این مطلب را می خونید‪ ،‬اگر برنامهنویس هستی قدر خودت رو بیشتر‬
‫بدون و اگر تازه داری وارد وادی برنامه نویسی میشی‪ ،‬بدون که داری کجا پا‬
‫میذاری‪ ،‬این وادی ملکوتیه! از این زاویه بهش نگاه کن‪.‬‬

‫مرتضی زندی‬

‫بهار ‪99‬‬

‫سبک های برنامه نویسی؟‬


‫در کل سه سبک برنامه نویسی بنیادین به منظور برنامه نویسی میکروکنترلرها وجود‬
‫دارد‪.‬‬

‫‪Bare Metal‬‬ ‫‪.1‬‬


‫‪RTOS .2‬‬
‫‪OS .3‬‬

‫‪www.EasyMCU.org‬‬
‫‪12‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫از این بین دو مورد اول ‪ bare metal‬و ‪ RTOS‬روی اکثر میکروکنترلرها قابل پیاده‬
‫سازی می باشد‪.‬‬

‫سبک ‪OS‬‬

‫مورد سوم مربوط به پردازنده های نسل جدیدتر و قدرتمندتر می باشد که در دسته‬
‫بندی میکروکنترلرهای ‪ ARM‬جزء خانوادهی ‪ Application‬قرار دارند‪ .‬به این ترتیب‬
‫معماری این پردازنده های به گونه ای است که می توانند سیستم عامل های همه‬
‫منظوره نظیر لینوکس را بوت کنند‪ .‬برای اینکه ‪ OS‬اشتباها در عوض ‪ RTOS‬استفاده‬
‫نشود‪ ،‬می توانیم نام ‪ GPOS‬را به آن اختصاص دهیم که به معنی سیستم عامل‬
‫همه منظوره (‪ )General Purpose Operation System‬است‪.‬‬

‫سبک ‪Bare Metal‬‬


‫‪ Bare metal‬به سبکی گفته می شود که برنامه نویس از پایه شروع به برنامه‬
‫نویسی در سطح رجیستر می کند بدون اینکه از ‪ abstraction‬و یا الیه های دیگر‬
‫برنامه نویسی استفاده کند و یا از کتابخانه های ‪ third party‬استفاده کند‪ ،‬به این‬
‫ترتیب کل سناریوی برنامه نویسی به عهده خود برنامه نویس است‪ .‬در حقیقت‬

‫‪www.EasyMCU.org‬‬
‫‪13‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫همان روش مرسوم که تمام برنامه درون یک حلقه ی بینهایت (ابر حلقه) ( ‪Super‬‬
‫‪ )Loop‬نوشته می شود‪.‬‬

‫سیستم عامل ‪ RTOS‬چیست؟‬


‫‪ RTOS‬عبارت کوتاه شده ی ‪ Real Time Operating System‬است و در این‬
‫کتاب هدف ما می باشد‪ .‬این عبارت به سیستم عامل های بالدرنگ ترجمه شده‬
‫است‪ .‬در این سبک‪ ،‬برنامه نویس کد را به وظایفی برای اجرا توسط میکروکنترلر‬
‫تقسیم می کند‪ .‬به این ترتیب تابع ‪ main‬در روش ‪ bare metal‬به قسمتهای‬
‫کوچکتری تقسیم می شود و جداگانه در قالب تسک (‪ )Task‬های متفاوتی پیاده‬
‫سازی می شود‪.‬‬

‫سیستم عامل بالدرنگ شامل یک کرنل (‪ )Kernel‬و یک بخش زمانبندی کننده‬


‫(‪ )Scheduler‬است که وظیفه ی زمان بندی و اولویت بندی اجرای تسک ها را بر‬
‫عهده دارد‪ .‬در این سطح‪ ،‬برنامه نویس درگیر خود کرنل نمی شود و به حد مناسبی‬
‫از سطح رجیستر جدا می شود‪ .‬برنامه نویس نیازی ندارد درگیر کدهای ‪Kernel‬‬
‫شود و با خیال راحت صرفا از آن ها استفاده می کند و تمرکز بیشتر خود را بر روی‬
‫پیاده سازی اپلیکیشن مدنظر می گذارد‪ .‬یکی از مزایای اصلی این روش‪ ،‬زمان ارائه‬
‫محصول به بازار است‪ .‬در ادامه ی این کتاب در رابطه با سیستم عامل ‪ RTOS‬موارد‬
‫بیشتری را یاد می گیریم‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪14‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫در این بین یک اشتباه رایج وجود دارد و آن این است که عبارت های ‪ RTOS‬و‬
‫‪ OS‬بعضا به جای یکدیگر استفاده می شوند‪ .‬منظور از ‪ OS‬سیستم عامل های همه‬
‫منظوره هستند که بنابه دالیلی برای هر نوع عملکردی بر روی میکروکنترلرها مناسب‬
‫نمی باشند‪ RTOS .‬به سیستم عامل هایی اطالق می شود که زمان اجرای تسک‬
‫ها را گارانتی می کنند‪ ،‬به این ترتیب‪ ،‬برنامه نویس می تواند مطمئن باشد که‬
‫وظایف هارد‪-‬تایم )‪( (Hard-Time‬وظایفی که بحرانی و مهم هستند و حتما باید‬
‫در زمان معینی انجام شوند) قابل اجرا می باشد‪ .‬بنابراین ‪ RTOS‬ها و ‪ OS‬ها دو‬
‫مورد جداگانه هستند و نباید بجای یکدیگر به کار گرفته شوند‪ .‬همانطور که پیش‬
‫تر اشاره شد‪ ،‬برای جلوگیری از این اشتباه می توانیم از عنوان ‪ GPOS‬در عوض ‪OS‬‬
‫استفاده کنیم‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪15‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫سیستم عامل ‪FreeRTOS‬‬


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

‫میکرو ‪STM32‬‬
‫در دهه ی اخیر شاهد ورود میکروکنترلرهای متنوع با قابلیت های متفاوتی بودیم‬
‫که از این بین میکرو کنترلر های ‪ ARM‬سهم بسیار زیادی از بازار را بدست آوردند‪.‬‬
‫شرکت های مختلف میکروکنترلرهای خود را بر مبنای هسته ی ‪ ARM‬توسعه دادند‪،‬‬
‫بنابراین شرکت های مختلفی از جمله ‪ ST ، NXP ، ATMEL‬و ‪ ...‬میکروکنترلرهای‬

‫‪www.EasyMCU.org‬‬
‫‪16‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫‪ ARM‬با قابلیت های متنوعی را به بازار عرضه کردند‪ .‬از این بین شرکت ‪ ST‬گوی‬
‫سبقت را ربوده و عالوه بر ارائه میکروکنترلرهای خود‪ ،‬بردهای توسعه پذیر مناسبی‬
‫ارائه کرده است‪ .‬همینطور نرم افزارهایی به منظور تسریع کار با میکروکنترلرهای‬
‫خود و ساده سازی امر برنامه نویسی آن ها بوجود آورده است عالوه بر این سبک‬
‫های برنامه نویسی مختص خود را نیز بوجود آورده است‪ ،‬به این ترتیب در بازار‬
‫توجه هر برنامه نویسی که در حوزی سیستم های نهفته ( امبدد سیستم ها) کار‬
‫می کنند را ربوده است و خیلی از مهندسان به استفاده از میکروکنترلرهای این‬
‫شرکت روی آوردند‪.‬‬

‫انواع ‪ abstraction‬های موجود‬


‫‪ Abstraction‬ها الیه های نرم افزاری هستند که از پیش آماده شده هستند و‬
‫توسط شرکت های مختلف توسعه می یابند‪ ،‬به این ترتیب برنامه نویس در پروژه‬
‫های خود صرفا از آن ها استفاده می کند‪ ،‬به بیان دیگر برنامه نویس از سطح‬
‫کدهای رجیستر جدا می شود و بیشتر درگیر پیاده سازی اپلیکیشن مدنظر خود می‬
‫شود‪ .‬در گذشته با گسترده تر شدن استفاده از هسته ی ‪ ARM‬در میکروکنترلرهای‬
‫شرکت های مختلف‪ ،‬برنامه نویسی این نسل از میکروکنترلرها قدری پیچیده شده‬
‫بود‪ .‬علت این مورد این بود که هر شرکت به سلیقه ی خود واحدهای جانبی‬
‫میکروکنترلرها را در کنار پردازنده ی ‪ ARM‬قرار می داد و میکروکنترلر خود را تولید‬
‫می کرد‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪17‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫همین امر باعث می شد‪ ،‬کد نویسی در سطح ریجستر این میکروکنترلرها برای‬
‫محصوالت هر شرکتی متفاوت باشد و طبیعتا این مورد کار برنامه نویسان و توسعه‬
‫دهندگان سیستم های نهفته را به شدت سخت و پیچیده می کرد‪ .‬بنیاد ‪ARM‬‬
‫کتابخانه های استانداردی برای استفاده از میکروکنترلرهای ‪ ARM‬را با نام ‪CMSIS‬‬
‫معرفی کرد و شرکت های استفاده کنند از هسته ی ‪ ARM‬در محصوالت‬
‫میکروکنترلری خود را موظف کرد که برای محصوالت خود این کتابخانه ها را توسعه‬
‫دهند‪ ،‬به این ترتیب یک کتابخانه ی مرجع در آستانه ی ظهور بود که قابلیت حمل‬
‫کدها بین میکروکنترلرهای شرکت های مختلف را تا حدی باال می برد‪.‬‬

‫هر شرکت میکروکنترلری الیه های نرم افزاری متنوعی را برای محصوالت خود ارائه‬
‫داد که از این بین شرکت ‪ ST‬متنوع ترین سبک ها را دارد‪ .‬بعد از ‪ ، CMSIS‬سبک‬
‫‪ SPL‬برای این میکروکنترلر ارائه شده و در ادامه ‪ abstraction‬های ‪ HAL‬و ‪LL‬‬
‫ارائه شد‪.‬‬

‫دلیل استفاده از سیستم عامل جهت میکروکنترلرها‬


‫سبک برنامه نویسی میکروکنترلر را می توان به دو دسته ی کلی تقسیم کرد‪ .‬در‬
‫گذشته‪ ،‬میکروکنترلرها ساده بودند و نیازهای پروژه های کوچک مشخص بود‪،‬‬
‫برنامه نویسان میکروکنترلر به صورت ‪ Bare Metal‬کدنویسی می کردند و نیازهای‬
‫پروژه ی خود را پوشش می دادند‪ .‬اما میکروکنترلرهای امروزه با توجه به نیاز امروز‬

‫‪www.EasyMCU.org‬‬
‫‪18‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫تولید می شوند‪ ،‬امروزه نیازهای بسیار ی مطرح هست و مصرف کنندگان انتظارات‬
‫بسیار زیادی از دستگاه ها و به عبارت دیگر انتظارات زیادی از میکرو کنترلرها دارند‪.‬‬
‫برای مثال اتصال به اینترنت و استفاده از استک ‪ TCP/IP‬امروزه یک خواسته ی‬
‫بسیار ابتدایی و نیاز اولیه ی مصرف کننده ها شده است‪ .‬این در حالی است که در‬
‫سطح پیاده سازی‪ ،‬استک ‪ TCP/IP‬بسیار پیچیده است و پیاده سازی پیچیده ای‬
‫دارد‪ .‬اگر کدهای این بخش به صورت ‪ Bare Metal‬بخواهد توسعه یابد‪ ،‬یک‬
‫چرخه ی عمر کامل انسان را طلب می کند و طبیعتا اصال معقول نیست‪.‬‬

‫حال مصارفی چون ‪ USB‬و ‪ ...‬ها را نیز که در نظر بگیریم متوجه می شویم که این‬
‫واحدها دارای پیچیدگی های بسیار زیادی هستند و برنامه نویسی آن ها از ابتدا‬
‫هیچ توجیهی ندارد‪ .‬بنابراین یه سری از این کتابخانه ها به صورت ‪Third party‬‬
‫با الیسنس های متنوعی به صورت آزاد و یا پولی در اختیار توسعه دهندگان در‬
‫دسترس است‪ .‬به طبع با باالتر رفتن خواسته های مصرف کنندگان و ساده سازی‬
‫بیشتر استفاده از محصوالت‪ ،‬سطح کاری برنامه نویسان نیاز به تحول جدی داشته‬
‫و سبک های مختلفی معرفی شده است‪.‬‬

‫سبک سیستم عامل چه مزایایی دارد‬


‫باتوجه به موارد گفته شده در بخش قبل به این نتیجه می رسیم‪ ،‬زمانی که با پروژه‬
‫های پیچیده تر سر و کار داریم‪ ،‬سیستم عامل نقش ناجی را برای برنامه نویس‬

‫‪www.EasyMCU.org‬‬
‫‪19‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫خواهد داشت و می تواند کار برنامه نویسی را تسهیل کند‪ ،‬از این جهت که دیگر‬
‫کل برنامه درون یک ابر حلقه )‪ (Super Loop‬در تابع ‪ main‬نوشته نمی شود‪،‬‬
‫بنابراین برنامه ی بزرگ می تواند در بلوک های جداگانه ی کد‪ ،‬در قالب تسک‬
‫)‪ (Task‬های مختلف پیاده سازی شود و کار خوانایی‪ ،‬نگهداری و قابلیت حمل آن‬
‫را به میزان قابل توجهی افزایش دهد‪ .‬همینطور دیباگ کردن تسک ها می تواند‬
‫ساده تر شود‪.‬‬

‫در پس پرده ی سیستم عامل چه می گذرد؟‬


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

‫‪www.EasyMCU.org‬‬
‫‪20‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫در نظر بگیرید که قصد داریم برنامه ای بنویسیم که کارهای ذیل را به صورت‬
‫همزمان اجرا کند‪.‬‬

‫‪ .0‬دریافت و ارسال اطالعات بر روی باس ‪ USB‬و پردازش اطالعات آن‪.‬‬


‫‪ .0‬دریافت اطالعات ورودی از طریق کیبرد متصل به دستگاه‪.‬‬
‫‪ .1‬نمایش اطالعات بدست آمده و پردازش شده بر روی ‪.LCD‬‬
‫‪ .2‬کنترل و پخش یک فایل صوتی‪.‬‬
‫‪ .5‬کنترل پایه های ورودی‪/‬خروجی به صورت آنی جهت عملیات‬
‫کنترلی‪.‬‬
‫‪ .1‬ارتباط با انواع حافظه ها و سنسورها‬
‫‪ .1‬و ‪...‬‬

‫بنظر شما با استفاده از چه روشی می توانیم تمام این کارها را به صورت‬


‫همزمان انجام دهیم؟‬

‫محدودیت های سبک کد نویسی معمولی‬


‫همینطور که می بینید روش کد نویسی یاد شده در باال جوابگوی چنین‬
‫خواسته و عملکردی نیست و به هر میزان که این وظایف تعیین شده‬

‫‪www.EasyMCU.org‬‬
‫‪21‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫افزایش پیدا کنند و برنامه پیچیده تر شود ‪ ،‬روش یاد شده در باال کامال غیر‬
‫قابل استفاده خواهد بود و همینطور امکان نگهداری برنامه و ارتقاء آن در‬
‫آینده بسیار پیچیده و مشکل خواهد بود و در بعضی مواقع کامال غیر ممکن‬
‫است!‬

‫و اما راه حل چیست؟!‬

‫مزایای سبک کد زنی سیستم عامل‬


‫استفاده از ‪ RTOS‬در میکروکنترلرها‪ RTOS .‬کوتاه شده ی عبارت ‪Real‬‬
‫‪Time Operating System‬به مفهوم سیستم عامل بالدرنگ می باشد‪.‬‬
‫روش کد نویسی به سبک سیستم عامل‪ ،‬به برنامه نویس این امکان را می‬
‫دهد که پروژه خود را به تعدادی ‪( Task‬وظیفه) تقسیم و دسته بندی کند‬
‫و هر وظیفه را در یک ‪ Task‬مجزا و اختصاصی پیاده سازی کند‪ .‬هر ‪Task‬‬
‫شامل یک حلقه ی بینهایت مجزا می باشد و دخالتی در ‪ Task‬های دیگر‬
‫ندارد‪ .‬مثال یک پروژه می تواند به ‪ 4‬تسک ‪ D ، C ، B ، A‬تقسیم شود که‬
‫هر بخش به صورت مستقل ایفای نقش می کند‪ .‬همینطور می توان برای‬
‫هر ‪ Task‬اولویت اجرا در نظر گرفت که به این ترتیب کارهای مهم تر می‬
‫توانند در اولویت اجرای باالتری توسط پردازنده قرار بگیرند! همچنین با‬
‫استفاده از سیستم عامل‪ ،‬زمان پردازنده با دستورات تاخیر به هدر نمی رود‬

‫‪www.EasyMCU.org‬‬
‫‪22‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫و بجای تاخیر‪Task ،‬به خواب )‪ (sleep‬می رود و فرصت اجرا شدن را به‬
‫‪Task‬بعدی می دهد و به این ترتیب از ماکسیمم توان پردازنده می توان‬
‫بهره برد و بهینه ترین برنامه ها و عملکردها را می توان نوشت‪.‬‬

‫نتیجه‬
‫همانطور که دیده می شود‪ ،‬با استفاده از ‪ RTOS‬در میکروکنترلرها‪ ،‬امکان‬
‫درک پروژه پیاده سازی شده بیشتر می شود و در دراز مدت می توان پروژه‬
‫را به راحتی تحلیل کرد‪ ،‬همینطور در قالب ‪ Task‬های جدید ارتقاء داد‪ .‬عالوه‬
‫براین می توان اولویت اجرا برای هر وظیفه (تسک) قائل شد‪ .‬مورد قابل‬
‫توجه در دید ما‪ ،‬اجرا شدن تمام ‪ Task‬ها به صورت همزمان در کنار یکدیگر‬
‫است! این گفته صحبت قبلی را رد نمی کند‪ ،‬همچنان پردازنده توانایی اجرای‬
‫یک دستور در هر لحظه را دارد و نه بیشتر‪ ،‬و اما توسط سیستم عامل چطور‬
‫این اتفاق به صورت همزمان نمود می کند؟!‬

‫‪www.EasyMCU.org‬‬
‫‪23‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫سبک سیستم عامل‬

‫در واقع سیستم عامل در پشت پرده‪ ،‬یک هسته با برنامه نویسی پیچیده‬
‫دارد که نام آن ‪( Scheduler‬زمان بندی کننده) است‪ .‬به این ترتیب زمان‬
‫اجرای ‪ Task‬ها ‪ ،‬وقفه های حین اجرا ‪ ،‬اولویت ها و … همه و همه به‬
‫وسیله ی ‪ Scheduler‬کنترل می شود‪ Scheduler .‬زمان های محدودی در‬
‫حد چند میلی ثانیه برای اجرای هر ‪ Task‬قائل است که به آن تکه های‬
‫زمانی )‪ (Time Slice‬یا (‪ )Time Slot‬گفته می شود‪ .‬اگر تسک در حال‬
‫اجرا در این مدت زمان به اتمام نرسد‪ ،‬در صورتی که ‪ Task‬ای با اولویت‬
‫باالتر وجود داشته باشد‪ ،‬اجرای ‪ Task‬فعلی را متوقف می کند و خط اجرای‬
‫برنامه را به ‪ Task‬با اولویت اجرای باالتر می دهد و خطوط اجرا را از سر می‬
‫گیرد‪ .‬در زمان جابه جایی ‪ Task‬ها‪ ،‬به خاطر می سپارد که هر ‪ Task‬تا چه‬
‫خطی اجرا شده است و در دور بعدی که نوبت به اجرای همان ‪ Task‬برسد‪،‬‬
‫خط اجرا را از همان نقطه که متوقف شده بود‪ ،‬ادامه و از سر می گیرد‪.‬‬

‫به این ترتیب با اجرای سریالی از هر تسک به اندازه ی چند میلی ثانیه‪،‬‬
‫باعث می شود که در یک ثانیه‪ ،‬همه ی تسک ها چند بار به صورت مکرر‬
‫اجرا شوند و این امر موجب می شود که عملیات اجرای تسک ها همزمان‬
‫نمود کند و این مزیت ‪ RTOS‬است که به طراح این اطمینان را می دهد که‬

‫‪www.EasyMCU.org‬‬
‫‪24‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫نیازمندی های بحرانی )‪ (Hard Real-Time‬پروژه برآورده شود و از قلم‬


‫نیفتد‪.‬‬

‫از کجا شروع کنیم‬


‫خوب تا اینجا دید خوبی نسبت به میکروکنترها و نیازهای امروزه پیدا کردیم‪،‬‬
‫همینطور با سبک های برنامه نویسی مختلفی آشنا شدیم‪ ،‬حال ممکن است این‬
‫سوال برای شما پیش بیاید که حاال برنامه نویسی را از کجا باید شروع کنیم؟‬

‫اجازه بده ید بحث را با معرفی نرم افزارها و سخت افزارهای مورد نیاز برای شروع‬
‫یادگیری برنامه نویسی به سبک ‪ RTOS‬ادامه دهیم‪ .‬با توجه به توضیحات قبل یک‬
‫میکروکنترلر از میکروکنترلرهای شرکت ‪ ST‬را معرفی می کنم که برای شروع‬
‫میکروکنترلر ی ارزان و مناسب است و آن ‪ STM32F103C8Tx‬است‪ ،‬اگر عالقه‬
‫مند بودید که یک برد توسعه بر مبنای این میکروکنترلر تهیه کنید‪ ،‬برد ‪mini‬‬
‫‪ STM32‬یک برد ارزان و در دسترس است که اندازه کوچکی دارد و به راحتی می‬
‫توان آن را بر روی بردبورد متصل کرد و به روش ‪ SWD‬با پروگرامر‪/‬دیباگر ‪St-Link‬‬
‫و یا ‪ J-link‬کار برنامه ریزی برد را انجام داد‪ .‬تصویر برد و پروگرامر‪/‬دیباگرهای یاد‬
‫شده را در ذیل مشاهده می کنید‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪25‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫برد مینی ‪STM32‬‬

‫تصویر ‪St-Link‬‬

‫‪www.EasyMCU.org‬‬
‫‪26‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫تصویر ‪J-link‬‬

‫همانطور‪ ،‬از نرم افزار ‪ STM32cubeMX‬که توسط شرکت ‪ ST‬توسعه داده می‬
‫شود‪ ،‬استفاده می کنیم و واحدهای مورد نیاز را پیکربندی می کنیم تا بیس پروژه‬
‫آماده شود‪ .‬کار برنامه نویسی را در محیط ‪ Keil‬ادامه می دهیم و پروژه مدنظر را‬
‫پیاده سازی می کنیم‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪27‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫‪ CMSIS-RTOS‬و ‪FreeRTOS‬‬
‫در بخش های قبلی در مورد سیستم عامل بالدرنگ ‪ FreeRTOS‬صحبت کردیم‪.‬‬
‫همینطور فهیدیم که ‪ CMSIS‬به چه هدفی به وجود آمده است‪ .‬این اواخر‬
‫‪ CMSIS-RTOS‬نیز ارائه شده به این هدف که ‪ API‬هایی در اختیار برنامه نویس‬
‫قرار دهد که وی را از سطح خود سیستم عامل مورد استفاده جدا کند‪ ،‬حال آنکه‬
‫سیستم عامل مورد بحث می تواند ‪ FreeRTOS ، RTX‬و ‪ ...‬باشد‪ .‬به عبارت دیگر‬
‫این کتابخانه اصطالحا شامل ‪ wrapper‬هایی می باشد که ‪ API‬های ‪ RTOS‬را به‬
‫‪ CMSIS-RTOS‬می دوزد و زین پس برنامه نویس بجای اینکه از ‪ API‬های خود‬
‫‪ RTOS‬بخواهد استفاده کند‪ ،‬از ‪ API‬های ‪ CMSIS-RTOS‬استفاده می نماید‪ .‬به‬
‫بیانی دیگر ‪ CMSIS-RTOS‬می تواند الیه ای بین برنامه نویس و ‪ RTOS‬باشد‪.‬‬
‫به این ترتیب می توان ‪ API‬های ‪ CMSIS-RTOS‬را به طور کلی نادیده گرفت و‬
‫به طور مستقیم از ‪ API‬های ‪ RTOS‬موردنظر استفاده کرد‪.‬‬

‫خروجی ای که از نرم افزار ‪ STM32cubeMX‬می گیریم از ‪ FreeRTOS‬در الیه ی‬


‫زیرین ‪ CMSIS-RTOS‬استفاده می کند‪ .‬از طرفی برای شروع‪ ،‬استفاده از ‪CMSIS-‬‬
‫‪ RTOS‬قدری ساده تر از ‪ FreeRTOS‬می باشد‪ ،‬گرچه در نهایت نیاز به استفاده از‬
‫برخی از ‪ API‬های ‪ FreeRTOS‬است و در نهایت برای کاربری حرفه ای نیاز است‬
‫که با ‪ API‬های خود ‪ FreeRTOS‬نیز آشنا شوید‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪28‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫بیایید شروع کنیم‬


‫بسیار خوب فکر می کنم تا اینجای کار اطالعات خوبی را کسب کرده باشیم و زاویه‬
‫دید مورد نیاز برای کار عملی تا حد خوبی شکل گرفته باشد‪ .‬از آنجایی که به نظر‬
‫من شهود و مفهوم برای حرفهای شدن و پرداختن به عمق مطالب خیلی موثر و‬
‫مهم است‪ ،‬اولین مثال را بسیار ساده انتخاب میکنیم که بتوانیم از لحاظ شهودی‬
‫یک حس مناسب نسبت به عملکرد سیستمعامل و بلوکهای مجزای حلقهی‬
‫‪ while‬در قالب تسکهای مجزا داشته باشیم‪ .‬برای شروع به ابزارهایی نیاز داریم‬
‫تا بتوانیم ایدهمان را پیادهسازی کنیم‪ .‬در این کتاب از امکانات ‪ IDE‬محبوب و‬
‫قدرتمند ‪ Keil‬بهره میبریم‪ .‬همانطور به منظور تنظیمات اولیهی واحدهای‬
‫میکروکنترلر از نرمافزار ‪ STM32cubeMX‬استفاده میکنیم تا یک شروع سریع‬
‫داشته باشیم‪.‬‬

‫آموزش نرم افزار ‪STM32cubeMX‬‬


‫یک آموزش ویدئویی رایگان عالی برای نرم افزار ‪ STM32cubeMX‬در وبسایت‬
‫‪ easymcu.org‬برای شما آماده کردهایم که از طریق لینک زیر مستقیم به صفحهی‬
‫آموزش هدایت میشوید‪ .‬اگر این نرمافزار را نمیشناسید و یا تجربهی کمی در‬

‫‪www.EasyMCU.org‬‬
‫‪29‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫استفاده از این نرمافزار دارید‪ ،‬این آموزش عالی رو از دست ندید‪ ،‬حتی اگر با محیط‬
‫این نرم افزار هم آشنا هستید توصیه می کنم روی این آموزش یک مرور سریع‬
‫داشته باشید‪ .‬در ادامه اینطور در نظر میگیریم که با این محیط آشنایی دارید‪،‬‬
‫بنابراین توضیحات خالصهتری ارائه میشود‪.‬‬

‫‪https://easymcu.org/fa/product/stm32cubemx-video-tutorial/‬‬

‫‪www.EasyMCU.org‬‬
‫‪30‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫تعریف اولین پروژه‬


‫با استفاده از برد ‪ ، mini STM32‬قصد داریم دو پروژه پیادهسازی کنیم‪ ،‬یکی به‬
‫حالت ‪ Bare metal‬و دیگری با روش ‪ .RTOS‬به این ترتیب دو عدد ‪ LED‬را به‬
‫برد ‪ mini STM32‬متصل میکنیم‪ LED .‬شماره یک با تاخیر ‪ 300‬میلی ثانیه شروع‬
‫به چشمک زدن میکند‪ ،‬این تاخیر را ‪ DELAY_LOW‬نام گذاری میکنیم‪LED .‬‬
‫شماره دو با تاخیر ‪ 350‬میلی ثانیه چشمک میزند‪ ،‬این تاخیر را ‪DELAY_HIGH‬‬
‫نامگذاری میکنیم‪ .‬بنظر شما چه اتفاقی در آستانهی وقوع است؟ با توجه به تمام‬
‫توضیحات باال خروجی این دو روش قراره چه چیزی را نشان دهد؟ حتما قبل از‬
‫ادامه قدری فکر کنید (ممکنه پروژهی احمقانهای به نظر برسد‪ ،‬اما دید شهودی‬
‫خیلی خوبی را ارائه می دهد! پس این پروژه را دست کم نگیرید!)‬

‫قبل از خواندن ادامهی مطالب‪ ،‬توصیه می کنم نتیجهی پروژهی یاد شده را در لینک‬
‫زیر پیگیری کنید‪ ،‬در یک سمت ویدئو پیاده سازی با روش ‪ Super Loop‬و در‬
‫سمت دیگر با روش ‪ RTOS‬پیاده سازی شده است‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪31‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫‪https://www.aparat.com/v/yoB8q‬‬

‫اکنون که فیلم عملکرد پروژه را مشاهده کردید‪ ،‬حدس شما به نتیجه تا چه حد‬
‫نزدیک بود؟‬

‫عملکرد ویدئو را بعد از پیادهسازی پروژه بررسی میکنیم‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪32‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫تنظیمات پروژه در محیط ‪STM32cubeMX‬‬

‫تنظیم ‪GPIO‬‬

‫نرم افزار ‪ STM32cubeMX‬را اجرا میکنیم‪ ،‬آخرین ورژن این نرمافزار و نرم افزار‬
‫استفاده شده در این کتاب ورژن ‪ 5.6.1‬است‪ .‬در پروژهی اول که در باال تعریف‬
‫شده است‪ ،‬نیاز داریم که دو پایه از میکروکنترلر ‪ STM32F103C8x‬را به صورت‬
‫خروجی پیکربندی کنیم و در سختافزار آن دو عدد ‪ LED‬را متناظر با این پایهها در‬
‫نظر بگیرم‪ .‬مطابق تصویر زیر پایههای ‪ B12‬و ‪ B13‬از برد ‪ mini STM32‬را برای‬
‫این منظور اختصاص میدهیم‪ B12 .‬معادل ‪ LED1‬و ‪ B13‬معادل ‪ LED2‬خواهد‬
‫بود‪ .‬این موارد را در ادامه در محیط ‪ Keil‬به صورت ‪ Define‬شده در نظر می‬
‫گیریم‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪33‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫تنظیم ‪FreeRTOS‬‬

‫همینطور از بخش ‪ middleware‬مورد ‪ FreeRTOS‬را انتخاب میکنیم و تنظیمات‬


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

‫‪www.EasyMCU.org‬‬
‫‪34‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫تنظیم واحد ‪UART‬‬

‫واحد ‪ UART‬را به شرح تصویر زیر فعال میکنیم‪( .‬از این واحد برای پروژه بعدی‬
‫استفاده میکنیم)‪ .‬باود ریت را برابر ‪ 115200‬تنظیم می کنیم‪ 8 ،‬بیت دیتا‪1 ،‬‬
‫استاپ بیت‪ ،‬بدون بیت پریتی‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪35‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫تنظیم ‪SWD‬‬

‫در ادامه پایههای )‪ Serial Wire (SW‬را نیز از بخش ‪ SYS‬فعال میکنیم‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪36‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫در صورتی که اطالعات بیشتری در رابطه با پروگرام کردن این میکروکنترلر نیاز‬
‫دارید‪ ،‬لینکهای زیر توضیحات کاملی را پوشش دادهاند‪.‬‬

‫‪www.EasyMCU.org‬‬
37 ‫ برای میکروکنترلرها‬RTOS ‫برنامه نویسی به روش‬

Keil ‫ در‬ST-Link ‫ با‬STM32 ‫پروگرام کردن میکروکنترلر‬


https://easymcu.org/fa/stm32-stlink-keil-program/

STM32 ST-Link Utility ‫ با‬STM32 ‫پروگرام کردن میکروکنترلر‬


https://easymcu.org/fa/stm32-stlink-utility-program/

www.EasyMCU.org
‫‪38‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫پروگرام کردن میکروکنترلر ‪ STM32‬با ‪Jlink‬‬


‫‪https://easymcu.org/fa/program-st-jlink/‬‬

‫‪www.EasyMCU.org‬‬
‫‪39‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫تنظیم پایه های کریستال خارجی‬


‫در ادامه منابع کالک سیستم را تنظیم می کنیم‪ ،‬برای این منظور مطابق تصویر زیر‬
‫عمل میکنیم و کریستال خارجی را به میکروکنترلر متصل میکنیم‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪40‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫تنظیم فرکانس کاری پردازنده‬


‫سپس در بخش کالک میزان ماکسیمم فرکانس کاری پردازنده را در نظر میگیریم‪.‬‬
‫مطابق تصویر زیر برای برد ‪ mini STM32‬این مقدار برابر ‪ 72MHz‬تنظیم شده‬
‫است‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪41‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫تولید فایل پروژه‬


‫حاال تنظیمات پروژه را مطابق تصاویر زیر انجام میدهیم و با انتخاب دکمه ی‬
‫‪ Generate‬پروژه را تولید میکنیم‪ .‬جهت ادامه فرایند پیادهسازی پروژه به محیط‬
‫‪ Keil‬سوئیچ میکنیم‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪42‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫بعد از زدن دکمهی ‪ Generate‬یک پیغام اخطار نمایان میشود که این مورد را‬
‫گوش زد میکند‪ ،‬در زمان استفاده از ‪ FreeRTOS‬بهتر است از یک تایمر دیگر بجای‬
‫‪ Systick‬استفاده کنید‪ .‬اینجا قصد نداریم وارد جزئیات بشیم‪ .‬بنابراین پیغام را ‪OK‬‬
‫میکنیم و پروژه را تولید میکنیم‪ ،‬توضیحات بیشتر در این رابطه در آینده ارائه‬
‫خواهد شد‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪43‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫بعد از تولید فایل های پروژه یک پیغام ظاهر میشود مشابه تصویر زیر‪ .‬در صورتی‬
‫که بخواهید پروژه مستقیم در محیط کد نویسی اجرا شود‪ ،‬دکمه ‪Open Project‬‬
‫را انتخاب کنید‪ .‬در صورتی که بخواهید به پوشهی تولید فایلهای پروژه هدایت‬
‫شوید‪ ،‬دکمهی ‪ Open Folder‬را انتخاب کنید‪.‬‬

‫توضیحات این موارد در آموزش ‪ STM32cubeMX‬که در باال معرفی شد موجود‬


‫است‪ ،‬در صورتی که ابهامی دارید حتما آموزش ‪ STM32cubeMX‬را ببینید‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪44‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫توسعه پروژه در محیط ‪Keil‬‬


‫تا اینجا تنظیمات مورد نیاز برای پروژههای پیشرو را انجام دادهایم‪ ،‬در گام بعدی‬
‫ادامه فرایند پیاده سازی پروژه را در محیط کد نویسی ادامه میدهیم‪.‬‬

‫شروع کدنویسی حالت اول‬


‫حال اگر پروژهی ایجاد شده توسط ‪ STM32cubeMX‬را اجرا کنیم‪ ،‬و از منوی‬
‫کناری در سمت چپ نرم افزار ‪ ، Keil‬فایل ‪ main.c‬را باز کنیم‪ ،‬تصویری مشابه‬
‫تصویر زیر مشاهده می کنیم‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪45‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫همینطور که متوجه شدید با یک ‪ main.c‬نسبتا خام مواجه هستیم‪ .‬قبل از شروع‬


‫به کد نویسی تابع ‪ main‬را بررسی میکنیم‪( .‬کامنت های اضافه حذف شدهاند‪).‬‬

‫‪www.EasyMCU.org‬‬
‫‪46‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫در تصویر باال محتویات تنهی اصلی برنامه قابل مشاهده است‪.‬‬

‫بخش ‪ : 9‬این تابع به منظور پیکربندی کردن سبک برنامه نویسی ‪ HAL‬فراخوانی‬
‫شدهاست‪.‬‬

‫بخش‪ : 2‬این تابع سیستم کالک پردازنده را پیکربندی میکند‪.‬‬

‫بخش‪ : 9‬این بخش واحدهای ‪ GPIO‬و ‪ UART‬را پیکربندی میکند‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪47‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫بخش‪ : 4‬این بخش ‪ defaultTask‬را به عنوان یک تسک قابل اجرا در ‪RTOS‬‬


‫تعریف میکند‪.‬‬

‫بخش‪ : 5‬این تابع کرنل ‪ RTOS‬و ‪ Scheduler‬را اجرا میکند‪ ،‬به این معنی است‬
‫که ازین پس برنامه به سبک سیستم عامل اجرا میشود‪.‬‬

‫بخش‪ : 7‬در صورتی که سیستم عامل به درستی اجرا شود‪ ،‬خط برنامه نباید به‬
‫بخش ‪ 6‬برسد‪ ،‬در غیر اینصورت خطایی رخ دادهاست‪.‬‬

‫حاال برنامهی چشمکزن را به سبک سنتی پیادهسازی میکنیم‪ .‬دقت کنید که در‬
‫محیط ‪ STM32cubeMX‬واحدهای بیشتری را فعال کردهایم که در این پروژه از‬
‫آنها استفاده نمیکنیم‪ ،‬در عوض برای پروژه بعدی نیازی نیست مجدد به محیط‬
‫‪ STM32cubeMX‬مراجعه کنیم و تنظیمات بیشتری را انجام دهیم‪ .‬بنابراین‬
‫محتویات این تابع ‪ main‬را کامنت میکنیم که بعدا از آن استفاده کنیم و در عوض‬
‫یک تابع ‪ main‬جدید به عنوان گام اول پیادهسازی کرده که محتوای آن به شرح‬
‫زیر است‪.‬‬

‫‪//------------------------------------‬‬
‫‪//--> Macro Defenition‬‬
‫‪//------------------------------------‬‬

‫)‪#define LED1_SET(x‬‬ ‫)‪HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, x‬‬


‫)‪#define LED2_SET(x‬‬ ‫)‪HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, x‬‬
‫‪#define DELAY_LOW‬‬ ‫)‪(300‬‬
‫‪#define DELAY_HIGH‬‬ ‫)‪(350‬‬

‫‪www.EasyMCU.org‬‬
48 ‫ برای میکروکنترلرها‬RTOS ‫برنامه نویسی به روش‬

//---------------------------------------
//--> Super Loop method
//---------------------------------------

int main(void)
{
HAL_Init();
SystemClock_Config();

MX_GPIO_Init();

while(1)
{
{ //LED1
LED1_SET(1);
HAL_Delay(DELAY_LOW);
LED1_SET(0);
HAL_Delay(DELAY_LOW);
}

{ //LED2
LED2_SET(1);
HAL_Delay(DELAY_HIGH);
LED2_SET(0);
HAL_Delay(DELAY_HIGH);
}
}
}

www.EasyMCU.org
‫‪49‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫تعدادی ماکرو به منظور اعمال وضعیت ‪LED‬ها و تاخیرها در نظر گرفته شدهاست‪.‬‬
‫همانطور که مشاهده می شود در کد باال که به سبک سنتی در یک سوپر لوپ‬
‫(‪ )Super Loop‬نوشته شدهاست‪ ،‬دو بخش برنامه که یکی وضعیت ‪ LED1‬را‬
‫کنترل میکند و دیگری وضعیت ‪ LED2‬را کنترل میکند‪ ،‬کامال به یکدیگر مربوط‬
‫هستند و بر روی یکدیگر اثر میگذارند‪ .‬به عبارت دیگر تغییر وضعیت ‪ LED1‬بستگی‬
‫به تاخیرهای اعمالی به ‪ LED2‬هم دارد‪ ،‬و اگر بخواهیم وضعیت ‪ LED1‬را تغییر‬
‫دهیم‪ ،‬ناگزیریم بخش مربوط به ‪ LED2‬را نیز تغییر دهیم‪.‬‬

‫ممکن است به ذهنتان روشهای دیگر ی خطور کند‪ ،‬مثال برنامهنویسی بدون‬
‫استفاده از تاخیرهای به این سبک‪ ،‬یا با استفاده از تایمر و اختصاص شرطهای‬
‫زمانی موازی بین تسکها‪ ،‬یا روش استفاده از وقفه و ‪ ، ...‬اما در کل ایدهی اصلی‬
‫تمام روشهای یاد شده سوپر لوپ است و در نهایت وظایف برنامه که از حدی‬
‫بیشتر باشد به شرایط محدودی مانند مثال سادهی یاد شده در باال م رسد‪ .‬پس‬
‫این مثال ساده میتواند با یک پروژهی پیچیده و بزرگ پیاده سازی شده به روش‬
‫سوپر لوپ که حاال قصد تغییراتی بر روی آن را داریم‪ ،‬مدل شود‪ .‬پس لطفا از این‬
‫دید به ماجرای سبکهای کدنویسی نگاه کنید‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪50‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫به منظور دیدن نتیجه‪ ،‬سختافزار سادهای مشابه تصویر زیر بر روی بردبورد می‪-‬‬
‫بندیم‪.‬‬

‫برای مشاهده نتیجه‪ ،‬نیاز است که برنامه نوشته شده را با زدن دکمه ی ‪ F7‬کامپایل‬
‫و سپس برد ‪ mini STM32‬را پروگرام کنیم‪ .‬خروجی که نرم افزار‬
‫‪ STM32cubeMX‬تولید میکند‪ ،‬به صورت پیشفرض‪ ،‬نوع دیباگر‪/‬پروگرامر را‬
‫‪ ST-Link‬انتخاب میکند‪ .‬جهت آموزش نحوه ی پروگرام کردن برد ‪mini STM32‬‬
‫لینک های زیر را بررسی کنید‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪51‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫اگر عالقهمند به پروگرام کردن میکرو با استفاده از ‪ ST-Link‬در محیط ‪ Keil‬هستید‪،‬‬


‫لینک زیر را مشاهده کنید‪.‬‬

‫‪https://easymcu.org/fa/stm32-stlink-keil-program/‬‬

‫اگر عالقهمند به استفاده از ‪ ST-Link Utility‬هستید‪ ،‬لینک زیر را مشاهده کنید‪.‬‬

‫‪https://easymcu.org/fa/stm32-stlink-utility-program/‬‬

‫اگر عالقهمند به استفاده از ‪ JLink‬در محیط ‪ Keil‬هستید‪ ،‬لینک زیر را مشاهده‬


‫کنید‪.‬‬

‫‪https://easymcu.org/fa/program-st-jlink/‬‬

‫خروجی پروژه در حالت اول‬


‫ویدئوی خروجی این حالت را قبال در بخش تعریف پروژه با همدیگر مشاهده کردیم‪.‬‬
‫در این حالت مشاهده میشود که با توجه به تاخیرهایی که در برنامه لحاظ کردیم‬
‫و به ترتیبی که در برنامه تعیین کردیم‪LED ،‬ها شروع به چشمک زدن میکنند‪.‬‬
‫نکته قابل توجه این است که یک سیکل تکرار کامال ثابت را مشابه میکنیم‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪52‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫پیاده سازی حالت دوم‬


‫در این بخش به سراغ پیادهسازی به روش سیستم عامل ‪ FreeRTOS‬می رویم و‬
‫البته به منظور شروع ساده تر پروژه را با ‪ API‬های ‪ CMSIS-RTOS‬پیاده سازی‬
‫می کنیم‪ .‬تمام تنظیمات مورد نیاز در محیط ‪ STM32cubeMX‬از قبل انجام شده‬
‫است‪ .‬حال کافیست که روتین تابع ‪ main‬را به صورت ذیل پیاده سازی کنید‪ .‬برای‬
‫این منظور پیاده سازی روش سوپر لوپی که در گام قبلی انجام شد را می توانید‬
‫کامنت کنید‪ ،‬و روتین ابتدایی تابع ‪ main‬را که در گام قبلی کامنت کرده بودیم‪ ،‬از‬
‫حالت کامنت خارج کنید و به شکل ذیل آن را تغییر دهید‪ .‬طبیعتا کد ذیل را‬
‫مستقیم می توانید کپی پیست کنید‪.‬‬

‫از ‪ define‬های گام قبلی مستقیم در این مرحله نیز استفاده می کنیم‪.‬‬

‫)‪#define LED1_SET(x‬‬ ‫)‪HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, x‬‬


‫)‪#define LED2_SET(x‬‬ ‫)‪HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, x‬‬
‫‪#define DELAY_LOW‬‬ ‫)‪(300‬‬
‫‪#define DELAY_HIGH‬‬ ‫)‪(350‬‬

‫هر تسک نیاز به یک ‪ handle‬دارد‪ ،‬برای این منظور از کدهای ذیل استفاده می‬
‫کنیم‪.‬‬

‫‪//--> tasks handle definitions‬‬


‫;‪osThreadId led1TaskHandle‬‬
‫;‪osThreadId led2TaskHandle‬‬

‫‪www.EasyMCU.org‬‬
53 ‫ برای میکروکنترلرها‬RTOS ‫برنامه نویسی به روش‬

‫ باید تعریف شود‬main ‫روتین هر تسک باالی تابع‬

//--> tasks routine


definitions

void led1Task(void const * arg);


void led2Task(void const * arg);

‫ به این صورت خواهد بود‬main ‫محتوای تابع‬

int main(void)
{
//--> Init System
HAL_Init();
SystemClock_Config();

//--> Config peripherals


MX_GPIO_Init();
MX_USART1_UART_Init();

//--> Task1 Definition


osThreadDef(task1, led1Task, osPriorityNormal, 0, 128);
led1TaskHandle = osThreadCreate(osThread(task1), NULL);

//--> Task2 Definition

www.EasyMCU.org
‫‪54‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫;)‪osThreadDef(task2, led2Task, osPriorityNormal, 0, 128‬‬


‫;)‪led2Taskhandle = osThreadCreate(osThread(task2), NULL‬‬

‫‪//--> Start Scheduler‬‬


‫;)(‪osKernelStart‬‬

‫)‪while (1‬‬
‫{‬

‫}‬
‫}‬

‫در تصویر فوق ‪ 2‬عدد تسک تعریف شده‪ ،‬تسک ‪ 1‬وظیفه ی کنترل ‪ LED1‬را بر عهده‬
‫دارد و تسک ‪ 2‬وظیفه ی کنترل ‪ LED2‬را بر عهده دارد‪ .‬در تصویر فوق صرفا این دو‬
‫تسک را در بدنه ی تابع ‪ main‬تعریف کردیم‪ .‬در آینده به جزئیات بیشتر می‬
‫پردازیم‪.‬‬

‫در گام بعدی روتین وظیفه ی هر کدام از تسک ها را به صورت جداگانه پیاده سازی‬
‫می کنیم که مشابه یک حلقه ی مستقل بینهایت اختصاصی به ازاء هر تسک می‬
‫باشد‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪55‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫پیاده سازی تسک ‪1‬‬


‫در این تسک ‪ LED1‬را با تاخیر ‪ DELAY_LOW‬به صورت چشمک زن در می آوریم‪،‬‬
‫برای این منظور روتین مربوط به این تسک را به شرح کد ذیل پیاده سازی می‬
‫کنیم‪.‬‬

‫پیاده سازی تسک ‪ 1‬به شرح ذیل می باشد‪.‬‬

‫‪//--> task1 routine‬‬


‫)‪void led1Task(void const * arg‬‬
‫{‬
‫)‪while(1‬‬
‫{‬
‫;)‪LED1_SET(1‬‬
‫;)‪osDelay(DELAY_LOW‬‬
‫;)‪LED1_SET(0‬‬
‫;)‪osDelay(DELAY_LOW‬‬
‫}‬
‫}‬

‫پیاده سازی تسک ‪2‬‬


‫در این تسک ‪ LED2‬را با تاخیر ‪ DELAY_HIGH‬به صورت چشمک زن در می‬
‫آوریم‪ .‬پیاده سازی این تسک به شرح کد ذیل می باشد‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪56‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫‪//--> task2 routine‬‬


‫)‪void led2Task(void const * arg‬‬
‫{‬
‫)‪while(1‬‬
‫{‬
‫;)‪LED2_SET(1‬‬
‫;)‪osDelay(DELAY_HIGH‬‬
‫;)‪LED2_SET(0‬‬
‫;)‪osDelay(DELAY_HIGH‬‬
‫}‬
‫}‬

‫برنامه ی جدید را که بر مبنای ‪ RTOS‬پیاده سازی شده است‪ ،‬با استفاده از دکمه‬
‫‪ F7‬کامپایل می کنیم و برد را مجدد برنامه ریزی یا اصطالحا پروگرام می کنیم‪.‬‬

‫خروجی حالت دو‬


‫ویدئوی خروجی این حالت را در بخش تعریف پروژه با همدیگر دیدیم‪ .‬همینطور‬
‫که مشاهده می شود‪ ،‬مشخصا هر ‪ LED‬به صورت مستقل با توجه به میزان تاخیری‬
‫که برای آن لحاظ شده‪ ،‬شروع به چشم زدن می کند و این امر کامال مستقل از ‪LED‬‬
‫دیگری است و این دو تسک به یک دیگر وابستگی ندارند‪ .‬به عبارت دیگر ‪LED1‬‬
‫با تاخیر ‪ DELAY_LOW‬چشمک می زند‪ ،‬این در حالیست که ‪ LED2‬با تاخیر‬

‫‪www.EasyMCU.org‬‬
‫‪57‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫‪ DELAY_HIGH‬چشمک می زند‪ .‬نکته قابل توجه اینجاست که ‪ DELAY_LOW‬و‬


‫‪ KELAY_HIGH‬هیچ تاثیری بر روی یک دیگر ندارند‪ .‬به همین ترتیب با توجه به‬
‫متفاوت بودن میزان تاخیرهای دو تسک‪ ،‬زمانی که برنامه شروع به اجرا می کند‪،‬‬
‫با گذر زمان مشاهده می شود که فاصله زمانی چشمک زدن دو ‪ LED‬نسبت به‬
‫یکدیگر ثابت نیست و تغییر می کند‪ ،‬چرا که نسبت به یکدیگر مستقل هستند و‬
‫به ازاء تاخیرهای اعمال شده‪ ،‬منتظر یکدیگر نمی مانند‪.‬‬

‫تابع )(‪osDelaly‬‬
‫این تابع یکی از ‪ API‬های ‪ CMSIS-RTOS‬می باشد که به موجب آن‪ ،‬روتین‬
‫اجرای تسکی که در آن فرا خوانی می شود را به میزان تعیین شده در ورودی تابع‬
‫به از حالت ‪ RUN‬خارج کرده و به حالت ‪ Ready‬می برد‪ .‬به عبارت دیگر این تابع‬
‫درون هر تسکی فراخوانی شود‪ ،‬آن تسک را به میزان تعیین شده می خواباند‪ ،‬در‬
‫این بین اگر تسک دیگری آماده ی اجرا باشد‪ ،‬فرصت اجرا را در دست می گیرد و‬
‫هیچ زمانی تلف نمی شود‪.‬‬

‫در سبک کد نویسی معمولی با استفاده از تابع )(‪ CPU ،delay‬را مجبور می کنیم‬
‫که دور باطل بزند‪ ،‬تا زمان تاخیر مورد نیاز ما برآورده شود‪ ،‬و این به مفهوم اتالف‬
‫زمان ‪ CPU‬می باشد‪ .‬اما در سبک سیستم عامل بالدرنگ‪ ،‬این میزان تاخیر با مفهوم‬

‫‪www.EasyMCU.org‬‬
‫‪58‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫دیگری اجابت می شود و از این زمان تاخیر برنامه استفاده می کند تا فرصت اجرای‬
‫برنامه را به تسکی بدهد که آماده ی اجرا می باشد‪.‬‬

‫حال ممکن است این سوال پیش بیاید که اگر هیچ تسکی آماده ی اجرا نباشد‪،‬‬
‫چه اتفاقی می افتد؟ در این حالت یک تسک پیشفرض به نام ‪ Idle‬در زمان اجرای‬
‫‪ scheduler‬ایجاد می گردد که در زمانی که تسکی در حال اجرا نباشد‪ ،‬این مورد‬
‫را به عهده بگیرد‪ ،‬به این ترتیب می توان اجرای تسک ها و وظایف را بهینه کرد و‬
‫حتی در زمانی که تسکی در حال اجرا نیست هسته را در حالت ‪Power Down‬‬
‫قرار داد که به میزان قابل توجه ای در مصرف انرژی صرفه جویی می کند و برای‬
‫دستگاه های پرتابل‪ ،‬زمان کارکرد طوالنی تری را به ازاء هر بار شارژ دستگاه در پی‬
‫دارد‪.‬‬

‫اولویت ‪Priority‬‬
‫زمانی که تسک ها را تعریف می کنیم‪ ،‬این امکان را داریم که اولویت اجرای آنها را‬
‫نیز تعیین کنیم‪ ،‬به این مفهوم است که اگر وظیفه ای دارای اولویت اجرای باالتر‬
‫باشد‪ ،‬و زمان اجرا شدن آن فرا رسیده باشد در حالی که در این لحظه یک تسک با‬
‫اولویت پایین تر در حال اجرا می باشد‪ scheduler ،‬تسک در حال اجرا را به حالت‬
‫‪ Ready‬می برد و تسک با اولویت باالتر را در حالت اجرا قرار می دهد‪ .‬اصالحا به‬

‫‪www.EasyMCU.org‬‬
‫‪59‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫این وضعیت گفته می شود که تسک با اولویت باالتر درون تسک با اولویت پایین‬
‫تر ‪ preempt‬شده است‪.‬‬

‫تعریف دومین پروژه‬


‫به منظور آشنایی بیشتر و البته مقدماتی به منظور تعیین اولویت برای تسک ها‪،‬‬
‫پروژه ی دیگری را پیاده سازی می کنیم‪ .‬در این پروژه دو تسک مجزا را پیاده سازی‬
‫می کنیم‪ ،‬در حالی که هر کدام از تسک ها به صورت جداگانه یک عبارت مشخص‬
‫را در محیط ترمینال پرینت می کنند‪ .‬یک بار به تسک اول اولویت ‪ 1‬می دهیم و به‬
‫تسک ‪ 2‬الویت ‪ 2‬می دهیم و خروجی را بررسی می کنیم‪ .‬بار بعدی جای اولویت‬
‫ها را تغییر می دهیم و مجدد نتیجه را بررسی می کنیم‪ .‬البته که تعیین اولویت ها‬
‫بحث بسیار گشترده تری هست و این مثال صرف به تنهایی نمی تواند حق مطلب‬
‫را ادا کند‪ ،‬اما دید مناسبی جهت ادامه مسیر یادگیری سیستم عامل پیدا خواهید‬
‫کرد‪.‬‬

‫‪www.EasyMCU.org‬‬
‫‪60‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫پیاده سازی حالت ‪1‬‬


‫توجه شود که در گام اول و در پروژه قبلی در محیط ‪ STM32cubeMX‬کار‬
‫تنظیمات واحد ‪ UART‬انجام پذیرفت‪ ،‬اما در پروژه قبلی نیازی به این واحد‬
‫نداشتیم و از این واحد در پروژه قبل استفاده نکردیم‪.‬‬

‫تعریف تسک ها‬


‫هر تسک نیاز به یک ‪ handle‬دارد‪ ،‬برای این منظور از کدهای ذیل استفاده می‬
‫کنیم‪.‬‬

‫‪//--> tasks handle definitions‬‬


‫;‪osThreadId task1Handle‬‬
‫;‪osThreadId task2Handle‬‬

‫روتین هر تسک باالی تابع ‪ main‬باید تعریف شود‪.‬‬

‫‪//--> tasks routine definitions‬‬


‫;)‪void task1(void const * arg‬‬

‫‪www.EasyMCU.org‬‬
61 ‫ برای میکروکنترلرها‬RTOS ‫برنامه نویسی به روش‬

void task2(void const * arg);

.‫یک ماکرو به منظور پرینت کردن اطالعات به شرح زیر تعریف می کنیم‬

#include <string.h>
#define Print(x) HAL_UART_Transmit(&huart1, (uint8_t*)x, strlen(x), 100);

‫ مربوط به واحد‬init ‫ مطمئن شوید که تابع‬main ‫در این پروژه کافیست که در تابع‬
‫ به شرح ذیل‬main ‫ به این ترتیب محتویات تابع‬.‫ فراخوانی شده است‬UART
.‫ به تعریف تسک ها می پردازیم‬main ‫ مشابه قبل در تنه ی تابع‬.‫خواهد بود‬

int main(void)
{
//--> Init System
HAL_Init();
SystemClock_Config();

//--> Config peripherals


MX_GPIO_Init();
MX_USART1_UART_Init();

//--> Task1 Definition


osThreadDef(t1, task1, 2, 0, 128); //--> 2 as higher priority
led1TaskHandle = osThreadCreate(osThread(t1), NULL);

www.EasyMCU.org
62 ‫ برای میکروکنترلرها‬RTOS ‫برنامه نویسی به روش‬

//--> Task2 Definition


osThreadDef(t2, task2, 1, 0, 128); //--> 1 as lower priority
led2Taskhandle = osThreadCreate(osThread(t2), NULL);

//--> Start Scheduler


osKernelStart();

while (1);
}

1 ‫تعریف روتین تسک‬


1 ‫ یک عبارت ثابت که معرف تسک‬.‫ به صورت کد ذیل می باشد‬1 ‫محتویات تسک‬
‫ به سمت ترمینال‬UART ‫در حال اجرا است که با استفاده از تابع مربوط به واحد‬
.‫کامپیوتر پرینت می شود‬

//--> task1 routine


void task1(void const * arg)
{
while(1)
{
Print("This is Task 1\r\n");
osDelay(500);
}
}

www.EasyMCU.org
‫‪63‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫تعریف روتین تسک ‪2‬‬


‫محتویات تسک ‪ 2‬به صورت کد ذیل می باشد‪ .‬یک عبارت ثابت معرف تسک ‪ 2‬در‬
‫حال اجرا است که با استفاده از تابع مربوط به واحد ‪ UART‬به سمت ترمینال‬
‫کامپیوتر پرینت می شود‪.‬‬

‫‪//--> task2 routine‬‬


‫)‪void task2(void const * arg‬‬
‫{‬
‫)‪while(1‬‬
‫{‬
‫;)"‪Print("This is Task 2\r\n‬‬
‫;)‪osDelay(500‬‬
‫}‬
‫}‬

‫نتیجه حالت اول‬


‫همانطور که مشاهده می شود‪ ،‬تسکی که اولویت ‪ 2‬به آن انتصاب داده شد‪ ،‬زودتر‬
‫از تسک دیگری اجرا شد‪ .‬به این ترتیب اول پیام موجود در تسک ‪ 1‬چاپ شد و‬
‫سپس پیام تسک ‪ .2‬این نتیجه قابل تعمیم است و همانطور که گفته شد در صورتی‬
‫که تسک با اولویت اجرایی در حال اجرا باشد و در همین حین زمان اجرای تسک‬

‫‪www.EasyMCU.org‬‬
‫‪64‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫با اولویت باالتر شده باشد‪ ،‬این تسک منتظر‪ ،‬منتظر تسک اولویت پایین در حال‬
‫اجرا نمی ماند تا تمام بشود و اصطالحا تسک با اولویت باالتر درون تسک با اولویت‬
‫کمتر که در حال اجراست ‪ preempt‬می شود و تسک در حال اجرا را به حالت‬
‫‪ Ready‬می برد‪.‬‬

‫‪This is Task 1‬‬


‫‪This is Task 2‬‬
‫‪This is Task 1‬‬
‫‪This is Task 2‬‬
‫‪This is Task 1‬‬
‫‪This is Task 2‬‬
‫‪This is Task 1‬‬
‫‪This is Task 2‬‬

‫پیاده سازی حالت دوم‬


‫در این حالت کافیست جای اولویت تسک های ‪ 1‬و ‪ 2‬را با یکدیگر جابه جا کنیم‪،‬‬
‫به این ترتیب فقط روتین تابع ‪ main‬نیاز به تغییر دارد‪ .‬به این ترتیب خط های‬
‫ذیل را جایگزین می کنیم‪.‬‬

‫‪//--> Task1 Definition‬‬


‫;)‪osThreadDef(t1, task1, 1, 0, 128‬‬ ‫‪//--> 1 as lower priority‬‬
‫;)‪led1TaskHandle = osThreadCreate(osThread(t1), NULL‬‬

‫‪www.EasyMCU.org‬‬
65 ‫ برای میکروکنترلرها‬RTOS ‫برنامه نویسی به روش‬

//--> Task2 Definition


osThreadDef(t2, task2, 2, 0, 128); //--> 2 as higher priority
led2Taskhandle = osThreadCreate(osThread(t2), NULL);

‫نتیجه حالت دوم‬


‫نتیجه این می شود که می بینیم در محیط ترمینال اول تسک با اولویت باالتر اجرا‬
1 ‫ دارای اولویت باالتری می باشد و سپس تسک‬2 ‫می شود که در اینجا تسک‬
.‫اجرای می شود‬

This is Task 2
This is Task 1
This is Task 2
This is Task 1
This is Task 2
This is Task 1

www.EasyMCU.org
‫‪66‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫نتیجه‬
‫تا اینجا به یک درک بسیار ابتدایی از عملکرد ‪ RTOS‬رسیدیم‪ .‬با پیاده سازی پروژه‬
‫به روش ‪ Super Loop‬و ‪ RTOS‬آشنا شدیم و در کنار یکدیگر دیدیم که استفاده‬
‫از ‪ RTOS‬همچین هم پیچیده به نظر نمی رسد و بسیار روش دلچسب‪ ،‬دقیق و‬
‫مطمئنی است مخصوصا برای پروژه های بزرگ‪ ،‬پروژه هایی که تسک هایی برای‬
‫اجرای همزمان نیاز دارد‪ ،‬مثل پروژه هایی که دارای رابط گرافیکی هستند و یا به‬
‫شبکه اینترنت متصل می شوند و در حیطه ی پروژه های ‪ IOT‬قرار می گیرند‪ .‬در‬
‫دهه ی پیش رو آنطور که نیازمندی های شرکت ها گویاست‪ ،‬تمایل به استفاده از‬
‫سیستم عامل های بالدرنگ در پروژه ها بسیار بیشتر از پیش به چشم می خورد و‬
‫اما سخن پایانی ‪...‬‬

‫‪www.EasyMCU.org‬‬
‫‪67‬‬ ‫برنامه نویسی به روش ‪ RTOS‬برای میکروکنترلرها‬

‫سخن پایانی‬
‫با این تفاسیل پر واضح است که توانایی برنامه نویسی بر پایه ی سیستم های‬
‫بالدرنگ امروزه تبدیل به یک ضرورت شده است‪ .‬اگر عالقه مند به پیشرفت و‬
‫تضمین موقعیت شغلی خود در آینده هستید‪ ،‬پیشنهاد می کنم که سری به وبسایت‬
‫‪ easymcu.org‬بزنید و در کنار دیگر مهندسان خواهان پیشرفت حضور یابید‪.‬‬
‫امیدوارم که در دورهی ‪ FreeRTOS‬همراه شما باشیم‪.‬‬

‫ارادتمند شما ‪...‬‬


‫مرتضی زندی‬
‫‪www.easymcu.org‬‬

‫دوره آموزش ‪FreeRTOS‬‬


‫‪https://easymcu.org/fa/product/freertos-course-for-‬‬
‫‪microcontrollers/‬‬

‫‪www.EasyMCU.org‬‬

You might also like