Arduino F(): что это на самом деле

Я уже задавал аналогичный вопрос, но я понимаю, что я не могу сделать головы или хвосты макрологии и шаблонов. Я программист C (а не С++).

Что делает F()? Когда он набирает персонажей в pgmem? Когда он вытаскивает персонажей из pgmem? Он кэширует их? Как он справляется с ситуациями с низкой памятью?

Ответ 1

Нет шаблонов, только перегрузка функций. Макрос F() выполняет две функции:

  • использует PSTR, чтобы гарантировать, что литеральная строка хранится во флэш-памяти (пространство кода, а не пространство данных). Однако PSTR("some string") нельзя распечатать, поскольку он получит простой char *, который представляет базовый адрес строки, хранящейся во Flash. Разъязывание этого указателя будет иметь доступ к некоторым случайным символам с одного и того же адреса в данных. Вот почему F() также...

  • выводит результат PSTR() на __FlashStringHelper*. Такие функции, как print и println, перегружены, так что при приеме аргумента __FlashStringHelper* они правильно разыгрывают символы во флэш-памяти.

Ответ 2

КСТАТИ. Для библиотеки ESP32 обе эти функции определены в следующих файлах:

# PSTR :  ../Arduino/hardware/espressif/esp32/cores/esp32/pgmspace.h
# F    :  ../Arduino/hardware/espressif/esp32/cores/esp32/WString.h

и F (x):

// an abstract class used as a means to proide a unique pointer type
// but really has no body
class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
...

Также для ESP32 PSTR(x) не требуется и представляет собой просто x: #define PSTR(s) (s).