آردوینو آموزش آردوینو

شناخت حافظه Dynamic و Stack و نحوه ذخیره سازی متغیرها در آردوینو

نوشته شده توسط معین صابری

حافظه یکی از عناصر مهم و کلیدی در بردهای آردویینو به شمار می روند. کلیه متغیرهای تعریف شده توسط برنامه نویس، در حافظه ذخیره می شوند. همچنین، پس از انجام اعمال حسابی و یا منطقی، نتیجه در حافظه ذخیره خواهد شد. فضای حافظه، به طور خاص حافظه RAM، در بردهای آردویینو به دو دسته کلی پشته(Stack) و حافظه پویا(Dynamic memory) تقسیم می گردند. در این آموزش به بررسی تقسیم بندی حافظه رم در بردهای آردویینو مبتنی بر تراشه AVR می پردازیم. پیش از آن، ابتدا به معرفی حافظه های مختلف در این بردها پرداخته و در نهایت با معرفی حافظه پویا و پشته، نحوه ذخیره سازی متغیردر هرکدام را تشریح خواهیم نمود. در ادامه با مرجع تخصصی آردوینو به زبان فارسی ، دیجی اسپارک همراه باشید.

 


انواع مختلف حافظه در آردوینو


بردهای آردویینو مبتنی بر تراشه های AVR، نظیر برد آردویینو، دارای سه حافظه FLASH، SRAM و EEPROM هستند. هر کدام از این حافظه ها وظیفه ذخیره سازی بخش خاصی از داده ها را بر عهده دارند. به طور کلی، متغیرهای تعریف شده توسط برنامه نویس در حافظه SRAM ذخیره می شوند. این در حالیست که کدهای برنامه در حافظه FLASH ذخیره می شوند. درنهایت حافظه EEPROM، بر خلاف حافظه SRAM، با قطع برق، داده های ذخیره شده در آن، پاک نخواهد شد.

Dynamic memory, Stack and how to store variables in Arduino

 

مطابق تصویر فوق، هر حافظه یک بخش از ذخیره سازی دیتا را بر عهده می گیرد. در حافظه FLASH، می توانید علاوه بر ذخیره کد برنامه، داده ها را ذخیره کنید. البته این ذخیره سازی فقط به صورت نوشتن در حافظه، یبکار آن هم حین آپلود است. البته هر تعداد که نیاز باشد، می توانید از این حافظه داده های ذخیره شده را بخوانید. به عنوان مثال، برای نمایش لوگو می بایست تصویر را به حالت هگز تبدیل کرده و سپس نمایش دهید. با استفاده از کلمه کلیدی PROGMEM، می توانید داده را در حافظه فلش ذخیره نمایید.

 


تعریف حافظه STACK


حافظه Stack یا پشته، یکی از بخش های بسیار مهم در SRAM به شمار می آید. مکانیزم عملکرد این حافظه بر مبنای LIFO اجرا می گردد. عبارت LIFO  مخفف Last In FirstOut بوده و بیانگر ارائه سرویس به آخرین داده است. برای درک بهتر این موضوع، ابتدا تصویر زیر را در نظر بگیرید.

Dynamic memory, Stack and how to store variables in Arduino

 

مطابق تصویر فوق، هر داده ای که زودتر وارد شود، در پایین ترین سطح حافظه قرار می گیرد. همچنین، داده هایی که دیرتر وارد حافظه می شوند، در بالاترین قسمت قرار می گیرند. برای ذخیره سازی و خواندن داده از این حافظه، دو عمل pop و push صورت می گیرد. عمل push، داده جدید را در بالاترین قسمت این حافظه(انتهای حافظه) قرار می دهد. در طرف مقابل، عمل pop بالاترین داده و یا به عبارت دیگر، آخرین داده قرار گرفته را خوانده و از حافظه آزاد می نماید. به عنوان مثال، مطابق شکل فوق، با یک عمل pop، آخرین داده که data5 است، از حافظه آزاد می شود. چنانچه push صورت گیرد، داده جدید در بالاترین قسمت این حافظه، یعنی بالای data4 قرار خواهد گرفت. بدیهی است که برای دستیابی به داده های پایین تر نظیر data1، کلیه داده ها پیش از data1 می بایست pop شوند.

 


نقش STACK در مدیریت حافظه SRAM


