Записать во флэш-память с помощью PROGMEM

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

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

А в описании ПРОГРАММЫ:

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

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

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

, 👍13

Обсуждение

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

Блоки записи страниц не делают запись на флэш-память непрактичной. На самом деле ее-то ждали., @Anothercg Gmail


1 ответ


Лучший ответ:

9

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

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

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

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

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

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

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

  • http://www.fourwalledcubicle.com/AVRArticles.php

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

  • http://www.avrfreaks.net/index.php?name =PNphpBB2&file=viewtopic&p=243018
,

https://mon.im/2014/11/modifying-avr-progmem-at-runtime.html, @flyandi