Jump to content

    

FreeRTOS и спецы ST

Ребята, прошу разъяснения.
При просмотре примеров, которые создают ребята из ST, у меня какой-то диссонанс возникает.
Что-то я упускаю, или чего-то недопонимаю глубинного... :blush:
Вот типовой пример:
(кусок из main)

  // Init thread
  osThreadDef(Start, StartThread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 2);  
  osThreadCreate (osThread(Start), NULL);
  
  // Start scheduler
  osKernelStart();
  
  // We should never get here as control is now taken by the scheduler
  for( ;; );

Ну и сама задача

static void StartThread(void const * argument)
{ 
  // Create tcp_ip stack thread
  tcpip_init(NULL, NULL);
  
  // Initialize the LwIP stack
  Netif_Config();
  
  // Initialize webserver demo
  http_server_netconn_init();
  
  // Notify user about the network interface config
  User_notification(&gnetif);
  
  // Start DHCPClient
  osThreadDef(DHCP, DHCP_thread, osPriorityBelowNormal, 0, configMINIMAL_STACK_SIZE * 2);
  osThreadCreate (osThread(DHCP), &gnetif);


  for( ;; )
  {
    // Delete the Init Thread
    osThreadTerminate(NULL);
  }
}

Мне вот непонятно, зачем запускается задача, из которой апускается ещё несколько, и удаляется стартующая задача.
Ведь ка минимум, при этом появится дырка в памяти. В чём преимущество такого подхода, по сравнению скажем, если я сразу из main запущу эти задачи?
 

Share this post


Link to post
Share on other sites
4 minutes ago, SapegoAL said:

При просмотре примеров

Хм... а это точно FreeRTOS? Вызовы не её. Или это какие-то мкросы/функции над вызовами этой оси?

4 minutes ago, SapegoAL said:

Мне вот непонятно, зачем запускается задача, из которой апускается ещё несколько, и удаляется стартующая задача.

Я тоже так делаю. Если вы посмотрите внимательнее, то там не только другие задачи запускаются, но и инициализируются сетевые сервисы. А им на момент инициализации уже может понадобится запущенная операционная система. В моих проектах именно так и происходит. Например, для инициализации драйверов периферии нужна уже запущенная ОС, т.к. драйвера используют её сервисы (объекты синхронизации, межпроцессного взаимодействия, да и сами иногда запускают поток).

4 minutes ago, SapegoAL said:

Ведь ка минимум, при этом появится дырка в памяти

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

Edited by haker_fox

Share this post


Link to post
Share on other sites
19 minutes ago, haker_fox said:

Хм... а это точно FreeRTOS? Вызовы не её. Или это какие-то мкросы/функции над вызовами этой оси?

Гугл говорит что это CMSIS-RTOS API

24 minutes ago, SapegoAL said:

Мне вот непонятно, зачем запускается задача, из которой апускается ещё несколько, и удаляется стартующая задача.

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

Share this post


Link to post
Share on other sites
On 8/16/2019 at 4:05 PM, AlexandrY said:

Гугл говорит что это CMSIS-RTOS API

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

Это FreeRTOS с "обёрткой". Сейчас ST так делает. Скорее всего в последствии планируют переходить на CMSIS-RTOS. Я за CMSIS_RTOS не слежу, но как я понял, пока её ещё нет. Думаю авторы FreeRTOS над ней работают, или привлекаются. Будет под флагом CMSIS выходить.
StartThread является задачей, а не функцией. И ей выделяется стек из кучи. При удалении, очевидно появляется дырка. Понятно стек выделяется куском, и, в принципе, он может быть использован.

On 8/16/2019 at 3:45 PM, haker_fox said:

Я тоже так делаю. Если вы посмотрите внимательнее, то там не только другие задачи запускаются, но и инициализируются сетевые сервисы. А им на момент инициализации уже может понадобится запущенная операционная система. В моих проектах именно так и происходит. Например, для инициализации драйверов периферии нужна уже запущенная ОС, т.к. драйвера используют её сервисы (объекты синхронизации, межпроцессного взаимодействия, да и сами иногда запускают поток).

Спасибо. Понял.

Share this post


Link to post
Share on other sites
8 минут назад, SapegoAL сказал:

StartThread является задачей, а не функцией. И ей выделяется стек из кучи. При удалении, очевидно появляется дырка. Понятно стек выделяется куском, и, в принципе, он может быть использован.

Так не выделяйте динамически. Выделяйте статически. И не будет дырки.

Share this post


Link to post
Share on other sites
54 minutes ago, jcxz said:

