شناخت انواع حافظه آردوينو و بهینه سازی آن
مقدمه
سلام دوستان در این جلسه می خواهیم در مورد حافظه ها و رفع مشکل اون ها در بردهای آردوینو بحث کنیم. ابتدا انواع معماری های مربوط به حافظه ها رو توضیح میدیم و سپس انواع حافظه ها رو در آردوینو با هم دیگه میشناسیم و در انتها روش هایی برای حل مشکل کمبود حافظه در آردوینو ارایه میدیم. پیشنهاد من این هست که اگه هیچ آشنایی با آردوینو ندارید ، ابتدا از لینک زیر نگاهی به دوره مقدماتی آردوینو وبسایت داشته باشید:
انواع معماری حافظه ها
معماری Von-Neumann
معماری ون نیومن که برای ENIAC (اولین کامپیوتری که ساخته شد) توسعه داده شده بود مسیر داده و برنامه یکی بود. در شکل زیر بوضوح مشاهده می شود که مسیر ذخیره داده و برنامه یکسان است یعنی کلا یک مموری برای هر دوتا بود:
معماری Harvard
معماری هاروارد که نوع دوم بود مسیر داده و برنامه کاملا جدا بود یعنی داده ها یه جایی ذخیره میشد و برنامه هم یه جای دیگه ذخیره میشد. در شکل زیر می بینید که دوتا حافظه جداگانه برای هر کدوم داریم:
کدام بهتر است؟
هر معماری مزایای خاص خودش را دارد. معماری هاروارد یک لبه اجرایی دارد و معماری ون نیومن انعطاف پذیری بالایی دارد.
مدل های دوگانه:
امروزه مدلهای حافظه از هر دونوع معماری استفاده می کنند تا بهترین نتیجه را بگیرند
حافظه آردوینو و میکروکنترلرها
میکروکنترلرهایی که در آردوینو استفاده می شود تقریبا از مدل هاروارد استفاده می کنند.برای مثال Atmega 328 که در آردوینو UNO استفاده شده است را در نظر بگیرید که برنامه ها در حافظه FLASH ریخته می شود و داده های تولید شده در حافظه SRAM ذخیره می شود. حافظه آردوینوUNO دارای 32کیلو بایت حافظه FLASH و 2کیلوبایت حافظه SRAM است. یعنی 100000 برابر کمتر از حافظه یک کامپیوتر شخصی مدل پایین است. بنابرین کارکردن در این محیط ریز باید با خردمندی صورت پذیرد.
سه نوع حافظه آردوینو داریم:
- حافظه Flash
- حافظه SRAM
- حافظه EEPROM
حافظه Flash
حافظه فلش برای ذخیره عکس برنامه و داده های اولیه ای که در برنامه استفاده می شود. شما می توانید برنامه را در حافظه فلش اجرا کنید ولی برنامه اجرا شده را در حافظه فلش نمی توانید اصلاح کنید. برای اصلاح برنامه ابتدا باید در حافظه SRAM کپی شود و سپس اصلاح کنید.
حافظه فلش دارای عمر محدود 100000 بار نوشتن است. یعنی اگر شما هر روز یک برنامه را روی حافظه فلش لود کنید تا 27 سال طول می کشد تا این حافظه از بین برود.
حافظه SRAM
مخفف Static Random Access Memory است. این حافظه هم خواندنی است و هم نوشتنی است. از این حافظه برای موارد زیر استفاده می شود:
- static data: این قسمت از حافظه برای داده های کلی و متغیرهایی که دارای مقادیر ثابت هستند رزرو شده است. متغیرهایی که دارای مقادیر اولیه هستند ابتدا از حافظه فلش به این قسمت از حافظه کپی می شوند و سپس برنامه اجرا میشود.
- Heap: این قسمت برای داده های دینامیکی است(منظور همون داده هایی است که تغییر میکنند و میان و میرن و… داده هایی که خیلی ورجه وورجه میکنن). محل قرارگیریش هم اگه به شکل نگاه کنید از بالای Static Ram هست تا جایی که کل آیتم های داده هاست.
- Stack: این قسمت برای داده های محلی است و برای نگهداری داده های مربوط به وقفه و فراخوانی توابع. محل قرارگیریش هم باتوجه به شکل از بالای حافظه شروع میشه و میاد به سمت Heap.
مشکل اکثر حافظه ها زمانی است که قسمت Static و Heap با هم برخورد میکنن. هنگامی که این دوتا قسمت حافظه به هم میخورن خیلی از نتایج هم غیرقابل پیش بینی میشه.
حافظه EEPROM
این نوع حافظه هم خواندنی است و هم نوشتنی. فقط بیت به بیت می توان آن را خواند بنابراین برای استفاده مشکلاتی به همراه می آورد.سرعت آن از SRAM کمتر است و می تونید 100000بار داخل اون برنامه بریزید.
درسته که به پای ارزش های SRAM نمیرسه ولی یه جاهایی واقعا سودمنده.
مقایسه حافظه های آردوینو
در جدول زیر میتوانید حافظه آردوینو مدل هاي مختلف رو با هم مقایسه کنید
اندازه گیری میزان استفاده شده در حافظه آردوینو
حافظه Flash
یک روش برای تشخیص مشکلات مربوط به حافظه اینه که میزان حافظه ای که استفاده کردیم رو اندازه گیری کنیم.
اندازه گیری حافظه فلش راحته و خود کامپایلر آردوینو این کار رو براتون انجام میده. بعنی هر بار که برنامه رو کامپایل کنید تو کادر پایینش می تونید ببینید که چقد حجم برنامتونه. در شکل زیر میبینید که برنامه چشمک زن رو اجرا کردیم و چون من آردوینو MEGA2560 رو انتخاب کردم عدد253982 ظاهر شد که با جدول بالا میتوانید مقایسه کنید.
نکته: 1 کیلوبایت= 1024 بایت
حافظه EEPROM
کنترل حافظه EEPROM بطور کامل در اختیار شماست چون شما مجبورید برای هر بیت که در این حافظه استفاده می کنید آدرس دهی می کنید یعنی اگر نوشتید BOOK باید برای دونه به دونه هر بیت یک آدرس تعیین کنید و بگید که جای هر چیز کجاست. بنابراین جای هیچ عذر و بهانه ای برای ندانستن میزان استفاده شده وجود ندارد.
مصرف کننده های بزرگ حافظه
کارت های SD
برای ارتباط با SD کارت نیاز به 512بایت حافظه بافر SRAM دارد.
پیکسل ها
هر پیکسل به 3بایت حافظه SRAM جهت ذخیره رنگ نیاز دارد و هنگامی که یک نوار رنگارنگ دارید به حافظه بسیار زیادی نیاز دارد. در یک حافظه آردوینو شما می توانید حداکثر 500پیکسل را استفاده کنید.
نمایشگرهای مونوکروم OLED
اینها برای هر 8 پیکسل نیازمند 1بایت هستند ولی به دلیل رزولوشن زیاد باعث بالا رفتن بایت مصرفی می شوند.
حل مشکلات مربوط به حافظه
حافظه جزو منابع محدود در یک میکروکنترلر است و در بعضی مواقع یک کاربرد ساده ممکن است تمام یک حافظه آردوینو را بگیرد. خوشبختانه اکثر برنامه ها را می توان بهینه سازی کرد. بنابراین اگر برنامه شما مقداری زیاد شد می توان با کمی نرمش و تمرین حجمش رو کم کرد.
نحوه بهینه سازی یک برنامه
هنگامی که برنامه را اجرا می کنید در پایین محیط برنامه نویسی آردوینو پیغامی مبنی بر حجم برنامه را مشاهده می کنید در صورتی که به محدوده مجاز رسیده باشید با استفاده از روشهایی می توانید حجم برنامه را بهینه کنید.
گام 1 : حذف کدهای بی استفاده
چنانچه کدهای شما از چندین منبع آمده است احتمالا مواردی اضافی و غیر قابل کاربرد در آن وجود دارد که می توانید آن را حذف کنید:
- کتابخانه های بی استفاده : همه توابع کتابخانه ای که لازم نیستند را حذف کنید. include#
- توابع بی استفاده: همه توابعی که از آنها استفاده نمی کنید.
- متغیرهای بی استفاده: همه متغیرهایی که بلااستفاده است را حذف کنید.
- عبارات شرطی بی استفاده: آن عبارات شرطی که هرگز به جواب true نمی رسند را حذف کنید.
نکته: برای اینکه بدونید یک تابع کتابخانه ای یا یک متغیر یا یک تابع در برنامه تان استفاده می شود یا نه با // آن را تبدیل به کامنت کنید و برنامه را اجرا کنید چنانچه باز برنامه اجرا شد یعنی اینکه اضافی است.
نوشتن تابع برای کدهای تکراری
چنانچه عباراتی وجود دارد که چندین بار در برنامه تکرار می شود بهتر است برای آن یک تابع بنویسید تا از نوشتن چندباره آن جلوگیری شود.
استفاده از حافظه Bootloader
چنانچه نیاز مبرم به حافظه اضافی داشتید می توانید حافظه مربوط به بوت لودر را حذف کنید که حدود 2تا4 کیلوبایت به دست می آورید. برای اینکار باید از یک ISP programmer برای برنامه ریزی استفاده کنید نه کابل USB آردوینو.
نکته کلیدی: سعی کنید در برنامه خود تاجایی که می توانید متغیرها را محلی تعریف کنید نه global. بخاطر اینکه اگر محلی تعریف کنید بعد از اینکه متغیر استفاده شده خودبخود حذف میشود و فضای حافظه خالی می شود در صورتی که متغیر گلوبال یا عمومی همیشه یک فضای اختصاصی را اشغال می کند.
برای دریافت آخرین مطالب سایت و همچنین مطالب منحصر به فرد دیگر که در سایت منتشر نمی شوند میتوانید در کانال تلگرام ما عضو شوید و یا در اینستاگرام ما را فالوو کنید:
17 دیدگاه
به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.
سلام خسته نباشید هنگام آپلود کد روی اردینو اونو همچین اخطاری میده میشه بگین علتش چیه و باید چیکار کرد؟Arduino: 1.8.5 (Windows 7), Board: “Arduino/Genuino Uno”
Sketch uses 3076 bytes (9%) of program storage space. Maximum is 32256 bytes.
Global variables use 125 bytes (6%) of dynamic memory, leaving 1923 bytes for local variables. Maximum is 2048 bytes.
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x30
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x0f
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x10
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x20
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x0f
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x10
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x30
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x0f
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x10
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x20
An error occurred while uploading the sketch
This report would have more information with
“Show verbose output during compilation”
option enabled in File -> Preferences.
با سلام.
لطفا به چند سوال زیر پاسخ دهید تا پاسخ کامل به شما داده شود :
۱- نوع برد خود را مشخص کنید.
۲- تصویری از Device manager سیستم خود ارسال بفرمایید.(در حالتی که برد به سیستم وصل شده است.)
۳- پروگرمر خود را روی چه چیزی تنظیم کرده اید ؟
۴- نوع بردخود را چه چیزی انتخاب کرده اید؟
۵- پورت COM شما با پورتی که در Device manager نشان داده می شود یکی است یا خیر.
موفق باشید.
با سلام.
من از wemos d1 mini برای خواندن و ارسال دما و رطوبت استفاده میکنم.که هر 5 ثانیه یه بار داده هارو به سرور mqtt ارسال میکنه.برنامه به خوبی کار میکنه ولی بعد از یکی دو روز (بعضی وقتا چند ساعت دیگه) انگار برد هنگ کرده.نه داده ای میفرسته و نه حتی میشه آی پی شو پینگ کرد.با ریست دستی برد دوباره اجرا میشه و لی باز بعد چند ساعت این مشکل براش پیش میاد.به نظرتون امکان داره از پر شدن حافظه باشه یا چیز دیگه ای میتونه باشه.این برنامه رو روی برد دیگه ای با اون مدل امتحان کردم و لی اون هم این مشکل رو داره.
با سلام و احترام.
آیا شما داده های خود را ذخیره میکنید که باعث پر شدن می شود ؟
آیا نکات و استانداردهای مربوط به نویزگیری را رعایت کرده اید؟
لطفا به این دو سوال پاسخ دهید تا راهنمایی های لازم انجام شود.
با تشکر.
با سلام…میشه مثال عملی بزنید که حافظه heap باید استفاده شود؟
با سلام.
همانطور که در این جلسه نیز گفته شده است ، حافظه heap زیرمجموعه ای از حافظه SRAM است. در واقع از این حافظه معمولا به صورت جدا استفاده نمی شود و صرفا برای داده هایی لحظه ای استفاده می شود.
موفق باشید.
سلام با توجه به اینکه زبانc مدیریت حافظه نداره بهتر نیست از c++ استفاده بشه؟
با سلام. آردوینو از زبان های برنامه C و C++ استفاده نمی کند. البته منکر شباهت زیاد این زبان برنامه نویسی با زبان های برنامه نویسی C و C++ نمی شویم ولی زبان آردوینو با آنها تفاوت دارد. به همین خاطر اصلا نمیتوانیم از C++ استفاده کنیم که بخواهیم از مزایای آن استفاده کنیم.
موفق باشید.