BALDA 0 17 февраля Опубликовано 17 февраля · Жалоба Форумчане, поделитесь опытом, как вы определяете в своих проектам размер стека и кучи? какие факторы? от вольного как то не хочется? может есть какие то моменты диагностики когда видно, что объема стека или кучи не хватает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 53 17 февраля Опубликовано 17 февраля · Жалоба По-моему, подобная тема уже была. Если совсем уж абстратно, безотносительно потребностей проекта - то вообще пофик, от вольного, от балды. Вообще, нужно уточнить, о чем конкретно речь. Если о работе с RTOS, то такая тема тут уже была - там было сказано, что есть некоторые правила по размерам стека задачи, а так же описаны средства диагностики стека. В мануале на FreeRTOS это всё написано. Если же без RTOS, а в общем и целом, то стек - это динамическая штука, которая изменяется в зависимости от глубины вложенности функций и прерываний и размеров хранящихся локально в них переменных. А куча - это то пространство, которое выделяется функционалом работы с динамической памятью - malloc/free или new/delete. Средств диагностики в общем случае не имеют. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 66 17 февраля Опубликовано 17 февраля · Жалоба В 17.02.2024 в 17:15, BALDA сказал: какие факторы? Размер вызовов известен, могут еще параметры передаваться, глубину вызовов можно прикинуть и примерно посчитать. В 17.02.2024 в 17:15, BALDA сказал: может есть какие то моменты диагностики когда видно, что объема стека или кучи не хватает? При запуске программы забиваете стек например 0xАА - через некоторое время останавливаете отладку и наблюдаете до куда дотянулось. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 17 февраля Опубликовано 17 февраля · Жалоба 2 часа назад, BALDA сказал: Форумчане, поделитесь опытом, как вы определяете в своих проектам размер стека и кучи? Размер кучи определяю весьма надёжным методом: #define HeapSize 0 2 часа назад, BALDA сказал: может есть какие то моменты диагностики когда видно, что объема кучи не хватает? Ни разу не сталкивался с такой проблемой. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BALDA 0 17 февраля Опубликовано 17 февраля · Жалоба В 17.02.2024 в 15:51, HardEgor сказал: Размер вызовов известен, могут еще параметры передаваться, глубину вызовов можно прикинуть и примерно посчитать. При запуске программы забиваете стек например 0xАА - через некоторое время останавливаете отладку и наблюдаете до куда дотянулось. Интересная мысль... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
firstvald 14 17 февраля Опубликовано 17 февраля · Жалоба сходу нужно посмотреть : сколько параметров вы передаете в функцию. нет ли функций у которых много локальных переменных или даже массивов. тут же посмотреть с пристрастием. лучше объявить static чтобы не пихать в стек. а так, если проект небольшой, то под стек 0x400, как по умолчанию. если сложная машина то 0x800. а куча уж какая получится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 35 17 февраля Опубликовано 17 февраля · Жалоба Размер кучи опеределяется до первой ошибки выделения. Размер стека предварительно из отчёта по глубине вызовов функций. В железе - запонением стека константой. Можно при входе в функции проверять, но это замедляет. Можно MMU настроить, можно стек расположить по разному. В общем методов много - выбирается из реальной обстановки Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 53 17 февраля Опубликовано 17 февраля · Жалоба Еще можно так (только для диагностики): стек - по минимальному адресу в указателе стека MSP (это значение сохранять в глобальную static-переменную каждый раз при входе в любую функцию или прерывание. (стек идет сверху вниз, поэтому значение адреса уменьшаются). Куча - аналогично, по максимальному значению адреса, получаемого указателем при динамическом выделении памяти. Если эти адреса пересеклись - всё, хана котёнку, данные повреждены, оперативки выбранного МК недостаточно для всех хотелок. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 17 февраля Опубликовано 17 февраля · Жалоба 14 минут назад, EdgeAligned сказал: Еще можно так (только для диагностики): стек - по минимальному адресу в указателе стека MSP (это значение сохранять в глобальную static-переменную каждый раз при входе в любую функцию или прерывание. Это не поможет при вызове чужих (библиотечных) функций. А тот же printf() ох как много стека может откушать. Да и компилятор может своих функций нагенерить. Это во-первых, во-вторых: В случае с РТОС и отдельными стеками для каждой задачи, сохранять придётся не "в глобальную static-переменную", а в область данных текущей задачи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kochevkv 0 4 апреля Опубликовано 4 апреля (изменено) · Жалоба С кучей все понятно - если используете (или вызываемые функции используют) динамическое выделение памяти (всякие malloc, calloc, realloc в си) то надо считать вручную где и сколько учитывая вложенность вызовов функций. Или при отладке когда там они вернут ошибку невозможности выделения блока памяти. Со стеком - ошибки от его переполнения ловить сложнее. Нескольких килобайт обычно хватает, если в своих функциях в стеке не выделять массивы и большие структуры. А так если бездумно и на ПК можно поймать в рекурсии переполнение стека. Признаком переполнения стека у меня было "самопроизвольное" (я так сначала посчитал) изменение значений глобальных переменных и структур Изменено 4 апреля пользователем kochevkv Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 4 апреля Опубликовано 4 апреля · Жалоба On 2/17/2024 at 1:15 PM, BALDA said: Форумчане, поделитесь опытом, как вы определяете в своих проектам размер стека и кучи? Quote «С опытом приходит стандартный, научный подход к вычислению правильного размера стека: взять случайное число и надеяться на лучшее» — Jack Ganssle, «The Art of Designing Embedded Systems» Как правила, стек начинается со старшего адреса ОЗУ и растет навстречу глобальным переменным. Тут уж размер стека определяется тем, что осталось от глобальных переменных. Можно заняться оптимизацией их количества для увеличения размера стека. Куча начинается сразу после глобальных переменны и растет в сторону стека. Получается, вам размеры стека и кучи указывать вообще нет никакой необходимости. Они сами займут весь доступный объем в процессе работы вашей программы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 4 апреля Опубликовано 4 апреля · Жалоба 3 часа назад, dimka76 сказал: Как правила, стек начинается со старшего адреса ОЗУ и растет навстречу глобальным переменным. Это где такие правила утверждены и кем? 3 часа назад, dimka76 сказал: Куча начинается сразу после глобальных переменны и растет в сторону стека. Получается, вам размеры стека и кучи указывать вообще нет никакой необходимости. Они сами займут весь доступный объем в процессе работы вашей программы. Глупость. Это называется: Разложить себе самому грабли на ровном месте. Когда переполнения стека начнут портить данные в куче. И поиски такой проблемы могут быть весьма длительными. Любая ошибка должна проявляться как можно сильнее. Чтобы быстро быть обнаруженной. А не заметаться под ковёр. А значит самое разумное - расположить стек в самом начале ОЗУ. Чтобы при переполнении стека шло обращение за пределы ОЗУ и вызывало срабатывание защиты MPU или MMU (если таковой блок имеется). 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
girts 7 4 апреля Опубликовано 4 апреля (изменено) · Жалоба Quote А значит самое разумное - расположить стек в самом начале ОЗУ Наверное тут уже - сильно очень зависит что за архитектура при делах... Но мысль интересная. ИМХО чтоб с уверенностью - ставить какие то маркеры в RAM и периодически контролировать их. И принимать меры по надобности. Quote Это где такие правила утверждены и кем? На тех же AVR если пойнтер не трогать, он по умолчанию грузится в RAMEND.... А в начале адресного пространства - регистры... Тема, конечно, про ARM, так что уж извините если не к месту. Изменено 4 апреля пользователем girts Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 4 апреля Опубликовано 4 апреля · Жалоба On 4/4/2024 at 8:04 PM, girts said: На тех же AVR если пойнтер не трогать, Тут скорее GCC. GCC для ARM так же распределяет. Только отличие в указателе стека. Адрес начала стека надо самому в регистр заносить. И тут уж можно произвольно указать. Но если не пользоваться всякими ухищрениями, то обычно вершину ОЗУ и указывают. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sergey_Aleksandrovi4 1 Понедельник в 15:16 Опубликовано Понедельник в 15:16 · Жалоба On 2/17/2024 at 3:51 PM, HardEgor said: При запуске программы забиваете стек например 0xАА - через некоторое время останавливаете отладку и наблюдаете до куда дотянулось. Приём называется "stack painting" (окраска стека). Анализировать % использования стека можно не только в отладчике, но и программно. Бывает полезно при длительном тестовом прогоне оборудования. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться