PROGMEM: эквивалент pgm_read_float_near() для double? (Ардуино Дуэ)
Я использую Arduino Due, где размер double составляет 8 байт. В своем программном обеспечении я использую константу двойной таблицы, хранящуюся в памяти программ. Раньше я использовал UNO и использовал pgm_read_float_near() для получения этих значений. Какую функцию мне следует использовать?
@snoob dogg, 👍3
2 ответа
Лучший ответ:
Arduino Due (ARM Cortex-M3) не требуется ничего вроде PROGMEM
, поскольку он имеет доступ к флэш-памяти так же, как и к RAM
. Квалификатора const
достаточно, чтобы хранить его только в памяти программы.
Платам на базе AVR
, таким как UNO
, требуется PROGMEM, поскольку существуют разные инструкции для извлечения данных из программной памяти, а g++
не очень продвинут в этом. таким образом (некоторые другие компиляторы поддерживают это напрямую - например, в gcc вместо этого можно использовать __flash и __eeprom, но не в g++, поскольку по некоторым причинам это было отклонено)
Изменить:
В настоящее время также существуют AVR с новым дизайном (они больше похожи на xmegas) и имеют плоское адресное пространство (эмуляция), поэтому с помощью одного указателя вы можете получить данные из RAM, FLASH, EEPROM и так далее. Но это ограничено устройствами с меньшим размером FLASH (все они должны умещаться в указатели 64 КБ/16 байт). В этих случаях вы можете просто использовать const для глобальных массивов, и они будут храниться во FLASH (а не во FLASH и загружаться в ОЗУ при запуске, как старые AVR), а строковые литералы не нуждаются в макросах P_STR/F()
Например:
- Atmega4809 (nano Every, Uno Wi-Fi R2) и варианты: 808, 809, 1608, 1609, 3208, 3209, 4808.
- Attiny(2/4/8/16/32)(0/1/2)(2,4,6,7) – например, Attiny212 1616...
- Это также должно быть возможно на устройствах AVR16/AVR32, но для устройств с 64 КБ/128 КБ снова требуется PROGMEM (компилятор не может оптимизировать его во FLASH, поскольку у вас есть только снимок размером 32 КБ в прямом адресном пространстве, но его можно изменить - однако есть также ошибка, связанная с тем, что он не работает должным образом)
Для тех, кто ищет эквивалент, вы можете вручную скопировать байты в двойной формат, например:
double pgm_read_double(const double* address) {
double result;
memcpy_P(&result, address, sizeof(double));
return result;
}
И используйте memcpy_PF
для дальних
адресов. Но знайте, что многие микроконтроллеры имеют доступ к флэш-памяти так же, как и к оперативной памяти, поэтому вам не нужно использовать это вообще.
- Записать во флэш-память с помощью PROGMEM
- Преимущества глобальных переменных перед статическими членами класса?
- Ошибка компиляции ESP8266: "previous declaration of 'HTTPMethod HTTP_HEAD'"
- Вспомогательный объект Flash String в качестве переменной
- Arduino IDE: как получить длину PROGMEM const?
- Использование программной памяти в ESP8266 по сравнению с AVR, а также как обрабатывать большие динамические строки
- Проблема с памятью Arduino со старыми чипами дисплея HP HDSP-2000
- Как использовать PROGMEM в файле .h/.cpp вместо файла .ino?
"инструкции"??, @James Waldby - jwpat7
Да, Джмайс, инструкции. Это то, чем вы ударяете микроконтроллеры, чтобы заставить их работать., @Majenko