در این قسمت به بررسی نحوه مدیریت حافظه SRAM به کمک Stack می پردازیم. در بردهای آردویینو مبتنی بر میکروکنترلرهای AVR، کلیه متغیرهایی که به صورت محلی تعریف می شوند، در حافظه Stack ذخیره می گردند. پس از اجرای تابع و خروج از آن، کلیه داده های محلی، از حافظه پشته پاک خواهند شد. این امر باعث می شود که مدیریت حافظه به صورت خودکار صورت گرفته و برنامه نویس نگرانی از بابت پرشدن حافظه، نداشته باشد.

Dynamic memory, Stack and how to store variables in Arduino

 

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

 


تعریف حافظه رجیستر در پردازنده‌ها


همانطور که اطلاع دارید، یک سیستم کامپیوتری از اجزای مختلفی تشکیل می شود. یکی از همه ترین این اجزا، حافظه ها هستند. حافظه ها خود نیز به انواع مختلف RAM، DISK، FLASH،CACH و REGISTER تقسیم می گردند. رجیسترها، کوچکترین حافظه ممکن از لحاظ اندازه هستند. این حافظه ها که سرعت بسیار بالایی دارند، درون پردازنده قرار گرفته و اعمال حسابی، منطقی و کنترل روال های برنامه، توسط آن ها صورت می گیرد.

Dynamic memory, Stack and how to store variables in Arduino

 

یکی از رجیسترهای بسیار مهم، رجیستر شمارنده برنامه است. این رجیستر که به صورت Program Counter یا به طور اختصار PC شناخته می شود، وظیفه ذخیره آدرس فعلی برنامه را بر عهده دارد. از دیگر رجیستر های مهم می توان به رجیسترهای وقفه، رجیسترهای اولویت وقفه، و… اشاره نمود.

 


حافظه SRAM، رجیستر PC و نحوه اجرای توابع


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

 


حافظه پویا در SRAM


در قسمت های پیشین، در رابطه با نحوه ذخیره سازی متغیرهای محلی در حافظه Stack صحبت کردیم. در طزف مقابل حاظف پشته، حافظه پویا و یا Dynamic Memory وجود دارد. این حافظه می تواند حین اجرای برنامه، از حافظه درخواست شده و سپس به آن برگردانده شود. بنابراین، یکی از مهم ترین چالش ها، مدیریت آن توسط برنامه نویس است.

void setup() {
}

void loop() {
 float *q = new float(75.25);  //تخصیص حافظه پویا 
  delete q;   //آزاد کردن حافظه
}

مطابق قطعه کد فوق، به کمک کلمه کلیدی new، حافظه ای را به صورت پویا به متغیر q اختصاص می دهیم. دلیل استفاده از کلمه “پویا” اینست که این نوع حافظه، می تواند در برنامه به صورت پویا دریافت و حذف شود. نکته مهم دیگر اینکه متغیرهای عمومی و یا GLOBAL، به صورت پویا تخصیص داده می شوند. از این رو در این زمینه، دقت نظر لازم را می باست به عمل آورد.

 


قطعات مورد نیاز


انواع برد آردویینو

 


جمع بندی


در این آموزش به بررسی مبحث مهم حافظه، دسته بندی و نحوه مدیریت آن در بردهای آردویینو پرداختیم. بردهای آردویینو مبتنی بر میکروکنترلر های AVR، دارای سه حافظه فلش جهت ذخیره کد برنامه، EEPROM جهت ذخیره سازی متغیرهایی که با قطع برق پاک نمی شوند و حافظه SRAM جهت ذخیره متغیرهای تعریف شده توسط برنامه نویس است. از طرف دیگر، حافظه SRAM، دارای دو حوزه کاری مختلف است. در این آموزش، ضمن بررسی این دو حوزه، نحوه ذخیره سازی متغیرها و اجرای برنامه در حافظه را مورد بررسی قرار دادیم.

 

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

 

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

معین صابری

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

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

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

۲ دیدگاه

  • سلام مهندس خدا قوت بده . در آردینو از چه توابعی جهت پاک کردن متغیرهای بلااستفاده و یا رفرش کردن حافظه داینامیک میتوان استفاده کرد ؟

    • سلام
      پاک کردن متغیرهای بلا استفاده به صورت خودکار توسط کامپایلر صورت می گیرد. برای پاک کردن حافظه داینامیک، همانطور که با کلمه کلیدی new متغرها تعریف می شوند، با کلمه delete هم پاک خواهند شد. البته در رابطه با متغرهای داینامیک!