Чего мне не хватает при использовании PROGMEM?

Поэтому я пытаюсь сохранить многомерный массив CHAR в памяти программ на моем Arduino, и у меня возникают проблемы с его работой. Вот что у меня есть …

typedef unsigned char RGBBitmap[8][8][3];
typedef prog_uchar ProgRGBBitmap[8][8][3]; // Have to use prog_uchar for stuff stored in progmem

ProgRGBBitmap Mailbox[3] PROGMEM =
{
... // some initializing data
};

Согласно документации PROGMEM, чтобы получить указатель на данные char, вы должны использовать вызов pgm_read_word. Тем не менее, когда я пытаюсь прочитать его обратно, используя это …

RGBBitmap * pMailbox0 = (RGBBitmap*)pgm_read_word( &Mailbox[0] );

…все, что я вернусь, это мусор.

Если я отбрасываю строку PROGMEM и работаю только с указателями RGBBitmap и удаляю pgm_read_word, он работает, но затем в оперативной памяти, которой у меня нет.

Так чего мне здесь не хватает?

0

Решение

Ваши массивы являются блоком значений. Вот так ваш код определяет непрерывный блок значений:

ProgRGBBitmap Mailbox[3] PROGMEM = {...};
... removing typedef is same as ...
prog_uchar Mailbox[3][8][8][3] = {...};

Таким образом, вы не можете прочитать указатель из памяти программ, потому что они не хранятся там. Блок весь учар.

Все ваши значения являются байтами, поэтому вы можете прочитать любое значение из этого блока с помощью:

uc = (uchar)pgm_read_byte( someaddress );

Теперь сложная часть 4-мерного массива — получить правильный синтаксис адреса.

uc = (uchar)pgm_read_byte( &Mailbox[i][x][y][c] );

Компилятор вставит арифметику указателя для [i] … [c], что может быть бесполезным в цикле. Таким образом, вы можете предварительно рассчитать часть указателя, что я думаю, что вы пытаетесь достичь. Примерно так можно сохранить код и такты:

ProgRGBBitmap* ptrOneBox = &(Mailbox[i]);  // this will be pointer into block
for(x ...
for(y ....
uc = (uchar)pgm_read_byte( &(ptrOneBox[x][y][c]) ); // this indexes out one byte

Указатель и массивы могут свести вас с ума, когда это не работает. Добавьте PROGMEM на платформе без отладчика …

Разрежьте проблему до более простого случая и вернитесь к ней.

0

Другие решения


По вопросам рекламы [email protected]