Формирование строки

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

andycat пишет:

ua6em пишет:

а нет какого метода прикрутить внешнюю память?

научиться писать софт при ограниченных ресурсах железа

не всем жеж дано, мелкомягкие вон не заморачиваются с ресурсами

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:

не всем жеж дано, мелкомягкие вон не заморачиваются с ресурсами

Так они и на ардуине не работают

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

ua6em пишет:

не всем жеж дано, мелкомягкие вон не заморачиваются с ресурсами

Так они и на ардуине не работают

а windows 10 core IoT ?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Что, на ардуине работает? Не знал, буду знать. Завтра на унку установлю.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

anarch пишет:

Т.е. если я не знаю какой длины у меня строка, я должен выделить кусок памяти с запасом, поработать с ним и очистить, а если не хватило попросить еще. На верном пути?

В общем случае - нет.

Я как-то пытался оценить максимальную длину строки в тексте на естественном языке, у меня получилось около 90000 символов. В юникоде это будет под 200к, тогда как у Ардуинки на все про все - 2к.

В общем, если Вы не знаете длину строки, не следует даже пытаться разместить ее в памяти Ардуинки (разве что у Вас Due). Обрабатывайте ее, не храня целиком в памяти.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

baby_in_Arduino пишет:

вопрос опытным ардуинщикам какой максимальный размер буфера на стеке? вообще каков размер стека? какая область памяти "за стеком"? что мы потрем в случае если превысим максимальный размер буфера?

Именно этот объем пишет Вам компилятор: 

Скетч использует 21144 байт (32%) памяти устройства. Всего доступно 65536 байт.
Глобальные переменные используют 4200 байт (20%) динамической памяти, оставляя 16280 байт для локальных переменных. Максимум: 20480 байт.

вот здесь 16280 - это суммарный объем кучи и стека. Сколько Вы выделяете в куче - легко контролировать, значит, все оставшееся - стек.

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Это решение для недалеких прогеров. Таким образом можно собирать веб страницу.

void setup() {
  int a = 8;
  Serial.begin(9600);
  Serial.print(
    (String)F("qwe:")
    + (String)a
    + (String)F("   qwe:")
    + (String)((char)33)
    + (String)F("\n")
  );
}
void loop() {
}

ПС: Да и скорее всего надо написать библиотеку для графического String (может назвать ее Gring) для сборки изображения и отправки на графические дисплеи.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

qwone пишет:

ПС: Да и скорее всего надо написать библиотеку для графического String (может назвать ее Gring) для сборки изображения и отправки на графические дисплеи.

Крутяк!!!

baby_in_Arduino
Offline
Зарегистрирован: 21.07.2019

andriano пишет:

baby_in_Arduino пишет:

вопрос опытным ардуинщикам какой максимальный размер буфера на стеке? вообще каков размер стека? какая область памяти "за стеком"? что мы потрем в случае если превысим максимальный размер буфера?

Именно этот объем пишет Вам компилятор: 

Скетч использует 21144 байт (32%) памяти устройства. Всего доступно 65536 байт.
Глобальные переменные используют 4200 байт (20%) динамической памяти, оставляя 16280 байт для локальных переменных. Максимум: 20480 байт.

вот здесь 16280 - это суммарный объем кучи и стека. Сколько Вы выделяете в куче - легко контролировать, значит, все оставшееся - стек.

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

тоесть размер стека не регламентирован? используем буфер локальный на 1кб значит в куче остается только 1кб, используем буфер локальный на полтора килобайта значит в куче остается 500 байт вот и все радости? а если мы сначала в куче выделили полтора килобайта и что то туда записали а потом зашли в функцию которая тоже создала буфер на стеке на полтора килобайта и что то записала в него значит она потерла данные в куче записанные ранее?  следить за тем чтоб эти области памяти не перекрывались должны мы сами? нету тут тебе как в винде __alloca_probe которую компилятор вставляет в начало каждой функции которая создает буферы нас стеке и таким образом следит чтобы не выйти за область пакмяти выделяемой под стек, микроконтроллер просто начнет глючить по тихому и гикнется

кстати откуда у вас 20480 байт динамической памяти? у ардуино уно всего 2кб же вроде?

 

anarch
Offline
Зарегистрирован: 10.09.2017

baby_in_Arduino пишет:

