متغیر هایی از نوع PROGMEM در کامپایلر GCC

شروع موضوع توسط Alma ‏27/1/19 در انجمن AVR

  1. Alma

    Alma مدیر عضو کادر مدیریت

    شاید برای شما هم پیش اومده باشه که وقتی از متغیر ها یاجدول های بزرگی مثل فونت ها استفاده میکنید در صورتی که این متغیر حتی اگر به صورت const هم تعریف شده باشه رم رو مشغول میکنه و در واقع اگر شما نیاز به یک بایت اون داشته باشید کل متغیر در حافظه رم قرار خواهد گرفت

    برای رفع این مشکل باید متغیر رو از نوع فلش PROGMEM تعریف کرد و مقدار اون رو در صورت نیاز از ادرسی که در اختیار قرار میگیره خوند در این صورت همه متغیر ی رشته در رم قرار نمیگیره بلکه فقط مقداری از اون که نیاز هست و خونده شده

    برای این منظور بایدابتدا فایل pgmspace.h رو وارد برنامه کنیم

    کد:
    #include "pgmspace.h"

    حالا یه رشته از نوع PROGMEM تعریف میکنیم برای مثال اینجا قراره یه فونت 8x8 تعریف کنیم

    کد:
    const  char f8x8b[] PROGMEM = {
        0x08,0x08,0x00,0x80,0x00,0x00,0x00,0x00 ,
        0x7E,0x81,0x95,0xB1,0xB1,0x95,0x81,0x7E ,
        0x7E,0xFF,0xEB,0xCF,0xCF,0xEB,0xFF,0x7E ,
        0x0E,0x1F,0x3F,0x7E,0x3F,0x1F,0x0E,0x00 ,
        0x08,0x1C,0x3E,0x7F,0x3E,0x1C,0x08,0x00 ,
        0x38,0x38,0x9F,0xFF,0x9F,0x38,0x38,0x00 ,
        0x10,0x38,0xBC,0xFF,0xBC,0x38,0x10,0x00 ,
        0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00 ,
        0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF ,
        0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00 ,
        0xFF,0xC3,0x99,0xBD,0xBD,0x99,0xC3,0xFF ,
        0x70,0x88,0x88,0x88,0x89,0x7D,0x03,0x0F ,
        0x00,0x4E,0x51,0xF1,0xF1,0x51,0x4E,0x00 ,
        0xC0,0xE0,0x7F,0x05,0x05,0x05,0x05,0x07 ,
        0xC0,0xE0,0x7F,0x05,0x05,0x65,0x75,0x3F ,
        0x5A,0x5A,0x3C,0xE7,0xE7,0x3C,0x5A,0x5A ,
        0x7F,0x3E,0x3E,0x1C,0x1C,0x08,0x08,0x00 ,
        0x08,0x08,0x1C,0x1C,0x3E,0x3E,0x7F,0x00 ,
        0x00,0x24,0x66,0xFF,0xFF,0x66,0x24,0x00 ,
        0x00,0x00,0x5F,0x00,0x00,0x5F,0x00,0x00 ,
        0x06,0x09,0x09,0x7F,0x01,0x01,0x7F,0x01 ,
        0x40,0xDA,0xA7,0xA5,0xE5,0x59,0x03,0x02 ,
        0x00,0x70,0x70,0x70,0x70,0x70,0x70,0x00 ,
        0x80,0x94,0xB6,0xFF,0xFF,0xB6,0x94,0x80 ,
        0x00,0x0C,0x06,0x7F,0x06,0x0C,0x00,0x00 ,
        0x00,0x18,0x30,0x7F,0x30,0x18,0x00,0x00 ,
        0x08,0x08,0x08,0x2A,0x3E,0x1C,0x08,0x00 ,
        0x08,0x1C,0x3E,0x2A,0x08,0x08,0x08,0x00 ,
        0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x00 ,
        0x08,0x1C,0x3E,0x08,0x08,0x3E,0x1C,0x08 ,
        0x30,0x38,0x3C,0x3E,0x3C,0x38,0x30,0x00 ,
        0x06,0x0E,0x1E,0x3E,0x1E,0x0E,0x06,0x00 ,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,
        0x00,0x00,0x00,0x5F,0x00,0x00,0x00,0x00 ,
        0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00 ,
        0x00,0x14,0x7F,0x14,0x14,0x7F,0x14,0x00 ,
        0x00,0x24,0x2A,0x6B,0x6B,0x2A,0x12,0x00 ,
        0x00,0x46,0x26,0x10,0x08,0x64,0x62,0x00 ,
        0x30,0x4A,0x45,0x4D,0x32,0x48,0x48,0x00 ,
        0x00,0x00,0x04,0x03,0x00,0x00,0x00,0x00 ,
        0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00 ,
        0x00,0x00,0x41,0x22,0x1C,0x00,0x00,0x00 ,
        0x08,0x2A,0x1C,0x1C,0x1C,0x2A,0x08,0x00 ,
        0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00 ,
        0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00 ,
        0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00 ,
        0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00 ,
        0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x00 ,
        0x00,0x3E,0x61,0x51,0x49,0x45,0x3E,0x00 ,
        0x00,0x44,0x42,0x7F,0x40,0x40,0x00,0x00 ,
        0x00,0x62,0x51,0x51,0x49,0x49,0x66,0x00 ,
        0x00,0x22,0x41,0x49,0x49,0x49,0x36,0x00 ,
        0x10,0x18,0x14,0x52,0x7F,0x50,0x10,0x00 ,
        0x00,0x27,0x45,0x45,0x45,0x45,0x39,0x00 ,
        0x00,0x3C,0x4A,0x49,0x49,0x49,0x30,0x00 ,
        0x00,0x03,0x01,0x71,0x09,0x05,0x03,0x00 ,
        0x00,0x36,0x49,0x49,0x49,0x49,0x36,0x00 ,
        0x00,0x06,0x49,0x49,0x49,0x29,0x1E,0x00 ,
        0x00,0x00,0x00,0x66,0x00,0x00,0x00,0x00 ,
        0x00,0x00,0x80,0x66,0x00,0x00,0x00,0x00 ,
        0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00 ,
        0x00,0x24,0x24,0x24,0x24,0x24,0x24,0x00 ,
        0x00,0x00,0x00,0x41,0x22,0x14,0x08,0x00 ,
        0x00,0x02,0x01,0x01,0x51,0x09,0x06,0x00 ,
        0x00,0x3E,0x41,0x5D,0x55,0x55,0x1E,0x00 ,
        0x00,0x7C,0x12,0x11,0x11,0x12,0x7C,0x00 ,
        0x00,0x41,0x7F,0x49,0x49,0x49,0x36,0x00 ,
        0x00,0x1C,0x22,0x41,0x41,0x41,0x22,0x00 ,
        0x00,0x41,0x7F,0x41,0x41,0x22,0x1C,0x00 ,
        0x00,0x41,0x7F,0x49,0x5D,0x41,0x63,0x00 ,
        0x00,0x41,0x7F,0x49,0x1D,0x01,0x03,0x00 ,
        0x00,0x1C,0x22,0x41,0x51,0x51,0x72,0x00 ,
        0x00,0x7F,0x08,0x08,0x08,0x08,0x7F,0x00 ,
        0x00,0x00,0x41,0x7F,0x41,0x00,0x00,0x00 ,
        0x00,0x30,0x40,0x40,0x41,0x3F,0x01,0x00 ,
        0x00,0x41,0x7F,0x08,0x14,0x22,0x41,0x40 ,
        0x00,0x41,0x7F,0x41,0x40,0x40,0x60,0x00 ,
        0x00,0x7F,0x01,0x02,0x04,0x02,0x01,0x7F ,
        0x00,0x7F,0x01,0x02,0x04,0x08,0x7F,0x00 ,
        0x00,0x3E,0x41,0x41,0x41,0x41,0x3E,0x00 ,
        0x00,0x41,0x7F,0x49,0x09,0x09,0x06,0x00 ,
        0x00,0x1E,0x21,0x21,0x31,0x21,0x5E,0x40 ,
        0x00,0x41,0x7F,0x49,0x19,0x29,0x46,0x00 ,
        0x00,0x26,0x49,0x49,0x49,0x49,0x32,0x00 ,
        0x00,0x03,0x01,0x41,0x7F,0x41,0x01,0x03 ,
        0x00,0x3F,0x40,0x40,0x40,0x40,0x3F,0x00 ,
        0x00,0x0F,0x10,0x20,0x40,0x20,0x10,0x0F ,
        0x00,0x3F,0x40,0x40,0x38,0x40,0x40,0x3F ,
        0x00,0x41,0x22,0x14,0x08,0x14,0x22,0x41 ,
        0x00,0x01,0x02,0x44,0x78,0x44,0x02,0x01 ,
        0x00,0x43,0x61,0x51,0x49,0x45,0x43,0x61 ,
        0x00,0x7F,0x41,0x41,0x41,0x00,0x00,0x00 ,
        0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x00 ,
        0x00,0x41,0x41,0x41,0x7F,0x00,0x00,0x00 ,
        0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x00 ,
        0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 ,
        0x00,0x00,0x00,0x03,0x04,0x00,0x00,0x00 ,
        0x00,0x20,0x54,0x54,0x54,0x54,0x78,0x40 ,
        0x00,0x01,0x7F,0x30,0x48,0x48,0x48,0x30 ,
        0x00,0x38,0x44,0x44,0x44,0x44,0x28,0x00 ,
        0x00,0x30,0x48,0x48,0x48,0x31,0x7F,0x40 ,
        0x00,0x38,0x54,0x54,0x54,0x54,0x18,0x00 ,
        0x00,0x00,0x48,0x7E,0x49,0x01,0x02,0x00 ,
        0x00,0x98,0xA4,0xA4,0xA4,0xA4,0x78,0x04 ,
        0x00,0x41,0x7F,0x08,0x04,0x04,0x78,0x00 ,
        0x00,0x00,0x44,0x7D,0x40,0x00,0x00,0x00 ,
        0x00,0x60,0x80,0x80,0x80,0x84,0x7D,0x00 ,
        0x00,0x01,0x7F,0x10,0x28,0x44,0x40,0x00 ,
        0x00,0x00,0x41,0x7F,0x40,0x00,0x00,0x00 ,
        0x00,0x7C,0x04,0x04,0x78,0x04,0x04,0x78 ,
        0x00,0x7C,0x08,0x04,0x04,0x04,0x78,0x00 ,
        0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00 ,
        0x00,0x84,0xFC,0x98,0x24,0x24,0x18,0x00 ,
        0x00,0x18,0x24,0x24,0x98,0xFC,0x84,0x00 ,
        0x00,0x44,0x7C,0x48,0x04,0x04,0x18,0x00 ,
        0x00,0x48,0x54,0x54,0x54,0x54,0x24,0x00 ,
        0x00,0x04,0x04,0x3F,0x44,0x44,0x20,0x00 ,
        0x00,0x3C,0x40,0x40,0x40,0x20,0x7C,0x00 ,
        0x00,0x0C,0x10,0x20,0x40,0x20,0x10,0x0C ,
        0x00,0x3C,0x40,0x40,0x38,0x40,0x40,0x3C ,
        0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00 ,
        0x00,0x9C,0xA0,0xA0,0xA0,0xA0,0x7C,0x00 ,
        0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00 ,
        0x00,0x08,0x08,0x36,0x41,0x41,0x00,0x00 ,
        0x00,0x00,0x00,0x77,0x00,0x00,0x00,0x00 ,
        0x00,0x00,0x41,0x41,0x36,0x08,0x08,0x00 ,
        0x00,0x02,0x01,0x01,0x02,0x02,0x01,0x00
    };


    همونطوری که مشاهده میکنید رشته ما از نوع PROGMEM تعریف شده
    برای خوندن از این رشته هم باید از ماکرو pgm_read_byte استفاده کنیم یعنی نمیشه به صورت معمولی از این رشته استفاده کرد لذا به این صورت عمل میکنیم

    کد:
    for(uint8_t i=0; i<8; i++)str[i] = pgm_read_byte(&f8x8b[(' ' - 'A') * 8 + i]);

    upload_2019-1-27_14-56-50.png

    همونطوری که در تصویر فوق مشاهده میکنید در صورتی که متغیر از نوع PROGMEM نباشه 98.4 درصد از رم اشغال میشه اما وقتی از نوع PROGMEM باشه حتی یک بایت از رم هم اشغال نخواهد شد

    upload_2019-1-27_14-55-23.png

    توجه داشته باشید

    دلیل اینکه هیچ رمی اشغال نمیشه اینه که کامپایلر فقط از ادرس و اشاره گر استفاده میکنه
    در واقع وقتی متغیری از نوع PROGMEM تعریف میکنیم اشاره گری به ادرس خاصی از حافظه فلش که مقدار دهی شده تعریف کردیم
    EHSAN1082 و saeeddelshad0020 از این پست تشکر کرده اند.
  2. saeeddelshad0020

    saeeddelshad0020 همکار

    ممنون مهندس عالی بود....یعنی ما بخوایم اکثر متغیر هامون رو با این روش اشاره گر بنویسیم و به ادرسش اشاره کنیم حجم رم ما خیلی میاد پایین درسته؟
  3. Alma

    Alma مدیر عضو کادر مدیریت

    دوست عزیز وقتی شما هر متغیری رو صدا میکنید کل اون متغیر در رم قرار میگیره
    حالا اگر این متغیر یه رشته خیلی بزرگ مثل یه دیتای فونت یا موارد مشابه باشه کل متغیر در رم قرار خواهد گرفت که باعث اشغال رم میشه در صورتی که فقط به چند بایت اون نیاز هست
    saeeddelshad0020 از این پست تشکر کرده است.
  4. EHSAN1082

    EHSAN1082 همکار

    حرف نداره _ مهندس کی نژاد هم اشاره کرده بودن اما توضیحات شما فهم ما را بیشتر کرد
    saeeddelshad0020 و Alma از این پست تشکر کرده اند.

به اشتراک بگذارید