Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: FreeRTOS + lwIP
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > FreeRTOS
_Mikhail_
Добрый день!
Имеются FreeRTOS 8 + lwIP 1.4.1 + LPC2478.
Столкнулся с такой проблемой. Работаю через Netconn API. Шлю на плату TCP пакеты (утилитой netcat передаю файлы по X Мб). Какое-то время пакеты проходят через стек нормально (10...20...40 Мб). Но в какой-то момент времени стек все чаще и чаще начинает выдавать отказ в выделении памяти под принятый пакет (memp_malloc_fn), пока прием совсем не "захлебывается". При этом передача от платы через другое соединение работает нормально. Принятые пакеты netconn_recv не обрабатываю, а просто отбрасываю (пока), затем удаляю буфер netbuf_delete. Стеки, кучи операционки большие и пустые. В lwipopts.h тоже памяти выделено достаточно. Стек по какой-то причине выделяет больше пулов, чем освобождает. Причину утечки никак найти не могу. На вход стека с mac пакеты выдаю корректные (по крайней мере так думаю).
Может кто сталкивался с подобной проблемой, в каком направлении копать?

Нажмите для просмотра прикрепленного файла
WitFed
На заступ надо провериться -- вдруг данных пишется больше, чем ожидалось (или железо пинается не на те адреса, выгрузка "в молоко"), портятся системные области, а там уже и "рух" недалеко.
Если нет такого "системного" средства в ОС, надо как-то "встрять" в каждое выделение/освобождение памяти, выделять на 16 байт больше, заливать первые 8 чем-то "особым", типа "DEADBEAF", последние 8 аналогично и возвращать указатель +8, ну а при возврате -- проверять на "особость". Обычно "вдаль" сразу никто не заступает, и так ловится большинство проблем.
Если этот заступ, конечно, был давно, определить причину будет трудно, ибо придётся отмотать момент выделения данного куска, кому он был нужен и для чего.
Тогда нужно стабилизировать наступление глюка: например, "принимать" пакеты не из физики, а из рандомного генератора. Вдруг при его стабильном стартовом значении и дальше всё будет повторяться 1в1...

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

Реентерабельность вдруг где хромает, семафор где-то "застреливают" аппаратной выгрузкой, возвращаемое значение при захвате не анализируют полностью...

Абсолютно детерминированная "повторябельность на N-м такте" при лечении глюков может сильно помочь, её надо добиваться в первую очередь. Тогда, в принципе, можно остановиться на любом предыдущем и проследить всё остальное. Где-то и "назад" могут степать отладчики, но жить в эту пору прекрасную... wink.gif

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

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

TCP в данном случае достаточно нехороший протокол (там много форматных излишеств ради восстановления пропавших пакетов, которые в локалке очень трудно сейчас "задушить"), легче через UDP попытаться вести "обстрел".
_Mikhail_
Цитата(WitFed @ Feb 5 2015, 16:01) *
На заступ надо провериться -- вдруг данных пишется больше, чем ожидалось (или железо пинается не на те адреса, выгрузка "в молоко"), портятся системные области, а там уже и "рух" недалеко.
Если нет такого "системного" средства в ОС, надо как-то "встрять" в каждое выделение/освобождение памяти, выделять на 16 байт больше, заливать первые 8 чем-то "особым", типа "DEADBEAF", последние 8 аналогично и возвращать указатель +8, ну а при возврате -- проверять на "особость". Обычно "вдаль" сразу никто не заступает, и так ловится большинство проблем.
Если этот заступ, конечно, был давно, определить причину будет трудно, ибо придётся отмотать момент выделения данного куска, кому он был нужен и для чего.
Тогда нужно стабилизировать наступление глюка: например, "принимать" пакеты не из физики, а из рандомного генератора. Вдруг при его стабильном стартовом значении и дальше всё будет повторяться 1в1...

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

Реентерабельность вдруг где хромает, семафор где-то "застреливают" аппаратной выгрузкой, возвращаемое значение при захвате не анализируют полностью...

Абсолютно детерминированная "повторябельность на N-м такте" при лечении глюков может сильно помочь, её надо добиваться в первую очередь. Тогда, в принципе, можно остановиться на любом предыдущем и проследить всё остальное. Где-то и "назад" могут степать отладчики, но жить в эту пору прекрасную... wink.gif

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

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

TCP в данном случае достаточно нехороший протокол (там много форматных излишеств ради восстановления пропавших пакетов, которые в локалке очень трудно сейчас "задушить"), легче через UDP попытаться вести "обстрел".


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

Пока остановился на том, что полноценный стек для моей задачи не нужен (просто хотелось его пощупать). Время, которое я мог себе позволить на решение этой проблемы, закончилось.
Сейчас уже проще самому написать простейшую реализацию UDP, чем сейчас и занялся. А с потерей пакетов разбираться буду уже на прикладном уровне.
Дальше планирую работать с кортексами, а там есть уже готовые связки (почти официальные, только до ума довести, под себя подстроить) стека, ОС (например в LPCExpresso). Возможно там такой проблемы уже не будет.
Но вообще разобраться было бы интересно. При случае кое-что из предложенного попробую. Спасибо.
den_po
Память выделяется с помощью pvPortMalloc?
_Mikhail_
Цитата(den_po @ Feb 9 2015, 15:48) *
Память выделяется с помощью pvPortMalloc?


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

В том варианте, в каком я использую стек, он выделяет память единожды, а потом выделяет/освобождает пулы под/от данные, не пользуясь функциями типа malloc. Я в этот механизм не вмешиваюсь. У меня получается, что заканчиваются свободные пулы при p = pbuf_alloc( PBUF_RAW, len, PBUF_POOL ) (и дальше по цепочке до memp_malloc_fn).

Но пробовал и другие варианты, результат аналогичен.

Мне кажется, что проблема явно не в самом стеке, а в его порте (emac.c, ethernetif.c) или я что-то не правильно настроил в lwipopts.h

den_po
Цитата(_Mikhail_ @ Feb 9 2015, 18:54) *
На сколько я понял, то LwIP имеет свой механизм выделения памяти.

В общем да, но зависит от.
На всякий случай можно перепроверить константы MEM_* и MEMP_*
lwip\src\include\lwip\opt.h
lwipopts.h
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.