Jump to content

    

FreeRTOS 9.0 Static

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

 

Share this post


Link to post
Share on other sites
Точно так же как и раньше

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

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

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

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

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

 

 

Share this post


Link to post
Share on other sites
2. Отслеживать указатель стека при вызове функций.

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

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

Share this post


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

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

 

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

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

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
Стеки задач в процессе работы firmware у меня не меняются (как и сами задачи).

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

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

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

 

 

 

Share this post


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

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

Share this post


Link to post
Share on other sites
Система управления версиями решает эту проблему за пару секунд.

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

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

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

 

Share this post


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

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

Share this post


Link to post
Share on other sites

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

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

Share this post


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

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

 

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

Share this post


Link to post
Share on other sites

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

Share this post


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

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

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

Share this post


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

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

 

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

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

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

 

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

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

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

 

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

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

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

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

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

 

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this