Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Удаление семафора "на лету"
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > FreeRTOS
Cosmojam
Есть задача сделать программный перезапуск lwip при ошибках. Для этого в ассёртах выдаётся семафор, в который упёрта задача собственно выполняющая перезапуск. Все создаваемые треды, семафоры и очереди сохраняются в связных списках по ходу создания (в sys_arch.c в функция создания этих объектов вызов добавления их в списки)
Сначала вызывается удаление всех тредов:
Код
struct s_netapp *netapp = netapp_root;
    netapp_root = NULL;
    while(netapp != NULL)
    {
        struct s_netapp *current = netapp;
        netapp = netapp->next;
        vTaskDelete(current->handle);
        vPortFree(current);
        current = NULL;
    }

Вроде всё проходит ОК.
Затем выход из треда с приличной задержкой чтобы дать возможность выполниться айдлу в котором происходит освобождение памяти. Сам тред в котором запущено удаление так же имеет приоритет айдла.
Затем удаление семафоров:
Код
struct s_semaphr *semphr = semaphr_root;
    semaphr_root = NULL;
    while(semphr != NULL)
    {
        printf("semaphore delete... %lu\n", semphr->sema);
        struct s_semaphr *current = semphr;
        semphr = semphr->next;
        vSemaphoreDelete(current->sema);
        vPortFree(current);
        current = NULL;
        printf("ok, semphr = %lu\n", semphr);
    }

И тут всё виснет после удаления 6 штук:
Цитата
semaphore delete... 268462400
ok, semphr = 268462640
semaphore delete... 268462544
ok, semphr = 268462784
semaphore delete... 268462664
ok, semphr = 268465112
semaphore delete... 268464992
ok, semphr = 268469624
semaphore delete... 268469504
ok, semphr = 268469960
semaphore delete... 268469840

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

Пробовал останавливать все задачи перед удалением семафоров (vTaskSuspendAll()), отключать все прерывания, увеличивать приоритет треда, выходить из треда после удаления каждого семафора (т.е. давать айдлу возможность освободить память) - не помогает, так же всё виснет после удаления 6 семафоров.
Подскажите как попробовать ещё или как иначе лучше решить задачу с перезапуском lwip?
Cosmojam
Конкретно виснет в vPortFree()::prvInsertBlockIntoFreeList() на
Код
    for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
    {
        /* Nothing to do here, just iterate to the right position. */
    }

С heap_2 и heap_4 одинаково.
Причём такая проблема только с семафорами и очередями созданными в одном треде. Если проигнорировать семафоры и очереди именно из этого треда то всё проходит нормально. Правда всё равно не работает то что задумано и виснет на создании основного треда lwip, но это по идее другая история
wave48
Можно проверить как будет вести себя мой аллокатор:
http://electronix.ru/forum/index.php?showt...15&start=15
Был сделан из-за такого же рода ошибок.
lwip вроде бы свои собственные (не RTOS) семафоры и очереди использует.
Cosmojam
Цитата(wave48 @ Oct 3 2013, 12:35) *
Можно проверить как будет вести себя мой аллокатор:
http://electronix.ru/forum/index.php?showt...15&start=15
Был сделан из-за такого же рода ошибок.
lwip вроде бы свои собственные (не RTOS) семафоры и очереди использует.

Спасибо! Попробую сегодня
lwip использует семафоры от ртос. Обёртки для работы с ними в sys_arch.{c,h} пишутся. Вроде кроме это больше ничего подобного в нём нет
kolobok0
Цитата(Cosmojam @ Oct 4 2013, 12:46) *
lwip использует семафоры от ртос....


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

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


это типа как ышо одна мысля...
MALLOY2
Зачем его перезапускать ? Стек работает годами без каких либо глюков, ищите проблему в другом месте, а не грабли прикрывайте листьями. А если по делу, что бы сильно не вникать в кишки lwip, создайте список всех созданных lwip хендлов, потом зарубать задачу lwip, потом в цикле все хендлы, потом заново создать задачу. Но еще раз это не правильно LWIP проверен годами.
Cosmojam
Цитата(kolobok0 @ Oct 4 2013, 13:48) *
долго наблюдал этот топик...
в своё время не прокатило останов/удаление потока из вне. если присмотреться к типовым решениям, то обычно это делается из того-же самого потока. т.е. поток получает команд - убейся, идёт и грохает свой хэндл. может тут собака порылась у вас? (насколько я увидел в вашем кусочке кода - Вы грохаете потоки из вне)

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

Цитата(MALLOY2 @ Oct 4 2013, 16:08) *
Зачем его перезапускать ? Стек работает годами без каких либо глюков, ищите проблему в другом месте, а не грабли прикрывайте листьями. А если по делу, что бы сильно не вникать в кишки lwip, создайте список всех созданных lwip хендлов, потом зарубать задачу lwip, потом в цикле все хендлы, потом заново создать задачу. Но еще раз это не правильно LWIP проверен годами.

По-хорошему - да. Но разобраться с этой проблемой в данном проекте не удалось ни мне ни ещё нескольким людям. Поэтому было принято решение прикрывать грабли листьями. Было бы здорово если Вы хорошо разбираетесь в lwip и помогли бы справится с этой проблемой за $.

wave48, с Вашим выделятором кажется нашёл утечку памяти в проекте. Сначала были такие глюки как в первом посте описаны. Потом другие люди вносили изменения в проект, причём совсем в другую его часть. Потом у меня начал вываливаться malloc hook в ртосе. Не вдаваясь в подробности попробовал Ваш выделатор - тоже самое, в какой-то момент malloc_z() возвращает NULL. Видимо где-то тут собака порылась.
wave48
Цитата(Cosmojam @ Oct 6 2013, 16:18) *
wave48, с Вашим выделятором кажется нашёл утечку памяти в проекте. Сначала были такие глюки как в первом посте описаны. Потом другие люди вносили изменения в проект, причём совсем в другую его часть. Потом у меня начал вываливаться malloc hook в ртосе. Не вдаваясь в подробности попробовал Ваш выделатор - тоже самое, в какой-то момент malloc_z() возвращает NULL. Видимо где-то тут собака порылась.


Рост кучи в нем легко увидеть, посмотрев в отладчике что происходит с system_heap. malloc_z() может не выделить память только если размер кучи этого не позволяет. Можно и нужно делать дефрагментацию кучи, вызывая по таймеру defragHeap(). Скорее всего, кто-то забыл про то что нужно память освобождать. ;-)) Есть специальная функция для определения возможности получения памяти - getHeapMaxSize(). Успехов.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.