Могу ли я записать на флэш-память, используя PROGMEM?

11

На документации Arduino я цитирую:

http://playground.arduino.cc/Learning/Memory Примечание. Флэш-память (PROGMEM) может быть заполнена только во время записи программы. Вы не можете изменить> значения во флэш-памяти после запуска программы.

А по описанию ПРОГМЕМ:

http://arduino.cc/en/Reference/PROGMEM Храните данные во флэш-памяти (программах) вместо SRAM. Там есть описание различных типов памяти, доступных на плате Arduino.

Ключевое слово PROGMEM является модификатором переменной, его следует использовать только с типами данных, определенными в pgmspace.h. Он говорит компилятору «поместить эту информацию во флэш-память», а не в SRAM, куда она обычно отправляется.

Так мы можем или не можем? Или это не одно и то же?

zzarbi
источник
Хотя вы можете записывать (флэш) память программы во время выполнения (если она не заблокирована), этот процесс немного сложнее и не может быть выполнен с помощью директивы PROGMEM, которая в основном просто контролирует процесс выделения. Если вы хотите увидеть, как это можно сделать, посмотрите на исходный код загрузчика.
Крис Страттон
Блоки записи страницы не делают запись во флэш-память непрактичной. На самом деле это что-то с нетерпением жду.
Anothercg Gmail

Ответы:

9

Краткий ответ - нет: данные PROGMEM доступны только для чтения.

Ограничения флэш-памяти
Первое, что нужно понять, это то, что флэш-память (где находится пространство программы) предназначена для длительного фиксированного хранения. Чтение с него очень быстрое и точное. Однако, вообще говоря, вы не можете изменять его побайтово (например, изменять конкретную переменную). Вы обычно должны стереть и переписать это большими блоками. Это делает его совершенно непрактичным для манипуляций во время выполнения, потому что вам придется хранить много избыточной информации в другом месте, пока вы выполняете цикл стирания и записи.

Что на самом деле делает PROGMEM
Любые литеральные данные, указанные в вашем коде (например, строки и числа), всегда сначала находятся в программном пространстве (то есть во Flash). Однако, когда ваш эскиз на самом деле хочет использовать эти данные во время выполнения, он обычно должен выделить для него некоторое пространство в SRAM и скопировать его. Это означает, что вы получите две копии: фиксированный оригинал во Flash и временную копию в SRAM.

Когда вы используете модификатор PROGMEM, вы говорите ему не делать эту вторую копию в SRAM. Вместо этого ваш эскиз просто получит доступ к оригиналу во Flash. Это очень полезно, если вам когда-либо нужно только прочитать данные, поскольку это позволяет избежать операций выделения и копирования.

Однако копирование его в SRAM необходимо, если вы хотите изменить данные. Помимо ограничений Flash, о которых я упоминал выше, это также вопрос безопасности кода.

Если вы можете изменять данные, хранящиеся в программном пространстве, то логически следует, что вы также можете изменить код, хранящийся в программном пространстве. Это будет означать, что простая ошибка (или теоретически злонамеренная атака) может привести к тому, что ваш эскиз будет частично или полностью переписан во время выполнения. Это может привести к очень непредсказуемым результатам, от простого прекращения работы до повреждения / разрушения любого подключенного оборудования.

Больше информации
Вы можете узнать больше о низкоуровневых материалах PROGMEM здесь:

Старая версия того же учебника PROGMEM доступна здесь:

Питер Блумфилд
источник