[Решено] STM32F103ZE 64 КБ память, истощенную массивом класса строк

Gasparobr
Ср 30 августа 2017 г. 22:09
Привет... Я новичок в этой группе.
Я с проблемой, чтобы справиться с 64 кбайтами моего STM32F103ZE с STM32DUINO.

Я сделал простой код, и он работает только до тех пор, пока он не использует 31 КБ, больше, чем система остановилась перед запуском. Может ли кто -нибудь помочь мне?

String ramtest[2160]; // <= WITH THIS THE SYSTEM WORK String ramtest[2170]; // <= WITH THIS THE SYSTEM HALT void setup() { // put your setup code here, to run once: Serial.begin(115200); } void loop() { // put your main code here, to run repeatedly: delay(3000); Serial.println(SERIAL_TX_BUFFER_SIZE); }

victor_pv
Четверг 31 августа 2017 г. 2:49
Не уверен, почему вам понадобится так много струн одновременно, но это не по теме.

Трудно сказать, почему ваш эскиз рушится, но помимо памяти, которую вы назначаете для переменных, есть также стек и куча в ОЗУ.
Они растут друг к другу, поэтому вы можете работать в ситуации, когда стек перезаписывает переменные в куче, или куча перезаписывает данные в стеке. Любой случай вызывает коррупцию памяти и, вероятно, сбой.
Я не могу сказать, сколько памяти вы используете в любом случае, но вы используете много «нового» или «malloc» для размещения места для переменных, которые будут поступать из кучи и может в конечном итоге сбиться со стеком.

С другой стороны, если у вас есть какой -то код, который многое гнездирует, вызывает много вызывает, прежде чем раскрыть все это, это будет значительно увеличить стек. Кроме того.

