Невозможно создать переменную RTC_DATA_ATTR внутри класса

Я пытаюсь создать класс deepSleep для своего проекта ESP32, но получаю эту ошибку: атрибут раздела не разрешен для 'clock_beforeSleep' Единственное место, где он компилируется, находится вне класса.

Как мне это объявить?

EDIT1: добавить код

#include "EEPROM.h"
#include "time.h"
#include "WiFi.h"

RTC_DATA_ATTR long clock_expectedWake = 0;
RTC_DATA_ATTR int bootCounter = 0;
RTC_DATA_ATTR int driftRTC = 0;
RTC_DATA_ATTR long clock_beforeSleep = 0;

class esp32Sleep
{
#define EEPROM_SIZE 16
#define DEV_NAME "ESP32lite"
#define uS_TO_S_FACTOR 1000000ULL /* Conversion micro seconds to seconds */

private:
  char sleepstr[250];
  // RTC_DATA_ATTR long clock_expectedWake = 0;
.
.
.

, 👍0

Обсуждение

член класса - это только объявление. он имеет место в памяти только в том случае, если создается объект этого класса. вы можете попробовать ключевое слово static. статические члены являются общими для всех экземпляров этого класса, @Juraj

@Juraj, но это TRV_DATA_ATTR, который сохраняет свое значение и извлекает его после пробуждения., @Guy . D

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

@Juraj - см. редактирование 1. не могли бы вы объяснить о «компоновщике», @Guy . D

компоновщик следует сценарию компоновщика, который указывает, что и где находится в памяти https://github.com/espressif/arduino-esp32/blob/1977370e6fc069e93ffd8818798fbfda27ae7d99/tools/sdk/ld/esp32.project.ld#L48, @Juraj


2 ответа


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

3

Вы не можете поместить квалифицированную переменную RTC_DATA_ATTR внутрь класса, поскольку класс хранится в обычной оперативной памяти. Полная переменная RTC_DATA_ATTR по определению хранится в ОЗУ RTC.

Определение RTC_DATA_ATTR включает атрибут section (__attribute__((section(".rtc.data")))), который сообщает компилятор, где в памяти должна храниться переменная (в данном случае 8 КБ «медленной» памяти RTC). Это не зависит от того, где компилятор решает сохранить класс.

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

,

1

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

  • Глобальные переменные, а также статические локальные переменные и статические члены класса выделяются компоновщиком во время сборки, обычно в .data или раздел .bss программы.
  • Локальные переменные выделяются в стеке во время выполнения. Обычно компилятор выдает некоторые инструкции для корректировки указателя стека по порядку. чтобы освободить место для переменной. В качестве оптимизации чаще всего используется локальные переменные могут храниться непосредственно в регистрах процессора, но такая оптимизация отключается, если вы используете адрес переменной.
  • Переменные, созданные с помощью new и malloc(), выделяются во время выполнения. в куче. Это распределение обрабатывается библиотекой поддержки.

Обратите внимание, что объекты являются переменными и размещаются в одной части, просто как C struct. Статические члены класса не являются частью класса экземпляры.

Теперь в некоторых цепочках сборки есть расширения, позволяющие хранить статически размещенные переменные в другом месте, кроме ОЗУ. Один пример хранилище PROGMEM на AVR. RTC_DATA_ATTR звучит похоже расширение. Вы можете сохранить обычный член класса таким образом, если:

  1. Объект является глобальным и сохраняется как RTC_DATA_ATTR целиком.
  2. Ему не нужен конструктор.
,

Есть ли обходной путь для создания такого класса?, @Guy . D