Перейти к содержанию
    

В новой версии FreeRTOS 9.0 появилась возможность выделять память (под задачи/очереди и т.д.) статически.

Подскажите, как определить оптимальный размер памяти под стек задачи? Ну, кроме как ловить vApplicationStackOverflowHook?

Может есть какая-то методика?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Точно так же как и раньше

1. Прописываем стек известным значением (мне нравится DEADBEEF) и потом смотрим

2. Отслеживать указатель стека при вызове функций.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Точно так же как и раньше

Ага. Только много неудобнее, ибо динамически выделенная память находится под управления менеджера памяти и соответственно можно добавить того-же владельца памяти и тип блока. В результате чего становится возможным абсолютно независимо от задач смотреть за тем-же использованием стека.

1. Прописываем стек известным значением (мне нравится DEADBEEF) и потом смотрим

А мне CAFEBABE :) - оптимистичнее :)

2. Отслеживать указатель стека при вызове функций.

Отслеживать - да. При вызове каких-то неведомых функций - незачем. У меня всегда есть консолька в ней можно и посмотреть по директиве и распределение памяти (статическое не использую по причине нахренненужности и неудобства - см.выше) и использование стеков.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2. Отслеживать указатель стека при вызове функций.

Что-то я в этих стеках не очень понимаю. Может подскажите, где можно прочитать?

Что и кто туда пишет? Локальные переменные данной задачи? Значения регистров, при вызове прерываний, во время активности задачи?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ага. Только много неудобнее, ибо динамически выделенная память находится под управления менеджера памяти и соответственно можно добавить того-же владельца памяти и тип блока. В результате чего становится возможным абсолютно независимо от задач смотреть за тем-же использованием стека.

Что же мешает делать то же самое при статически выделенных стеках?

 

Отслеживать - да. При вызове каких-то неведомых функций - незачем. У меня всегда есть консолька в ней можно и посмотреть по директиве и распределение памяти (статическое не использую по причине нахренненужности и неудобства - см.выше) и использование стеков.

Я динамическое не использую по той же самой причине - нафига оно? Зачем ещё какие-то функции вызывать чтобы распределить этот блок под стек в run-time, когда то же самое прекрасно сделает линкер в build-time?

Стеки задач в процессе работы firmware у меня не меняются (как и сами задачи).

И, например, если в устройстве есть разная память (по скорости/латентности/занятости другими bus-masters), то статически я могу раскидать стеки задач по разным типам памяти, как считаю нужным. А с динамическим выделением что - для каждой памяти свой манагер писать??

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если освоить SystemView, то можно на большом экране красивые диаграммы видеть. Только это надо обычно один раз. Ну или для простоты в Watch окне смотреть сколько осталось до границы стека. В общем 100500 способов есть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Стеки задач в процессе работы firmware у меня не меняются (как и сами задачи).

Но меняются от релиза к релизу. В результате, в случае чего, возникают интересные вопросы, а как память была распределоена линкером на релизе XX.YY годовой давности стоящем где-то на объекте...

А с динамическим выделением что - для каждой памяти свой манагер писать??

Нет, менеджер один, а блоки памяти, которые он распределяет, могут быть разные. Никаких проблем. Кроме того, менеджер памяти может работать и внутри уже им-же выделенного блока памяти, например, при использовании одинаковых по размеру блоков памяти для гарантированного исключения дефрагментации.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но меняются от релиза к релизу. В результате, в случае чего, возникают интересные вопросы, а как память была распределоена линкером на релизе XX.YY годовой давности стоящем где-то на объекте...

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Система управления версиями решает эту проблему за пару секунд.

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

Если я правильно понял контекст вашего ответа. Кстати, как тут поможет динамическое выделение?

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если освоить SystemView, то можно на большом экране красивые диаграммы видеть. Только это надо обычно один раз. Ну или для простоты в Watch окне смотреть сколько осталось до границы стека. В общем 100500 способов есть.

Просветите пожалуйста, что за SystemView? И как в Watch окне смотреть сколько осталось до границы стека?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Копируем в гуглопоиск SystemView и смотрит первую ссылку.

2. В начале каждой функции делаем функцию которая сохраняет меньшее значение указателя стека из текущего и сохраненного. Конец стека мы и так знаем. В Watch их выбираем и смотрим.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Слабо представляю себе ситуацию, чтобы выехать на объект с пустыми руками, т.е. без инструментария и проекта. А если есть проект, так там и репозиторий (.git), где вся история в подробностях.

 

Кроме того, как правило имеется удалённый репозиторий, с которым регулярно делается синхронизация. Есть бесплатные и хорошо развитые и бесплатные сервисы как для открытых (github.com), так и закрытых (bitbucket.com) проектов. Т.ч. всегда можно вытянуть проект, был бы интернет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А мне тоже нравится динмаическое распределение, чувствуешь какую-то волшебную принадлежность к большим ОС))) Ну, а если серьёзно, то действительно удобно смотреть, что кому отдано и для каких целей)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Слабо представляю себе ситуацию, чтобы выехать на объект с пустыми руками, т.е. без инструментария и проекта. А если есть проект, так там и репозиторий (.git), где вся история в подробностях.

Объектов многие тысячи за многие годы. Экземпляров оборудования - миллионы. На объекте есть обслуживающий персонал заказчика, выехать максимум могут сервисные инженеры из ближайшего сервисного центра, но ближайший, это тоже могут быть пару тысяч километров. Ничего из вышеперечисленного у них нет, как и соответствующей квалификации :(. Часть оборудования вообще находится во взрывоопасных и труднодоступных местах (так что ни компьютеров, ни отладчиков там не может быть в принципе).

Таковы реалии. Так что наличие встроенных средств локализации совершенно обязательно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но меняются от релиза к релизу. В результате, в случае чего, возникают интересные вопросы, а как память была распределоена линкером на релизе XX.YY годовой давности стоящем где-то на объекте...

Узнаём версию firmware "где-то на объекте", скачиваем её исходники из репозитария, компилим, открываем .map и смотрим. В чём проблема?

 

Нет, менеджер один, а блоки памяти, которые он распределяет, могут быть разные. Никаких проблем. Кроме того, менеджер памяти может работать и внутри уже им-же выделенного блока памяти, например, при использовании одинаковых по размеру блоков памяти для гарантированного исключения дефрагментации.

Для того, чтобы менеджер распределял память из разных блоков, ему надо как-то сообщить: какой блок мы хотим в очередном запросе? Т.е. - очевидно нужно передать какой-то доп. аргумент в функции malloc() или new (что там используется во FreeRTOS?). И как же из вызова xTaskCreate() передать в каком блоке памяти она должна выделить память? Да и наверняка в вызовах менеджера памяти внутре FreeRTOS она запрашивает у malloc()/new только объём памяти и не передаёт никаких доп. аргументов.

Так как же при создании задачи FreeRTOS задать блок памяти в каком она должна выделить стек?

 

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

Это надуманная проблема.

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

 

2. В начале каждой функции делаем функцию которая сохраняет меньшее значение указателя стека из текущего и сохраненного. Конец стека мы и так знаем. В Watch их выбираем и смотрим.

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

Да и алгоритм действий компилятора, при котором он на входе в функцию один раз делает PUSH/SUBS SP,... а потом больше не трогает SP, это имхо не есть догма.

Не исключаю, что в каких-то случаях или какие-то компиляторы могут в теле функции менять SP. Это во многих случаях было бы полезно.

Да и учтите, что стеков может быть много (при наличии RTOS да и не только).

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...