Rogerclark
Четверг 31 августа 2017 г., 7:41
Я сделал быстрый тест на Maple Mini, чтобы определить, где в оперативной памяти эти глобальные переменные будут выделены.
String ramtest; String ramtest2; void setup() { // put your setup code here, to run once: Serial.begin(115200); } void loop() { // put your main code here, to run repeatedly: Serial.print((int)&ramtest,HEX); Serial.print(" "); Serial.println((int)&ramtest2,HEX); delay(1000); }

Rogerclark
Чт 31 августа 2017 г., 7:43
Обновлять

Я провел тот же тест на STM32Generic и получаю

20000E0C 20000E24


Поэтому я думаю, что потенциально существует проблема с местоположением BSS на Libmaple

Пито
Чт 31 августа 2017 г., 7:46 утра
Я видел проблему с F103Z. С F103ZE я не могу выделить больший буфер, чем 16 КБ (т.е. 32 КБ не работал).

Rogerclark
Чт 31 августа 2017 г., 7:51 утра
[Пито - Четверг 31 августа 2017 г. 7:46] - Я видел проблему с F103Z. С F103ZE я не могу выделить больший буфер, чем 16 КБ (т.е. 32KB).
Я думаю, что кто -то, кто понимает файлы линкеров, должен посмотреть на файлы либмапле линкеров, так как, кажется, есть большая часть оперативной памяти, которую нельзя использовать.

Я думаю, это может быть для стека, но я подумал, что это обычно ставит на вершину ОЗУ и движется вниз

Пито
Четверг 31 августа 2017 г., 7:55 утра
Нам нужен простой тестовый эскиз, чтобы проверить/воспроизвести проблему.
Например: http: // www.STM32duino.com/viewtopic.PHP ... 787#P33787
Вы можете объединить стек против распределения буферов.

victor_pv
Четверг 31 августа 2017 г. 13:19
Отвечая на некоторые из вышеперечисленных вопросов.
BSS - это переменные, инициализированные до 0. Он входит в память после того, как переменные инициализированы с любым значением, поэтому они начинаются выше 0x2000000

Тест, который сделал Роджер, не то же самое, что и OP, поскольку OP использовал массив струн, поэтому Roger's не принимает столько памяти.

Я только что посмотрел на сценарий линкера для ZE и не вижу проблемы, начальный адрес выглядит правильно и устанавливается размером 64 КБ, а сценарий линкера, а код запуска, который инициализирует BSS до 0, выглядит правильно , используя 32 -битные указатели и никакие маски или что -то в этом роде, могут остановить инициализацию после 32 КБ. Возможно, Рик может найти то, что я пропустил.

victor_pv
Четверг 31 августа 2017 г. 13:40
[Пито - Четверг 31 августа 2017 г. 7:46] - Я видел проблему с F103Z. С F103ZE я не могу выделить больший буфер, чем 16 КБ (т.е. 32 КБ не работал).
Pito, эта проблема, возможно, была другой, в зависимости от того, как управляются буферы, могут быть маски, указатели и т. Д., меньше, чем UIN32, и поэтому ограничение размера буфера, которым можно управлять.
UINT16 разрешил бы 64 КБ, INT16 позволит 32 КБ, поскольку числа негатиков, вероятно, не имеют большого смысла для указателя в зависимости от того, как написан код, поэтому, если преобразования между int и uint, все больше, чем 32 КБ, может привести к не -Солепа математика, и если где -то есть дивизия, возможно, в 16 лет он исполняется 32 КБ. Не сказать, что это точно так, но не может сказать, что проблема такая же, как и OP.
Я думаю, что необходимо гораздо больше контекста в его коде. Его переменные глобальные или местные? Он использует Malloc или новый набросок для чего -то другого? Любое использование Malloc или New не будет учитываться как RAM, используемая во время компиляции, ни одна локальная переменная.
Он может копировать эти строки в местные где -то в своем коде, поэтому для каждого KB в размерах он увеличивает эти переменные, может быть еще несколько, используя в куче и стеке во время выполнения...

Только что сделал сборник эскиза в первом посте, и это соответствующий кусок в файле карты. .bss.ramtest 0x20000ddc 0x65b8 .\sloeber.ino.cpp.o 0x20000ddc ramtest .bss.pbreak.4444 0x20007394 0x4 C:/Users/Victor/workspace/ZE_RAM_ALLOC/Release/arduino.ar(syscalls.c.o) .bss.line_dtr_rts 0x20007398 0x1 C:/Users/Victor/workspace/ZE_RAM_ALLOC/Release/arduino.ar(usb_cdcacm.c.o) .bss.vcomBufferTx 0x20007399 0x100 C:/Users/Victor/workspace/ZE_RAM_ALLOC/Release/arduino.ar(usb_cdcacm.c.o) *fill* 0x20007499 0x3 .bss.tx_head 0x2000749c 0x4 C:/Users/Victor/workspace/ZE_RAM_ALLOC/Release/arduino.ar(usb_cdcacm.c.o) .bss.rx_hook 0x200074a0 0x4 C:/Users/Victor/workspace/ZE_RAM_ALLOC/Release/arduino.ar(usb_cdcacm.c.o) .bss.vcomBufferRx 0x200074a4 0x100 C:/Users/Victor/workspace/ZE_RAM_ALLOC/Release/arduino.ar(usb_cdcacm.c.o) .bss.transmitting

Gasparobr
Четверг 31 августа 2017 г. 14:16
Я сделал тест на оперативную память, и ответ был:

200010b4 200010c0


[Rogerclark - Четверг 31 августа 2017 г. 7:41] - Я сделал быстрый тест на Maple Mini, чтобы определить, где в оперативной памяти эти глобальные переменные будут выделены.
String ramtest; String ramtest2; void setup() { // put your setup code here, to run once: Serial.begin(115200); } void loop() { // put your main code here, to run repeatedly: Serial.print((int)&ramtest,HEX); Serial.print(" "); Serial.println((int)&ramtest2,HEX); delay(1000); }

Gasparobr
Четверг 31 августа 2017 г. 14:26
Спасибо, Виктор, за ваш ответ.

Мой основной код сбоя с использованием более 20 тыс. Поэтому я только что сделал этот простой тест, чтобы проверить, что происходит с моей оперативной памятью, без какого -либо стека. У моего процессора есть 64K, и мне действительно нужно использовать его для локальных переменных и серийных буферов. Есть какой -то способ, которым я могу использовать все это?
[victor_pv - Четверг 31 августа 2017 г. 2:49] - Не уверен, почему вам понадобится так много струн одновременно, но это не по теме.

Трудно сказать, почему ваш эскиз рушится, но помимо памяти, которую вы назначаете для переменных, есть также стек и куча в ОЗУ.
Они растут друг к другу, поэтому вы можете работать в ситуации, когда стек перезаписывает переменные в куче, или куча перезаписывает данные в стеке. Любой случай вызывает коррупцию памяти и, вероятно, сбой.
Я не могу сказать, сколько памяти вы используете в любом случае, но вы используете много «нового» или «malloc» для размещения места для переменных, которые будут поступать из кучи и может в конечном итоге сбиться со стеком.

С другой стороны, если у вас есть какой -то код, который многое гнездирует, вызывает много вызывает, прежде чем раскрыть все это, это будет значительно увеличить стек. Кроме того.

victor_pv
Чт 31 августа 2017 г. 14:39
Код в первом посте сбой? Если это так, мы можем использовать это в качестве теста.
У меня еще не было времени запустить. Если это не сбои, то в вашем коде может быть что -то еще.
В нормальных условиях вы должны иметь возможность использовать все 64 КБ, но в ядре может быть ошибка, в зависимости от того, как именно будет использоваться память.
Если у вас есть отладчик, stlink или любой другой, было бы здорово, если бы вы могли проверить, где именно сбой. Вот когда я планирую сделать, когда у меня есть время для проведения теста.

victor_pv
Пт, сентябрь 01, 2017 12:45
Я только что запустил его в MCU 103RT6, и проблема в классе строки.
Конструктор класса строк выделяет 16 байтов памяти на строку в куче, в отношении других 12 байтов, которые он выделяет в глобальном пространстве, в BSS.

Когда вызывается конструктор класса строк, с:
String ramtest [nnn]

Что он делает, он копирует строковый объект nnn times (он процитирует время через конструктор, выполняющий копии), и каждый из тех случаев он выделяет память из кучи.
В конце концов куча достигает стека, и она разрушает MCU.

Объект ramtest [] содержит только указатели, всего 12 байтов, и один из указателей на адрес ОЗУ в куче, где он выделяет буфер, я думаю, чтобы написать фактическую строку текста, для которого вы должны использовать это, и и и Я вижу, как каждый из этих строковых объектов содержит указатель 16 байтов впереди предыдущего, поэтому он выделяет 16 байтов кучи для каждого объекта строки, он инициализируется. Последний указатель, который он пишет в массиве Ramtest до того, как он сбой в моем случае, в 2000 году, и указатель стека находится на том же адресе, поэтому куча разбила стек.

Поэтому, если вы хотите использовать класс строк, вам нужно понять, что он выделяет гораздо больше, чем всего 12 байтов на строку, и это с пустыми струнами, я могу представить, если это не сбои, и вы хотели, чем дать строковый объект Содержание, которое, скажем, длиной 100 байтов, ему придется снова вызвать конструктор копии и выделить еще 100 байтов от кучи.
Я ничего не знаю о классе струн, кроме того, что я видел сейчас в Bdebugger, поэтому, если кто -то еще на форуме не может дать вам несколько советов, лучше всего выступить на форумах Arduino или на форуме Teensy, так как это Похоже, Пол Стоффеген переворачивается весь класс строки.

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

Хорошая ссылка о том, что происходит с вашим:
https: // учиться.Адафрут.com/воспоминания- ... Изинг-срам

Rogerclark
Пт, сентябрь 01, 2017 1:43
Виктор

Спасибо за информацию о классе строки.

Но я подозреваю, что может быть проблема с Libmaple

Глядя на адреса в ОЗУ, которые он назначил строкам в глобальном масштабе (а также такие вещи, как серийный и серийный 1 и т. Д.)

Адреса, которые его используют, составляют около 5 тыс. От базы ОЗУ, и из файла карты я не могу видеть очень много, используя пространство ниже области 5K

STM32Generic, по -видимому, распределяет глобальные VARS, намного ниже, чтобы начало оперативной памяти (в течение нескольких сотен байтов).
Но их организация памяти может быть совершенно другой.

К сожалению, я недостаточно знаю о директивах линкера, чтобы понять, почему .BSS, кажется, 5 тыс. от основания ОЗУ
Я предполагаю, что это зарезервирует это пространство для чего -то другого, но я не уверен, что.

victor_pv
Пт, сентябрь 01, 2017 3:58
В моем случае BSS начинается с DC0 (3520)

До этого все выглядит нормально, но есть большая часть, связанная с Libc inture_data. Я считаю, что на форуме была более длинная дискуссия на форуме, и это связано с использованием Malloc. Поскольку класс строки использует Malloc, он тянет все это в. Я не думаю, что есть проблема с Libmaple, но есть проблема со строкой наверняка. Также есть несколько интересных постов от Пола на форуме Arduino, объясняющих, как команда Arduino отказалась реализовать большинство своих исправлений для этого класса и выбрала только некоторые из них. Некоторые из этих потоков старые, и, возможно, было принесено больше изменений, но все же может быть удобно взглянуть на то, как находится класс строки для Teensy3, так как Пол, очевидно, посвятил много времени на исправления, команда Arduino не хотела Слияние, поэтому он применил эти исправления к подростковым ядрам.
*fill* 0x2000057c 0x4 .data.impure_data 0x20000580 0x428 c:/sloeber/arduinoplugin/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\libc.a(lib_a-impure.o) .data._impure_ptr 0x200009a8 0x4 c:/sloeber/arduinoplugin/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\libc.a(lib_a-impure.o) 0x200009a8 _impure_ptr .data.__malloc_av_ 0x200009ac 0x408 c:/sloeber/arduinoplugin/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\libc.a(lib_a-mallocr.o) 0x200009ac __malloc_av_ .data.__malloc_trim_threshold 0x20000db4 0x4 c:/sloeber/arduinoplugin/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\libc.a(lib_a-mallocr.o) 0x20000db4 __malloc_trim_threshold .data.__malloc_sbrk_base 0x20000db8 0x4 c:/sloeber/arduinoplugin/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\libc.a(lib_a-mallocr.o) 0x20000db8 __malloc_sbrk_base 0x20000dc0 . = ALIGN (0x8) *fill* 0x20000dbc 0x4 0x20000dc0 __data_end__ = .

Rogerclark
Пт, сентябрь 01, 2017 4:32
Виктор

Спасибо...

На кленовом мини - .BSS, кажется, DF0, который ровно 3K с самого начала ОЗУ, что заставляет меня думать, что есть настройка где -то, что управляет этим

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

На данный момент, я думаю, что у нас есть большая рыба, чем оптимизировать струны, чтобы лучше использовать память.

ИМХО Класса строкости следует избегать для встроенной разработки. Я вряд ли когда -либо использую его с STM32, однако я заметил, что ядро ​​ESP8266 широко использует струны (но у них, вероятно, больше оперативной памяти для игры)

Стивестронг
Пт, сентябрь 01, 2017, 9:31
Разве мы не можем просто посмотреть на струнный класс Teensy и взять на себя некоторые части (все?) этого?

Rogerclark
Пт, сентябрь 01, 2017 10:10
[Стивестронг - Пт, сентябрь 01, 2017 9:31] - Разве мы не можем просто посмотреть на струнный класс Teensy и взять на себя некоторые части (все?) этого?
У меня нет времени сделать это.

victor_pv
Пт, сентябрь 01, 2017 13:50
[Rogerclark - Пт - ИМХО Класса строкости следует избегать для встроенной разработки. Я вряд ли когда -либо использую его с STM32, однако я заметил, что ядро ​​ESP8266 широко использует струны (но у них, вероятно, больше оперативной памяти для игры)
+1

Я тоже не использую строку, я уже потратил достаточно времени, чтобы найти, есть ли ошибка в ядре, и нет. Если кто -то использует строку и имеет время для сравнения с Teensy и т. Д., То отправьте PR, мы можем вернуться.

Рик Кимбалл
Пт, сентябрь 01, 2017, 16:51
Иногда мне интересно, приходят ли люди сюда и публикуют вопросы, чтобы просто троллить нас?

Оригинальный плакат, похоже, не показывает нам код, который он действительно работает. Так что для нас попытаться выяснить, что он делает, это просто пустая трата времени. Я не могу себе представить, пытаясь использовать множество струн, как он кодировал. Я предполагаю, что он хотел выделить один экземпляр строки, который длится 2170 байтов.

Martinayotte
Пт
[Рик Кимбалл - Пт - Я не могу себе представить, пытаясь использовать множество струн, как он кодировал. Я предполагаю, что он хотел выделить один экземпляр строки, который длится 2170 байтов.
Верно ! Я думаю, ты положил на это пальцем !
На многих форумах я видел некоторых новичков, которые даже не могли различить разницу между распределением структуры и указателями на структуры, вызывая исключения из нулевого указателя.

ZMEMW16
Пт
домашнее задание ?
коммерческий ?
SRP

Martinayotte
Пт
[ZMEMW16 - Пт - домашнее задание ?
коммерческий ?
SRP
Что ты имеешь в виду ?

ZMEMW16
Пт
Студент где -то ищет готовое решение, хотя они, как правило, более доступны с деталями.
Мой обычный ответ - строка поиска Google :)
кто -то работает над чем -то коммерческим, и старается не отдавать слишком много - добиться успеха
или
кто -то дергает наши цепи
SRP

Martinayotte
Пт
Вот пример, который я нашел сегодня утром ... : ugeek:
https: // esp32.com/viewtopic.PHP?f = 2&T = 2870

victor_pv
Пт, сентябрь 01, 2017 8:19
[Martinayotte - Пт - Вот пример, который я нашел сегодня утром ... : ugeek:
https: // esp32.com/viewtopic.PHP?f = 2&T = 2870
И мы думали, что некоторые вопросы здесь не имели смысла...

Gasparobr
Пт
[Рик Кимбалл - Пт - Иногда мне интересно, приходят ли люди сюда и публикуют вопросы, чтобы просто троллить нас?

Оригинальный плакат, похоже, не показывает нам код, который он действительно работает. Так что для нас попытаться выяснить, что он делает, это просто пустая трата времени. Я не могу себе представить, пытаясь использовать множество струн, как он кодировал. Я предполагаю, что он хотел выделить один экземпляр строки, который длится 2170 байтов.
Привет, Рик. Я не хочу тебя троллить. Мой основной код не хватает памяти без причины. Поэтому я просто пытаюсь заполнить все память, чтобы увидеть, что случилось. Я не использую этот код, это пример Simplr, чтобы проверить полного пользователя памяти.

Рик Кимбалл
Пт
Почему бы вам не опубликовать этот код тогда?

Gasparobr
Пт, сентябрь 01, 2017 8:58
[Рик Кимбалл - Пт - Почему бы вам не опубликовать этот код тогда?
Мой код имеет 9K строки кода. Код замораживает без причины, если я добавлю какую -либо строку или использую последовательные.print (); или сериал.print (f ()), с алокацией всего 23 тыс. Я использую много серийного процессора в этом коде. Это причина, по которой я сделал этот пример кода, чтобы проверить ОЗУ.

Сейчас я сделал другой тест с другим образцом, и я могу просто использовать 23 тыс. ОЗУ со строкой, но если я использую другие массивы поплавки и двойной, я могу использовать полные 64K.

Рик, я не эксперт в области встроенного процессора, но я думаю, что STM32Duino в нашем случае фокусируется, потому что он помогает сильно создавать встроенный код без быть экспертом.

Спасибо за внимание!

Рик Кимбалл
Пт, сентябрь 01, 2017 21:11
Крайне маловероятно, что проблема в строке. Если у вас 9 тыс. Кода, это много строк кода, которые могут сделать функцию строки выглядеть как красная сельдь.

Вы используете массив струн или одну строку и пробуете итерацию, хотя каждый элемент в одной строке?

Что делает это 9 тысяч кода?

Можете ли вы решить свою проблему, не используя строку?

Вы понимаете, как работает строка? Каждый элемент строки выделяет 12 байтов, прежде чем вы даже что -нибудь положите в него.

Строка класса: {...
буфер *
int, содержащий его способность
int, содержащий его фактическую длину.

4 байта + 4bytes + 4bytes
}

Когда вы на самом деле вкладываете что -то в строковое значение, он выделяет больше памяти и устанавливает указатель буфера на этот адрес. Тем не менее, Malloc не просит точного количества символов, которые вы просите. (На самом деле он использует realloc ())

String MyString; // резервы 12 байтов в .BSS это недоступно для кучи или стека.

void somefunc () {
...
myString = 'a'; // выделяет 16 байтов из кучи
...
}

Строка кода выше фактически выделяет как минимум 16 байтов, потому что строка предполагает, что вы собираетесь вырастить строку
(В противном случае, почему бы вам также не использовать какой -то другой примитив хранилища данных), Malloc работает лучше, когда он может распределять и бесплатные элементы того же размера.

Так что мы на самом деле не знаем, как вы используете свои строковые объекты. Не видя вашего кода, мы можем только догадываться.

victor_pv
Сб 02 сентября 2017 г. 22:26
Рик, конструктор для массива, используемого в примере, опубликованном OP (String ramtest [xxx])) выдвигает правую память буферной памяти, когда конструктор вызывается. Не уверен, что это просто потому, что это массив, но это то, что он делает, поэтому каждая строка в массиве занимает 12bytes в BSS и еще 16 байтов в куче, при этом оставаясь пустым.

Это то, что вы ожидали?

Рик Кимбалл
Сб 02 сентября 2017 г. 22:55
Это не то, что я наблюдал в отладчике.

victor_pv
Солнце 03 сентября 2017 г. 14:17
Вы можете опубликовать .Карта файла из вашего кода? Это поможет увидеть, куда в основном идет память, а также посмотреть, вытаскивает ли она вещи из stdlib.
Вы также можете опубликовать разделы, в которых вы используете строки, как вы видели выше строки, это свинья памяти, так что, возможно, есть другой способ достичь того, что вы хотите сделать по -другому, который не примет все это.
Если вы не можете поделиться этими частями, то мы не можем знать, что происходит. Как я доказал ваш пример, куча может быть очень легко истощенной.

victor_pv
Солнце 03 сентября 2017 г. 14:25
[Рик Кимбалл - Сб 02 сентября 2017 г. 22:55] - Это не то, что я наблюдал в отладчике.
Ваш тест истощал кучу, как в моем? Если это так, когда выделили кучу и для чего?
Если это не истощало кучу, как в моем случае, это вообще сбило?

Рик Кимбалл
Солнце 03 сентября 2017 г. 16:50
Похоже, что он выделяет пустую строку.Буферный массив при инициализировании строкового массива.

Когда я отлаживал, я заметил строку.Буферная переменная является нулевой. Однако к тому времени, когда вы попадете в функцию setup (), строка.Буфер действительно имеет допустимое значение, выделенное. Минимальное распределение, по -видимому, составляет 16 байтов. Так что да, это зарезервирует .Пробел секции BSS и распределение памяти кучи перед настройкой () даже запуска.

Извините за путаницу.

Я вижу, что конструктор по умолчанию для строк по умолчанию String (const char *cstr = "") версия: (gdb) p my_array $3 = {{buffer = 0x20000c60 "", capacity = 0, len = 0}, {buffer = 0x0, capacity = 0, len = 0}} (gdb) where #0 String::String (this=0x20000b44 , cstr=0x8002e32 "") at /home/kimballr/Arduino/hardware/stm32duino/STM32F1/cores/maple/WString.cpp:34 #1 0x080001ba in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at /home/kimballr/Arduino/sketch_sep03a/sketch_sep03a.ino:1 #2 _GLOBAL__sub_I_my_array () at /home/kimballr/Arduino/sketch_sep03a/sketch_sep03a.ino:10 #3 0x08001216 in __libc_init_array () #4 0x08000214 in start_c () at /home/kimballr/Arduino/hardware/stm32duino/STM32F1/variants/generic_stm32f103c/wirish/start_c.c:84 #5 0xfffffffe in ?? () Backtrace stopped: previous frame identical to this frame (corrupt stack?)

victor_pv
Вторник 05 сентября 2017 г., 21:21
[Gasparobr - Пт - Код замораживает без причины, если я добавлю какую -либо строку или использую последовательные.print (); или сериал.print (f ()), с алокацией всего 23 тыс. Я использую много серийного процессора в этом коде. Это причина, по которой я сделал этот пример кода, чтобы проверить ОЗУ.

Сейчас я сделал другой тест с другим образцом, и я могу просто использовать 23 тыс. ОЗУ со строкой, но если я использую другие массивы поплавки и двойной, я могу использовать полные 64K.
Как вы видели, строка использует гораздо больше ОЗУ, чем статически распределенная сначала, и истощает кучу. Сказать, что вы можете использовать только 23 КБ со строкой, неверно, вы распределяете гораздо больше, 23 КБ во время компиляции, а остальные, чтобы завершить 64 КБ во время выполнения.
Вы должны проверить, имеет ли это место с вашим кодом, и вы истощаете кучу или стек.
Я обновлю заголовок этого потока, пока вы не сможете предоставить какой -то другой тестовый кусок кода, поскольку в исходном сообщении не отображается никаких проблем с распределением памяти в MCU или в ядре, а показывает, что создание массива тысяч объектов String Class занимает много памяти во время выполнения.

Rogerclark
Вторник 05 сентября 2017 г. 9:42 вечера
Виктор

Одна вещь, которую я заметил, это то, что Malloc (), кажется, не уходит изящно.
Он должен вернуть NULL, если не может выделить память, но на практике, если вы продолжаете распределять 8 байтов, в конечном итоге код будет сбоем.

Я наблюдал то же поведение с Nordic NRF51, которое также основано на руке, когда я составляю с использованием GCC.

Я не уверен, является ли проблем.

Я думаю, что я посмотрел на ядро ​​Libmaple некоторое время назад, чтобы посмотреть, использовался ли Malloc, и, начиная с того, что я помню, оно не использует Malloc.
Поэтому я полагаю, что каким -то образом я вызывает аварию, хотя я не уверен, как это возможно, если только она не выделяет память, которая используется в стеке

victor_pv
Ср. 06 сентября 2017 г. 18:53
Я не думаю, что ядро ​​использует Malloc или новый.
На самом деле я уверен, потому что, когда мы добавляем это в эскиз, мы видим, как втягивается дополнительный код.

Malloc () Он должен назвать new (), если я правильно помню, и я считаю, что new () не проверяет, где находится текущий стек, ни у него нет жесткого ограничения для кучи, отличной от вершины оперативной памяти (если я помню код верно).
Таким образом, в этом случае New () будет продолжать выделять память, пока не вызовет коррупцию стека и разбивание ядра, поскольку независимо от того, насколько маленьким является стек, он определенно будет ниже, чем вершина ОЗУ в любой момент времени.

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

Я не помню о макушке моей головы, какая ядра или какие сценарии линкеров используют эту технику, но мы можем посмотреть на Сэма и Тенси для справки.

Единственная проблема, которую я вижу, заключается в том, что даже если мы вернем ошибку (или нулевую), когда куча достигнет предела, это произойдет во время выполнения и, скорее всего, просто разбил доску, точно так же, как в примере в первом посте. Кроме того... Таким образом, это помогает определить проблему, если система вылетает прямо при загрузке, но я не думаю, что она полностью решает ее, так как размер стека переменная.
Даже если new () проверяется, где указатель стека правильный при его вызове, нет никакой гарантии, что указатель стека не станет ниже, как только возврат New () и несколько других функций вызваны.

Это хорошее чтение по вопросам класса строк:
http: // форум.Ардуино.CC/INDEX.PHP?Тема = 115552.0

И есть указатели на Биллу Греймана на то, как использование кучи полностью запрещено в некоторых критических встроенных системах:
http: // форум.Ардуино.CC/INDEX.PHP?тема ... #msg869721

Возможно, у Рика есть несколько советов о том, есть ли какая -то ценность для резервирования некоторого места в стеке.

ПИН -функции на доске.CPP

Generic STM32F103C8T6 от Taobao