Когда использовать PROGMEM?
Я считаю, что PROGMEM используется для хранения больших данных (например, строк), которые не меняются. Поэтому он освобождает SRAM.
в справочнике Ardunio упоминается, что.
«Использование PROGMEM также является двухэтапной процедурой. После помещения данных во флэш-память требуются специальные методы (функции), также определенные в библиотеке pgmspace.h, для считывания данных из памяти программ обратно в SRAM, чтобы мы могли сделать с ними что-то полезное».
Если мне нужно загрузить данные в SRAM перед их использованием, то насколько это эффективнее, чем прямая запись в SRAM путем определения переменной обычным способом?
3 ответа
Лучший ответ:
Скажем, у вас есть строка из 1000 символов во Flash, и вы хотите напечатать ее в Serial. Да, вам нужно загрузить ее в ОЗУ, чтобы передать эти данные по месту для печати. Но нужно ли вам помещать все их в ОЗУ сразу? Нет. Вам нужен только один символ за раз. Поэтому вместо того, чтобы брать 1000 символов, выделять 1000 байт ОЗУ и копировать все это в ОЗУ, а затем печатать, вам просто нужно выделить 1 байт ОЗУ* и копировать каждый символ по очереди и печатать его.
Поскольку из Flash-файла можно считывать только один символ за раз, нет никакого смысла считывать все сразу.
*На самом деле, из-за оптимизаций компилятора, это, вероятно, даже не касается оперативной памяти и просто остается в регистре ЦП.
Если в вашем коде есть константная c-строка (массив символов) без макроса F или программной памяти, то строка копируется в оперативную память при запуске и остается там.
Если в функции вы используете макрос F или создаете буфер символов определенного размера и копируете строку progmem в буфер, при возврате функции переменные удаляются из стека и память освобождается.
В случае большого массива, если вы поместите его в progmem, а затем в коде, когда вам понадобится найти значение в этом массиве, вам нужно будет копировать в оперативную память только один элемент массива за раз, а не весь массив.
Как сказал Маженко, вам не нужно помещать все, что у вас есть во флэш-памяти, в ОЗУ сразу. Вы можете перемещать элементы в SRAM по мере необходимости и повторно использовать память, когда закончите.
Однако вы не ограничены перемещением одного байта за раз. Существуют функции, определенные в avr/pgmspace.h
, которые могут обрабатывать перемещение данных для вас.
Например, вы можете сделать что-то вроде:
const struct mystruct_s my_value PROGMEM = { value = 1234 };
// ...
struct mystruct_s working_copy;
memcpy_P(&working_copy, &my_value, sizeof(struct mystruct_s));
int foo = working_copy.value / 2;
- Получить доступ к EEPROM ATtiny с помощью кода Arduino?
- Выделение строковой памяти Arduino
- Как очистить кучу памяти в esp32
- Есть ли способ подключить оперативную память компьютера к Arduino?
- Последовательная печать из флэш-памяти (F() macro, PROGMEM, sprintf_P, SPTR)
- Альтернатива SoftwareSerial с низким объемом памяти?
- Функция freeMemory() из библиотеки memoryfree не возвращает уменьшенное значение в arduino UNO
- Как функция/метод может определить, является ли передаваемый массив const PROGMEM (flash) или нет (RAM)?