Запись строки в постоянную флэш-память Arduino ESP32

Я хочу записать текст во флэш-память Arduino ESP32. Это вроде как работает, но не так, как я хочу.

void writeString(const char* toStore, int startAddr) {
  int i = 0;
  for (; i < LENGTH(toStore); i++) {
    EEPROM.write(startAddr + i, toStore[i]);
  }
  EEPROM.write(startAddr + i, '\0');
  EEPROM.commit();
}

Мой вызов

writeString("TEST_STRING_TO_WRITE", 0);

только записывает ТЕСТ в память. Я не понимаю почему. Это из-за _? Или мне чего-то не хватает?

Вот используемый макрос LENGTH

#define LENGTH(x) (sizeof(x)/sizeof(x[0]))

и метод, который я использую для повторного чтения строки из памяти (который, кажется, работает правильно):

String readStringFromFlash(int startAddr) {
  char in[128];
  char curIn;
  int i = 0;
  curIn = EEPROM.read(startAddr);
  for (; i < 128; i++) {
    curIn = EEPROM.read(startAddr + i);
    in[i] = curIn;
  }
  return String(in);
}

person DrEichenbach    schedule 14.05.2019    source источник


Ответы (2)


Откуда вы взяли этот макрос LENGTH? Это нереально.

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

Вы хотите использовать strlen (), предполагая, что ваш char * является правильно завершенной строкой C. Добавьте один, чтобы убедиться, что "\ 0" в конце тоже сохраняется.

#define LENGTH(x) (strlen(x) + 1)
person romkey    schedule 15.05.2019
comment
это из визуальной студии. Большое спасибо, теперь он работает. Но я думал, что sizeof (x) дает размер массива в байтах. И это должно быть разделено на размер типа данных в массиве, чтобы получить количество элементов. - person DrEichenbach; 15.05.2019
comment
Если бы у вас было char string[23];, тогда sizeof(string); вернул бы 23, даже если вы сохранили только 5-символьную строку в массиве символов. Если вы затем передали string в качестве аргумента функции и использовали sizeof внутри функции, вы (скорее всего, это будет зависеть от ЦП) получите 4, потому что функция будет знать только о char *. sizeof возвращает количество байтов, необходимых для хранения любого аргумента. - person romkey; 15.05.2019
comment
Это действительно плохо с String - если вы сделали sizeof(String("verylongstring")), вы получите количество байтов, необходимое для хранения объекта String, а не количество байтов, выделенных для хранения его данных. Это все время кусает людей. - person romkey; 15.05.2019

Ниже приведен код, демонстрирующий сохранение, а также получение строки ssid в EEPROM (постоянное хранилище).

#include "EEPROM.h"

int addr = 0;
#define EEPROM_SIZE 64

// the sample text which we are storing in EEPROM
char ssid[64] = "CARNIVAL OF RUST";

void setup() {
    Serial.begin(115200);
    Serial.println("starting now...");

    if (!EEPROM.begin(EEPROM_SIZE)) {
        Serial.println("failed to init EEPROM");
        delay(1000000);
    }

    // writing byte-by-byte to EEPROM
    for (int i = 0; i < EEPROM_SIZE; i++) {
        EEPROM.write(addr, ssid[i]);
        addr += 1;
    }
    EEPROM.commit();

    // reading byte-by-byte from EEPROM
    for (int i = 0; i < EEPROM_SIZE; i++) {
        byte readValue = EEPROM.read(i);

        if (readValue == 0) {
            break;
        }

        char readValueChar = char(readValue);
        Serial.print(readValueChar);
    }
}

void loop() {

}
person Rounak Datta    schedule 19.11.2019