Как объявить глобальную переменную в PSRAM?

Ардуинщики всех стран - объединяйтесь! В этом форуме, конечно.
Ответить
WorkPage
Открыл глаза
Сообщения: 65
Зарегистрирован: Чт сен 03, 2009 16:42:39

Как объявить глобальную переменную в PSRAM?

Сообщение WorkPage »

Перед использованием PSRAM надо выполнить psramInit()
Тогда каким образом объявить глобальные переменные? В void setup() они же не будут глобальными…
В примерах кода нашёл только это:

Код: Выделить всё

void setup() {
Serial.begin(115200);
//PSRAM Initialisation
if(psramInit()){
        Serial.println("\nThe PSRAM is correctly initialized");
}else{
        Serial.println("\nPSRAM does not work");
}

//Create an integer
int *var_int = (int *) ps_malloc(sizeof(int));
*var_int = 42;
}
Аватара пользователя
maxlab
Мучитель микросхем
Сообщения: 478
Зарегистрирован: Вт апр 23, 2013 22:21:18
Откуда: KUBAN, Krasnodar

Re: Как объявить глобальную переменную в PSRAM?

Сообщение maxlab »

Привет! Its depend - как говорят наши западные коллеги.
Так как линкер не знает что существует PSRAM на этапе компиляции/сборки, фокус с размещением глобальных переменных там, в понимании Ардуинщика, не пройдет.
Еще трудность в том что PSRAM обычно не является продолжением ОЗУ в контроллере, и выделение памяти в этой области имеет особенности.
Это зависит от карты памяти конкретного микроконтроллера. Есть конечно ухищрения связанные с модификацией ld файла и ассемблерного стартапа, но это не для
слабонервных. Где то на гитхабах встречал продвинутые методики работы с PSRAM, поищите.
Девице - Device
Ult1mat3X
Родился
Сообщения: 6
Зарегистрирован: Вт мар 24, 2026 09:45:52

Re: Как объявить глобальную переменную в PSRAM?

Сообщение Ult1mat3X »

Чтобы переменная была доступна во всем скетче (была глобальной), но память под нее выделялась в PSRAM после инициализации, используйте указатели.
Вот как это реализуется на практике:
1. Объявление (вне функций)
В начале скетча вы объявляете только «адрес» (указатель), изначально равный NULL. На этом этапе память еще не выделяется.
cpp
int *myGlobalInt = NULL; // Указатель на будущее целое число
float *myDataArray = NULL; // Указатель на будущий массив
Используйте код с осторожностью.

2. Инициализация (в setup)
После того как psramInit() прошел успешно, вы выделяете физическое место в PSRAM и присваиваете этот адрес вашему глобальному указателю.
cpp
void setup() {
Serial.begin(115200);

if (psramInit()) {
// Выделяем память под 1000 чисел типа float в PSRAM
myDataArray = (float *) ps_malloc(1000 * sizeof(float));

if (myDataArray != NULL) {
myDataArray[0] = 25.5; // Теперь это доступно везде
}
}
}


3. Использование (в loop или других функциях)
Теперь вы можете обращаться к этим данным из любой части программы, так как сам указатель определен глобально.
cpp
void loop() {
if (myDataArray != NULL) {
Serial.println(myDataArray[0]);
}
delay(1000);
}


Важный нюанс: Ключевое слово EXT_RAM_ATTR
Если ваша среда разработки (IDE) и плата поддерживают атрибуты, можно объявить глобальную переменную в PSRAM статически (без ps_malloc). В этом случае система сама выделит память при старте:
cpp
EXT_RAM_ATTR int myStaticGlobalArray[10000];

void setup() {
psramInit();
// Массив уже готов к работе, malloc не нужен
}
Rapra
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 16, 2026 17:30:02

Re: Как объявить глобальную переменную в PSRAM?

Сообщение Rapra »

Даже намного проще: int* ptr = (int*)0хAABBCCDD, где 0xAABBCCDD - конкретный адрес в области PSRAM.
Однако, здесь надо учитывать систему адресации микроконтроллера. Если адресация линейная и PSRAM может быть подключена к линейному адресному пространству с назначением ей диапазона адресов, то показанный вариант имеет место быть. В противном случае, при косвенной (относительной) адресации такой вариант не проканает.

Эта тема была создана в разделе Ардуино. И скорее всего, здесь имеется ввиду микросхема PSRAM на SPI-интерфейсе с относительной адресацией. При таком раскладе для работы с внешней PSRAM используется кэширование блока некоторого размера. И разумеется, никакого вообще выделения памяти, хоть через malloc, хоть через указатель, хоть статически, в PSRAM здесь быть не может.
Аватара пользователя
JackSmith
Потрогал лапой паяльник
Сообщения: 332
Зарегистрирован: Ср мар 09, 2016 08:07:41

Re: Как объявить глобальную переменную в PSRAM?

Сообщение JackSmith »

[uquote="Rapra",url="/forum/viewtopic.php?p=4800736#p4800736"]int* ptr = (int*)0хAABBCCDD, где 0xAABBCCDD - конкретный адрес в области PSRAM.[/uquote]
таким способом объявлять глобальную переменную нельзя, потому что компилятор ничего не будет знать про такую переменную, и может затереть ее своими данными. такая переменная не может быть инициализирована значением по умолчанию, которое сохраняется в .data-секции. правильно это делается через создание дополнительной секции в скрипте компоновщика.
Rapra
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 16, 2026 17:30:02

Re: Как объявить глобальную переменную в PSRAM?

Сообщение Rapra »

Так адрес задается вручную, вне диапазона адресов описанных секций. И указатель - это отдельная переменная, которая указывает на некоторый адрес.
И если уж работаете с секциями, тогда не нужны никакие указатели. Просто объявите переменную или массив с атрибутом указанной секции:
int var __attribute__((section(".MySection")));
int array[100] __attribute__((section(".MySection")));

И во-вторых, и это самое главное - нужно было прочитать не только первую строчку моего предыдущего поста.
Если микроконтроллер не имеет выделенного диапазона адресов для внешней PSRAM, то работа с переменными хоть через указатели, хоть через секции, будет невозможна. Внешняя PSRAM будет работать в режиме кэша с отображением кэшированного блока во внутренней SRAM микроконтроллера.
Ответить

Вернуться в «Arduino»