Так не выделяйте динамически. Выделяйте статически. И не будет дырки.

Правда память и не вернётся в систему. Честно говоря, до недавнего времени я был ярым приверженцем динамической памяти в приборах. До тех пор, пока мы не собрали первый прибор, который должен работать в режиме 365 дней... Вот тут, когда стала проявляться фрагментация памяти, и прибор стал периодически перезагружаться (срабатывала ловушка), я подумал, что можно обойтись и статической памятью. Да и менеджеры кучи не всегда шустрые. Со вруменем (как я понимаю, когда память фрагментируется) время их работы увеличивается.

Share this post


Link to post
Share on other sites

Ну у меня динамически выделяется. Прибор коммерческого учёта. Работает годами. Ничего не перезагружается. Правда у меня, после старта, только LwIP динамически с памятью работает.
Я не делал удаление/ запуск задач "на лету".
Да, если какая то задача запрашивает размер памяти, который отсутствует в системе одним куском, то крах произойдёт.
Но тут у Вас 2 выхода. Либо размер кластера увеличить. Либо запускать дефрагментацию периодически. Дефрагментация - решаемая задача.

Share this post


Link to post
Share on other sites
4 minutes ago, SapegoAL said:

Прибор коммерческого учёта. Работает годами. Ничего не перезагружается.

Понятно, что здесь ситуация сугубо субъективная. В одном проекте память так распределена, в другом - этак. Мы тоже свой прибор довели до ума) Но я сделал вывод, что в принципе, это динамическое выделение не везде и нужно.

Share this post


Link to post
Share on other sites
9 minutes ago, haker_fox said:

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

Ну по-моему это очевидно. Работа с динамической памятью сложнее и объёмнее. Загрузка проца, непроизводительной работой выше. Приходится непрерывно работать с косвенной адресацией. Требуется обеспечить корректную работу в многозадачных системах при выделении/ удалении.
Если в этом нет необходимости, то зачем притягивать за уши? Если при статическом распределении у Вас хватает памяти, то это самый лучший выход.

Share this post


Link to post
Share on other sites
11 minutes ago, SapegoAL said:

Приходится непрерывно работать с косвенной адресацией.

Простите? Получаем же указатель, и дальше всё как обычно... Да и в Си/Си++ проблемы адресации по-моему закрыты для программиста.

12 minutes ago, SapegoAL said:

Если при статическом распределении у Вас хватает памяти, то это самый лучший выход.

Угу.

Share this post


Link to post
Share on other sites
3 часа назад, SapegoAL сказал:

Но тут у Вас 2 выхода. Либо размер кластера увеличить. Либо запускать дефрагментацию периодически. Дефрагментация - решаемая задача.

"Решаемая"?? Это интересно - как? :smile:  

Как решаете в

3 часа назад, SapegoAL сказал:

Прибор коммерческого учёта. Работает годами.

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

 

PS: Я конечно понимаю что это можно реализовать. И даже примерно представляю как. Но это будет такой гемор, с такими огромными накладными расходами и затратами на отладку и реализацию, что заниматься этим может только убеждённый мазохист.  :dash2:

3 часа назад, SapegoAL сказал:

Приходится непрерывно работать с косвенной адресацией.

Если разговор про ARM, то в его системе команд нет других способов адресации данных в памяти, кроме косвенной. И от того - используется динамическая память или нет этот факт не изменится.  :wink:

Share this post


Link to post
Share on other sites
В 22.08.2019 в 08:37, SapegoAL сказал:

Правда у меня, после старта, только LwIP динамически с памятью работает.

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

Share this post


Link to post
Share on other sites
On 8/22/2019 at 12:22 PM, jcxz said:

"Решаемая"?? Это интересно - как? :smile:  

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

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

Share this post


Link to post
Share on other sites
18 minutes ago, SapegoAL said:

Отладка времени займёт. Короче, перспективы не очень радужны.

Я как-то вообще не очень от менеджеров памяти. Прикручивал дакже всякие bget  и tsfl... медлеееенннооо...((( Ну или я прикрутил неправильно((( Самый шустрый - тот, который поставляется с компилятором. Но там возможности отладки, как правило, ограничены.

Share this post


Link to post
Share on other sites
В 30.08.2019 в 15:15, haker_fox сказал:

Прикручивал дакже всякие bget  и tsfl... медлеееенннооо...((( Ну или я прикрутил неправильно((( Самый шустрый - тот, который поставляется с компилятором. Но там возможности отладки, как правило, ограничены.

А тот, что уважаемый zltigo реализовал? Интересно было бы узнать, какое он место в вашем рейтинге бы занял?

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