Jump to content

    

FreeRTOS 9.0 Static

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

В том, что без этих действий легко обойтись.

Для того, чтобы менеджер распределял память из разных блоков, ему надо как-то сообщить: какой блок мы хотим в очередном запросе?

Да.

Да и наверняка в вызовах менеджера памяти....

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

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

Это вообще НЕ проблема сделать, как я сделал. ОДИН раз много лет назад был создан инструмент идентификации и просмотра блоков памяти. Он работает с тех пор тупо автоматически всегда и вообще нет необходимости придумывать причины его не использовать. Причем, поскольку динамическое выделение памяти используется на только для стеков задач, то этот же инструмент позволяет просматривать и области памяти всяких буферов и очередей.

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

Одна из областей в которой работают мои изделия, это телекоммуникационное оборудование. На объектах оно связано с оборудованием десятков производителей. Причем окружение все время меняется, поскольку сети живут и развиваются. Протоколы взаимодействия весьма сложны и имеют массу реализация, например, SS7 https://ru.wikipedia.org/wiki/ОКС-7. Я очень рад, что "у себя в лаборатории" Вы можете "воссоздать обстановку заказчика" :).

Share this post


Link to post
Share on other sites
Там используется обертка над одним из нескольких "штатных" менеджеров памяти. Я использую свой менеджер, имеющий больше возможностей. Если, вдруг окажется нужным разным задачам выделять тот же стек в разных блоках, добавлю без проблем. Эти дополнения будут ничем не сложнее добавления статического выделения памяти руками в разных секциях и их описание в скриптах линкера. Даже проще.

Без проблем? Для этого Вам придётся модифицировать код самой FreeRTOS. Например: добавив в список аругментов xTaskCreate() ещё и идентификатор нужной кучи где стек выделять. И пробросить этот идентификатор внутрь xTaskCreate() до вызова Вашего malloc().

Или например передавать этот идентификатор через глобальную переменную, завернув вызов xTaskCreate() вместе с установкой этой переменной внутрь критической секции.

Конечно можно и так сделать. Можно и трусы через голову надевать каждую переменную в куче выделять. Но только - ЗАЧЕМ???

Зачем все эти кучи, malloc()-и и пр. хлам когда задачи создаются однократно (при старте firmware) и, соответственно, стеки выделяются также однократно. И никогда не освобождаются.

Зачем все эти лишние сущности, которые тратят доп. память, увеличивают кол-во кода и время выполнения (хоть и не на много)?

Даже просто посмотреть состояние стека выделенного статически гораздо проще. Для этого не нужно писать никакие свои тулзы, достаточно эмулятора. С динамическим стеком всё много сложнее.

 

Это вообще НЕ проблема сделать, как я сделал.

Сделать можно всё что угодно, вопрос - зачем?

В программе всегда есть переменные/массивы, время жизни которых - всё время работы ПО. Такие переменные нужно распределять статически (сюда относятся и стеки статических задач).

Можно конечно все такие переменные выделять на куче (и я видел что многие ламеры так и делают на PC). Но зачем??? Никаких плюсов это не даёт, одни минусы.

Всё, что может быть распределено build-time и должно распределяться build-time.

Share this post


Link to post
Share on other sites
Без проблем? Для этого Вам придётся модифицировать код самой FreeRTOS.

Она и так модифицирована в том числе и под другой менеджер памяти. Многое в ней не устраивало :(, или было недостаточно функционально с самого начала. На уровне 6 версии я вообще перестал следить за основной веткой. Только относительно недавно просмотрел 9 версию и с удовлетворением обнаружил, что подавляющая часть изменений, которая есть у меня и предлагалась Автору, таки появилась в 9 версии. Так что я добавил в 9 версию некоторые изменения (свой менеджер памяти, несколько дополниельных системных вызовов, другой порядок создания idle задачи,...) и у меня теперь большую часть проектов можно собирать с двумя вариантами операционки - "моим" и "почти 9".

Зачем все эти кучи, malloc()-и и пр. хлам когда задачи создаются однократно (при старте firmware) и, соответственно, стеки выделяются также однократно. И никогда не освобождаются.

Это у Вас в Ваших настольных :) системах однократно. У меня есть и задачи, которые порождаются и уничтожаются. Как минимум это одна задача начальной инициализации и диагностики системы.

Зачем все эти лишние сущности, которые тратят доп. память, увеличивают кол-во кода и время выполнения (хоть и не на много)?

"Лишняя сущность" в виде динамического выделения памяти под задачи, конечно, "тратят память" на MCB, но эти затраты сразу с лихвой компенсируются даже уничтожением одной ставшей ненужной задачи типа начальной инициализации.

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

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