кстати откуда у вас 20480 байт динамической памяти? у ардуино уно всего 2кб же вроде?

STM32 Blue Pill 

negavoid
Offline
Зарегистрирован: 09.07.2016

baby_in_Arduino пишет:

тоесть размер стека не регламентирован? используем буфер локальный на 1кб значит в куче остается только 1кб, используем буфер локальный на полтора килобайта значит в куче остается 500 байт вот и все радости? а если мы сначала в куче выделили полтора килобайта и что то туда записали а потом зашли в функцию которая тоже создала буфер на стеке на полтора килобайта и что то записала в него значит она потерла данные в куче записанные ранее?  следить за тем чтоб эти области памяти не перекрывались должны мы сами? нету тут тебе как в винде __alloca_probe которую компилятор вставляет в начало каждой функции которая создает буферы нас стеке и таким образом следит чтобы не выйти за область пакмяти выделяемой под стек, микроконтроллер просто начнет глючить по тихому и гикнется

Всё правильно :) _alloca_probe нет, так как нет винды, нет супервизора, нет защищённого режима, нет stack guard и reserved pages, есть только суровый "реальный" режим с прямым доступом к оперативке, да ещё и Гарвардская архитектура, память команд отдельная.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

baby_in_Arduino пишет:

тоесть размер стека не регламентирован? используем буфер локальный на 1кб значит в куче остается только 1кб, используем буфер локальный на полтора килобайта значит в куче остается 500 байт вот и все радости? а если мы сначала в куче выделили полтора килобайта и что то туда записали а потом зашли в функцию которая тоже создала буфер на стеке на полтора килобайта и что то записала в него значит она потерла данные в куче записанные ранее?  следить за тем чтоб эти области памяти не перекрывались должны мы сами? нету тут тебе как в винде __alloca_probe которую компилятор вставляет в начало каждой функции которая создает буферы нас стеке и таким образом следит чтобы не выйти за область пакмяти выделяемой под стек, микроконтроллер просто начнет глючить по тихому и гикнется

Ну, в суровую ты сказку попал, чо. 

Logik
Онлайн
Зарегистрирован: 05.08.2014

qwone пишет:

Это решение для недалеких прогеров. Таким образом можно собирать веб страницу.

void setup() {
  int a = 8;
  Serial.begin(9600);
  Serial.print(
    (String)F("qwe:")
    + (String)a
    + (String)F("   qwe:")
    + (String)((char)33)
    + (String)F("\n")
  );
}
void loop() {
}

 

А ежели в строках 4-9 не сцеплять все в одну колбасу, а в каждой строке свой Serial.print вызывать то решение становится сразу для далеких прогеров, жаждущих отправлять данные произвольной длины и структуры при пошти нулевом расходе ОЗУ. А для особо далеких прогеров этот подход и принимать такие данные позволяет ;)

SLKH
Offline
Зарегистрирован: 17.08.2015

andriano пишет:

Я как-то пытался оценить максимальную длину строки в тексте на естественном языке, у меня получилось около 90000 символов.

Кодекс об адм. нарушениях, статья 4.5 ? 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Logik пишет:
А ежели в строках 4-9 не сцеплять все в одну колбасу

Вот в этом и плохо. Кроме "колбасного завода" String ничего нет 

void setup() {
  int a = 8;
  Serial.begin(9600);
  {
    String buffer;
    buffer.reserve(30);//выделить 30 байт памяти
    buffer = (String)F("qwe:")
             + (String)a
             + (String)F("   qwe:")
             + (String)((char)'$')
             + (String)F("\n");
    Serial.print(buffer);
  }// вытряхнуть из памяти buffer;
  // плохо что метод invalidate() закрыт
}
void loop() {
}

ПС: А библиотека Adafruit_GFX не построена на принципах "колбасного завода"

Logik
Онлайн
Зарегистрирован: 05.08.2014

шайтанамана

Serial.print("qwe:")
Serial.print(a)
Serial.print("   qwe:")
...

там препинания, ltoa и пр. дребедень сами порасставляйте, мне некогда сейчас, налито уже.  Просто ненадо собирать все в один бухер, слона отправляем по частям.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

SLKH пишет:

 Кодекс об адм. нарушениях, статья 4.5 ? 

Там же меньше 8 кбайт!