Можно ли определить размер стека по свободной куче?

у меня есть NodeMCU с es8266 на борту. Я читал, что память кучи и стека обращена друг к другу, и если куча или стек заполняются и достигают других, происходят странные вещи. Поэтому мне интересно, можем ли мы использовать ESP.getFreeHeap() для получения свободной кучи и завершения использования стека.

один небольшой вопрос: может ли Serial.println("asd asd") вызывать фрагментацию памяти?

, 👍2


1 ответ


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

3

Я читал, что память кучи и стека обращена друг к другу, и если куча или стек заполняются и достигают другого, происходят странные вещи.

Это действительно так. И такие вещи бывает сложно отследить.

Поэтому мне интересно, можем ли мы использовать ESP.getFreeHeap(), чтобы получить свободную кучу и завершить использование стека.

Нет, нельзя. «Свободный» объем кучи не равен верхнему адресу кучи. В куче могут быть (и обычно есть) дыры. «Свободное» пространство — это сумма всех этих дыр плюс любое дополнительное «зарезервированное куче» пространство над самой высокой записью кучи.

Чтобы получить текущее использование стека, вам нужно знать две вещи:

  1. Начальный адрес стека и
  2. Текущий экстент стека

Элемент 1 будет фиксированным значением, хотя я понятия не имею, что это за значение, но некоторое чтение наверняка даст вам это значение.

Элемент 2 можно получить, выделив локальную переменную в функции и получив адрес этой переменной.

Если все, что вам нужно, это изменение стека, вызванное вашим кодом, вы можете записать «начальную» точку стека и использовать ее в точке 1. Например:

char *stack_start;

void setup() {
    char stack;
    stack_start = &stack;
}

Затем вы можете использовать это, чтобы сравнить текущий размер стека с началом вашей программы:

uint32_t stack_size() {
    char stack;
    return (uint32_t)stack_start - (uint32_t)&stack;
}

один крошечный вопрос: может ли Serial.println("asd asd") вызывать фрагментацию памяти?

Нет. Использование String и других динамических распределений вызывает фрагментацию памяти.

,

но разве "asd asd" не строка? и этот код стека кажется действительно полезным, спасибо., @alphaceph

Это "строковый литерал", а не "String". «Строка» — это конкретный экземпляр класса «Строка» (специфического для Arduino)., @Majenko