PROGMEM 키워드 사용법
PROGMEM
PROGMEM 키워드는 데이터를 SRAM 대신 Flash(Program) 메모리에 생성하는 키워드입니다. PROGMEM 은 변수 앞에 사용할 수 있는 키워드로 pgmspace.h 파일에 선언된 데이터 타입에만 적용할 수 있습니다. 이 키워드를 사용한다는 것은 컴파일러에게 “이 변수를 일반적으로 사용하는 SRAM 대신 Flash 메모리에 저장하라”고 지시하는 것과 유사합니다.
PROGMEM 키워드는 pgmspace.h 라이브러리의 일부이기 때문에 사용하기 전에, 스케치 최 상단에 아래와 같은 선언문을 넣어줘야 합니다. (최신 아두이노 IDE 에서는 이 과정이 없어도 사용할 수 있습니다. 오히려 사용할 경우 일부 라이브러리와 충돌을 일으킬 수도 있는듯 합니다.)
#include <avr/pgmspace.h>
PROGMEM 사용방법
PROGMEM 키워드를 사용하는 일반적인 방법은 아래와 같습니다.
dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3…};
변수를 선언할 때 PROGMEM 키워드를 넣는 위치는 유연하게 조정할 수 있습니다. 다만 아두이노 IDE 버전에 따라 컴파일러인 GCC 버전이 틀리고, GCC 버전에 따라 특정 위치가 아니면 에러를 발생할 수도 있습니다. 이 때는 적절히 위치를 조정해줘야 합니다.
dataType variableName[] PROGMEM = {}; // use this form
dataType PROGMEM variableName[] = {}; // not this one
PROGMEM dataType variableName[] = {}; // use this form
배열이 아닌 형태의 변수에도 PROGMEM 키워드를 사용할 수 있습니다.
PROGMEM 키워드로 변수를 선언할 때와 마찬가지로 PROGMEM 으로 선언된 변수를 사용할 때도 특별한 방법을 이용해야 합니다. 변수를 사용하기 위한 별도의 함수가 pgmspace.h 에 선언되어 있으므로 이 파일을 참고하세요. 아래 예제에서 자세한 사용방법을 확인하실 수 있습니다.
PROGMEM 키워드를 적용할 수 있는 데이터 타입은 아래와 같습니다. (실수형 변수는 사용 불가)
prog_char – a signed char (1 byte) -127 to 128
prog_uchar – an unsigned char (1 byte) 0 to 255
prog_int16_t – a signed int (2 bytes) -32,767 to 32,768
prog_uint16_t – an unsigned int (2 bytes) 0 to 65,535
prog_int32_t – a signed long (4 bytes) -2,147,483,648 to * 2,147,483,647.
prog_uint32_t – an unsigned long (4 bytes) 0 to 4,294,967,295
예제
아래 코드는 char 배열(문자열)과 int 배열(정수 배열)을 PROGMEM 키워드로 선언해서 사용하는 방법입니다.
#include <avr/pgmspace.h> // save some unsigned ints PROGMEM prog_uint16_t charSet[] = { 65000, 32796, 16843, 10, 11234}; // save some chars prog_uchar signMessage[] PROGMEM = {"I AM PREDATOR, UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPART"}; unsigned int displayInt; int k; // counter variable char myChar; // read back a 2-byte int displayInt = pgm_read_word_near(charSet + k) // read back a char myChar = pgm_read_byte_near(signMessage + k);
C 에서 문자열은 char 형 배열입니다. 이런 문자열의 묶음, 즉 문자열 배열을 생성할 경우도 PROGMEM을 응용해서 사용할 수 있습니다. 아래 코드를 참고하세요.
/* PROGMEM string demo How to store a table of strings in program memory (flash), and retrieve them. Information summarized from: http://www.nongnu.org/avr-libc/user-manual/pgmspace.html Setting up a table (array) of strings in program memory is slightly complicated, but here is a good template to follow. Setting up the strings is a two-step process. First define the strings. */ #include <avr/pgmspace.h> prog_char string_0[] PROGMEM = "String 0"; // "String 0" etc are strings to store - change to suit. prog_char string_1[] PROGMEM = "String 1"; prog_char string_2[] PROGMEM = "String 2"; prog_char string_3[] PROGMEM = "String 3"; prog_char string_4[] PROGMEM = "String 4"; prog_char string_5[] PROGMEM = "String 5"; // Then set up a table to refer to your strings. PROGMEM const char *string_table[] = // change "string_table" name to suit { string_0, string_1, string_2, string_3, string_4, string_5 }; char buffer[30]; // make sure this is large enough for the largest string it must hold void setup() { Serial.begin(9600); } void loop() { /* Using the string table in program memory requires the use of special functions to retrieve the data. The strcpy_P function copies a string from program space to a string in RAM ("buffer"). Make sure your receiving string in RAM is large enough to hold whatever you are retrieving from program space. */ for (int i = 0; i < 6; i++) { strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy. Serial.println( buffer ); delay( 500 ); } }