С динамическим стеком всё много сложнее.

Много проще, поскольку так или иначе в устройстве есть встроенные отладочные средства для отладки не "на столе" c эмуляторами, симуляторами, отладчиками... Такова моя реальность.

Сделать можно всё что угодно, вопрос - зачем?

Уже многократно объяснял.

В программе всегда есть переменные/массивы, время жизни которых - всё время работы ПО. Такие переменные нужно распределять статически (сюда относятся и стеки статических задач).

О! Появилась мысль, что задачи могут быть не статическими :). Так что, будете, как Вы тут выражались - "лишние сущности" и тоже менять операционку для создания статических и динамических задач? Вот уж точно лишние сущности, если есть создание динамических задач.

Можно конечно все такие переменные выделять на куче (и я видел что многие ламеры так и делают на PC).

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

Но зачем??? Никаких плюсов это не даёт, одни минусы.

Все уже говорилось неоднократно. То, что Вы ХОТИТЕ что-то не видеть, это не означает, что этого нет.

Всё, что может быть распределено build-time и должно распределяться build-time.

Вот тут уж мне остается только Вам задать вопрос - Почему?

Share this post


Link to post
Share on other sites
"Лишняя сущность" в виде динамического выделения памяти под задачи, конечно, "тратят память" на MCB, но эти затраты сразу с лихвой компенсируются даже уничтожением одной ставшей ненужной задачи типа начальной инициализации.

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

 

Много проще, поскольку так или иначе в устройстве есть встроенные отладочные средства для отладки не "на столе" c эмуляторами, симуляторами, отладчиками... Такова моя реальность.

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

Опять минус Вашего варианта ;)

 

О! Появилась мысль, что задачи могут быть не статическими :). Так что, будете, как Вы тут выражались - "лишние сущности" и тоже менять операционку для создания статических и динамических задач? Вот уж точно лишние сущности, если есть создание динамических задач.

Причём тут операционка??? Опять передёргиваете и подменяете понятия....

Например есть функция создания задачи (uCOS):

INT8U OSTaskCreate (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT8U prio)

где: ptos - указатель на вершину стека;

Передаю туда указатель на статически распределённый стек.

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

Зачем менять ОС, которая принимает указатель на стек, а не только его размер???

 

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

Ну понятно - Вам проще, так как у Вас всё работает на столе и нет жёстких требований по экономии памяти, быстродействия и т.п. Можно хоть каждый байт в куче выделять...

Поди и связные интерфейсы реализуете ногодрыгом? :biggrin:

 

Вот тут уж мне остается только Вам задать вопрос - Почему?

Ладно - воля Ваша - делайте хоть malloc(1) для каждого байта, хозяин - барин.

Share this post


Link to post
Share on other sites
И в чём выигрыш от её уничтожения? Или хотите сказать, что освобождаете память занятую под её стек? Т.е. - что такое union и как с его помощью можно эффективно распределять память, используемую на разных этапах работы ПО разными процессами, Вы не в курсе?

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

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

Опять минус Вашего варианта ;)

Ага, для каждого случая каждый раз вписывать. Некрасиво, если все может быть ОДИН раз написано и использоваться и для задач и для любых блоков памяти.

Причём тут операционка??? Опять передёргиваете и подменяете понятия....

Например есть функция создания задачи (uCOS):

INT8U OSTaskCreate (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT8U prio)

где: ptos - указатель на вершину стека;

Передаю туда указатель на статически распределённый стек.

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

Зачем менять ОС, которая принимает указатель на стек, а не только его размер???

Передавайте. Речь идет НЕ о том, как выглядит системный вызов конкретной операционной системы, а об самом факте использования динамически выделяемой памяти.

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

Ну понятно - Вам проще, так как у Вас всё работает на столе и нет жёстких требований по экономии памяти, быстродействия и т.п. Можно хоть каждый байт в куче выделять...

Поди и связные интерфейсы реализуете ногодрыгом? :biggrin:

Изверетелись, как я вижу весь в попытках объснить "ненужность" :( и начали просто хамить :(. Напомню, что все началось с того, что я написал, что как раз "наcтольные" приемы отладки недоступны ввиду абсолютно ненастольных условий. Теперь Вы вдруг взялись рассказывать, что у меня, а не у Вас настольные системы. Что для "ногодрыга", который почему-то на голубом глазу мне тоже приписали, не требуется быстродействия. Ну и на сладкое вообще глупость, про экономию памяти - динамическое выделение памяти как раз и позволяет ЭКОНОМИТЬ память в системах с ограниченными ресурсами. А, например, те же телекомуникационные системы они все такие - делят ограниченные ресурсы каналов, пропускной способности каналов,... И соответственно и микроконтролеры имеют ресурсы в том числе и по памяти требуемой для процессов и соединений на расчетную нагрузочную способность.

Ладно - воля Ваша - делайте хоть malloc(1) для каждого байта, хозяин - барин.

Спасибо, но про выделение памяти под байт, это Вы придумали. Я всегда писал только о функционально законченных блоках памяти, причем в основном хранящих однотипную информацию (очереди, буфера,....). Что в качестве ДОПОЛНИТЕЛЬНОГО эффекта позволяет при динамическом выделении под них памяти использовать встроенные унифицированные средства отладки и для их просмотра и анализа.

 

 

Share this post


Link to post
Share on other sites
Это надуманная проблема.

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

Одно из недорузамений, которое происходит при общении с опытными людьми, возникает в тот момент, когда они пытаются тебе сказать, что много видели, и много знают, а значит, ситуации которой они не знают, просто не существует :rolleyes: Без обид. Занимаюсь разработкой оборудования, которое может работать на подстанции вплоть до 750 кВ. Воссоздать всю эту "мерзкую" обстановку из электромагнитных полей у себя сможет далеко не каждая сертифицированная лаборатория. А симитировать какой-нить транс на 250 МВа вообще невозможно, не имея такой же у себя (или дорого в десятой степени) :rolleyes:

 

Можно конечно все такие переменные выделять на куче (и я видел что многие ламеры так и делают на PC). Но зачем??? Никаких плюсов это не даёт, одни минусы.

Отдельные переменные выделять в куче - это, на мой взгляд, ибыточно. Обычно в куче выделяются массивы данных. Зачем это делать динамически во встраиваемой системе? Но ведь сама FreeRTOS изначально диктует динамическое выделение структур: стек, TCB... Статически всё это выделять можно только с 9 версии, если я не ошибаюсь.

 

Также удобно по ходу программы писать что-то в стиле

type_t * ptr = new type_t[ WANT_SIZE]

,

использовать массив, а затем удалить его, нежели заранее создавать его статически.

Share this post


Link to post
Share on other sites
Зачем это делать динамически во встраиваемой системе?

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

 

 

 

Share this post


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

"Смешались в кучу кони, люди...."

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

Менеджер не имеет никакого прямого отношения к ОС, она вообще может его не использовать (посмотрите например на uCOS).

Соответственно - говорить о каком-то "духе операционной системы" - по меньшей мере странно.

 

Изверетелись, как я вижу весь в попытках объснить "ненужность" :( и начали просто хамить :(.

Смотримся в зеркало:

Это у Вас в Ваших настольных :) системах однократно.

 

Ну и на сладкое вообще глупость, про экономию памяти - динамическое выделение памяти как раз и позволяет ЭКОНОМИТЬ память в системах с ограниченными ресурсами.

Вот это как раз и есть ГЛУПОСТЬ.

Каким образом экономят объясните пожалуйста??? Количество бит в байтах увеличивает?

Именно обычное дин. выделение, а не выделение блоков одинакового размера по Вашему экономит?

Т.е. - что такое фрагментация дин. памяти Вы как бы не задумывались никогда?

 

Воссоздать всю эту "мерзкую" обстановку из электромагнитных полей у себя сможет далеко не каждая сертифицированная лаборатория. А симитировать какой-нить транс на 250 МВа вообще невозможно, не имея такой же у себя (или дорого в десятой степени) :rolleyes:

Ну естественно воссоздание насколько это возможно.

 

Обычно в куче выделяются массивы данных. Зачем это делать динамически во встраиваемой системе? Но ведь сама FreeRTOS изначально диктует динамическое выделение структур: стек, TCB... Статически всё это выделять можно только с 9 версии, если я не ошибаюсь.

На FreeRTOS свет клином не сошёлся. Есть и другие ОС, где разработчики постарались отделить мух от котлет и не валить всё в одну кучу, а предоставить возможность разработчику самому решать как ему оптимальнее распределить память. Та же uCOS например. Во FreeRTOS до этого додумались почему-то только к 9-й версии.

 

Также удобно по ходу программы писать что-то в стиле

type_t * ptr = new type_t[ WANT_SIZE]

,

использовать массив, а затем удалить его, нежели заранее создавать его статически.

А теперь представьте, что это работает не в игрушке у Вас на столе, с которой Вы поигрались и потом выключили, ну а если что зависло - нажали кнопочку RESET. А что это система, работает за много тыс. км где-нить на месторождении в тайге у заказчика, куда и дороги-то нету. И что таких устройств не одно, а их тысячи работают. И работают они в режиме 24/7. И что задача под ОС крутится не одна, а с десяток или больше. И что задачи эти обрабатывают события асинхронные друг относительно друга. И что требования к памяти у этих задач разные: одна выделяет большими блоками редко, другая часто и мелкими, третья - вообще разные размеры запрашивает.

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

Вот тут и идёт лесом всё удобство....

Конечно если памяти в устройстве с избытком, то здесь другое дело. Но мне всё время приходилось работать над системами, где ресурсов в обрез.

Share this post


Link to post
Share on other sites
Вот это как раз и есть ГЛУПОСТЬ.

Есть два человека - Вы и я. Я умею и пользуюсь с успехом динамическим выделением памяти. Вы НЕ умеете и не пользуетесь, но считаете возможным уже не первый пост нести пургу о "ненужности" и в "доказательство" начинаете приписывать мне то использование менеджера для выделения памяти по байту, то хаотические бессистемные и бездумные запросы и освобождения разнообразных блоков памяти да еще и при полном отсутствии у менеджера борьбы с дефрагментацией. Поскольку я не вчера слез с пальмы, а уже десятки лет проектирую, как уже писал, контроллеры для высокоответственных применений при заведомо ограниченных ресурсах (в том числе и памяти), то мне просто надоело с Вами общаться в таком ключе и выслушивать "идеи", как использовать менеджеры памяти через анальное отверстие. Если Вы по другому не умеете, это Ваши проблемы, а не проблемы менеджера памяти.

Share this post


Link to post
Share on other sites
Вы НЕ умеете и не пользуетесь, но считаете возможным уже не первый пост нести пургу о "ненужности" и в "доказательство" начинаете приписывать мне то использование менеджера для выделения памяти по байту, то хаотические бессистемные и

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

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

И ещё раз - не надо мне приписывать, чего-то, совершенно безосновательно. Динамическое выделение памяти (особенно для задач связи) я широко использую, только не в виде классического интерфейса malloc(), а в виде выделения индексов элементов статически распределённого массива (с элементами одинакового размера).

А вот динамическое выделение стеков для задач считаю и неудобным и совершенно ненужным. О чём и написал в первом посте.

Share this post


Link to post
Share on other sites
Я просто отразил этот стиль на Вас....

"Отобразил" это очень правильное слово. Только отобразили Вы не "стиль", а свой ограниченный круг задач, свои ограниченные знания операционных систем, свои ограниченные навыки и приемы программирования :(.

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

Share this post


Link to post
Share on other sites
. . .

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

. . . .

Записано в мой "цитатник Мао" за Вашим (С) авторством :)

 

 

Share this post


Link to post
Share on other sites

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

 

Переписываю задачи на статик. Получаю в плагине IAR странное у.г. В частности, больше не отображается состояние задач - RUNNING/BLOCKED и т.д.

 

FreeRTOS v.9.0.0

IAR EWARM 7.2 с плагином: "Kernel awareness for FreeRTOS and OpenRTOS" 3.0.0

 

Это у всех так стало или пора обновлять IAR?

 

Немного прошелся поиском. Нашел здесь же, на электрониксе, топик с архивом, с плагином версии 2.х.х С ним, при открытии проекта, IAR просто падает, при попытке открыть проект. Что не удивительно.

post-15600-1481373378_thumb.png

Share this post


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

Этот Ваш высер означает только то, что действительно больших и ответственных систем работающих в тяжелых условиях Вы даже и приблизительно не представляете :(. Есть места на планете, куда если и можно отправить "квалифицированного" сервисного инженера, то не быстро (например, заполярье оно, блин, даже дальше МКАД), и компьютерами с отладчиками его обвешать тоже нельзя, например, по причине взрывоопасных условий в шахте с оборудованием размазанным на сотни километров под землей. И вообще там очень грязно, темно, столов, стульев и даже розеток для компьютеров нет совсем, зато есть каска с фонарем, резиновые сапоги, роба, самоспасатель на шее и возможность ползать на четвереньках. А стоимость простоя комплекса в ожидании сервисинженера (а что, сервисинженер должен уметь собой заменять и программиста, и вообще всех?) со свежим лицензионным IAR EWARM и плагинами к нему :), это не много, а очень очень много.

Share this post


Link to post
Share on other sites
Ваш высер

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

 

А пока, если по существу моего вопроса ответить нечего - проходи мимо и не флуди. Я доходчиво обозначил позицию? Повторяться, как это часто бывает, для самых тупых/упоротых, не придется, надеюсь? Ты же выше этого, да? :D

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