Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Утечка памяти из PBUF_PULL
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > FreeRTOS
athlon64
Использую FreeRTOS 7.2 + LwIP 1.4.0, процессор STM32F217.
Сборка основана на демо-проекте с сайта st.com, в которой был обновлён сначала FreeRTOS, затем LwIP. С LwIP 1.3.2 утечка тоже была (собственно, поэтому и решил попробовать обновить LwIP 1.3.2 -> 1.4).

Проблема проявляется следующим образом:
Константа PBUF_POOL_SIZE = 20
Веду опрос контроллера по modbus-tcp с 4 клиентов, всё работает прекрасно. В статистике стека по использованию буферов PBUF_POOL used = 0..2, max = 4..5. Параллельно пингую контроллер.
Через некоторое время (обычно около 8-10 минут) счётчики используемых буферов начинают расти (used и max) вплоть до 20. Если во время роста остановить опрос контроллера, то счётчик used не обнуляется, т.е. буферы не освобождаются. Далее при дальнейшем опросе все буферы занимаются и все новые входящие пакеты игнорятся.

Проблема была и до обновления стека.
Подозреваю что баг либо в драйвере MAC, либо в моей задаче.
В какую сторону копать? Наверняка многие с этим сталкивались.
Gunner
QUOTE (athlon64 @ Sep 29 2012, 13:54) *
Использую FreeRTOS 7.2 + LwIP 1.4.0, процессор STM32F217.
Сборка основана на демо-проекте с сайта st.com, в которой был обновлён сначала FreeRTOS, затем LwIP. С LwIP 1.3.2 утечка тоже была (собственно, поэтому и решил попробовать обновить LwIP 1.3.2 -> 1.4).

Проблема проявляется следующим образом:
Константа PBUF_POOL_SIZE = 20
Веду опрос контроллера по modbus-tcp с 4 клиентов, всё работает прекрасно. В статистике стека по использованию буферов PBUF_POOL used = 0..2, max = 4..5. Параллельно пингую контроллер.
Через некоторое время (обычно около 8-10 минут) счётчики используемых буферов начинают расти (used и max) вплоть до 20. Если во время роста остановить опрос контроллера, то счётчик used не обнуляется, т.е. буферы не освобождаются. Далее при дальнейшем опросе все буферы занимаются и все новые входящие пакеты игнорятся.

Проблема была и до обновления стека.
Подозреваю что баг либо в драйвере MAC, либо в моей задаче.
В какую сторону копать? Наверняка многие с этим сталкивались.

Попробуйте
#define SYS_LIGHTWEIGHT_PROT 1
athlon64
Цитата(Gunner @ Oct 1 2012, 11:20) *
Попробуйте
#define SYS_LIGHTWEIGHT_PROT 1

Офигеть! Слона то я и не приметил biggrin.gif
Пока тестирую, но похоже, что это решает проблему.
athlon64
Теперь стек работает более менее сносно. Но смущают 2 вещи:
1. Нарастает счётчик lwip_stats.sys.mbox.err. При увеличении длины очереди константой archMESG_QUEUE_LENGTH, ошибки помещения в очередь прекращаются, но начинают расти другие (lwip_stats.memp[8].err - TCPIP_MSG_INPKT).
2. При опросе контроллера периодически (каждые 20-30 секунд) происходят TCP-Retransmission. Всегда в одном направлении (к контроллеру).
athlon64
Наставил в разных местах стека счётчиков TCP-пакетов на MAC контроллера, удалось выяснить, что:
1. В low_level_input() из сети добираются все пакеты, отправленные с контроллеру, а из low_level_output() все пакеты отправляются в сеть.
2. В задачу tcpip_thread() пропущенные пакеты не попадают. Т.е. функция sys_timeouts_mbox_fetch() не отдаёт эти пакеты задаче tcpip_thread().
Копаю дальше
athlon64
Разобрался!

Баг 1: В sys_arch.c функция sys_mbox_t sys_mbox_new(int size) создавала всегда очередь длиной archMESG_QUEUE_LENGTH, вместо того чтобы создавать очередь передаваемого ей размера. Соответственно, все очереди были одинаковой длины (по-умолчанию 6), а настройки:
Код
#define TCPIP_MBOX_SIZE
#define DEFAULT_UDP_RECVMBOX_SIZE
#define DEFAULT_TCP_RECVMBOX_SIZE
#define DEFAULT_ACCEPTMBOX_SIZE

при создании очередей игнорировались.

Баг 2: Исправление бага с отвалом пингов способом, который представлен на форуме st.com не совсем удачное. Если изменить ethernetif_input() в соответствии с их рекомендацией, то функция приёма пакетов (tcpip_input() для NO_SYS=0) вызывается примерно 270 раз на каждый пакет, что вызывает переполнение майлбоксов, используемых для передачи пакетов с задачи ethernetif_input в задачу tcpip_thread, что вызывает пропуски пакетов.
Для борьбы с "отвалом пингов" использовал метод, рекомендованный здесь
IXUS666
Цитата(athlon64 @ Oct 5 2012, 07:13) *
Разобрался!

Баг 1: В sys_arch.c функция sys_mbox_t sys_mbox_new(int size) создавала всегда очередь длиной archMESG_QUEUE_LENGTH, вместо того чтобы создавать очередь передаваемого ей размера. Соответственно, все очереди были одинаковой длины (по-умолчанию 6), а настройки:
Код
#define TCPIP_MBOX_SIZE
#define DEFAULT_UDP_RECVMBOX_SIZE
#define DEFAULT_TCP_RECVMBOX_SIZE
#define DEFAULT_ACCEPTMBOX_SIZE

при создании очередей игнорировались.

Баг 2: Исправление бага с отвалом пингов способом, который представлен на форуме st.com не совсем удачное. Если изменить ethernetif_input() в соответствии с их рекомендацией, то функция приёма пакетов (tcpip_input() для NO_SYS=0) вызывается примерно 270 раз на каждый пакет, что вызывает переполнение майлбоксов, используемых для передачи пакетов с задачи ethernetif_input в задачу tcpip_thread, что вызывает пропуски пакетов.
Для борьбы с "отвалом пингов" использовал метод, рекомендованный здесь

Подскажите исходя из чего нужно задавать константы #define TCPIP_MBOX_SIZE, #define DEFAULT_UDP_RECVMBOX_SIZE, #define DEFAULT_TCP_RECVMBOX_SIZE, #define DEFAULT_ACCEPTMBOX_SIZE ? Или где можно про них почиать.
В ST'шном примерах последние три констаны определены как 2000 O_O.
У вас кстати ETH_RXBUFNB сколько стоит, 5? У меня до установки SYS_LIGHTWEIGHT_PROT 1, более менее стабильно работало только с ETH_RXBUFNB=1. Сейчас пробую с SYS_LIGHTWEIGHT_PROT 1 и ETH_RXBUFNB 5, на плате одновременно запущен TCP сервер и TCP клиент, работает это все уже часов 7, пока ничто не отвалилось но потихоньку накапливается lwip_stats.sys.mbox.err.
athlon64
Цитата(IXUS666 @ Oct 6 2012, 16:41) *
Подскажите исходя из чего нужно задавать константы #define TCPIP_MBOX_SIZE, #define DEFAULT_UDP_RECVMBOX_SIZE, #define DEFAULT_TCP_RECVMBOX_SIZE, #define DEFAULT_ACCEPTMBOX_SIZE ? Или где можно про них почиать.
В ST'шном примерах последние три констаны определены как 2000 O_O.
У вас кстати ETH_RXBUFNB сколько стоит, 5? У меня до установки SYS_LIGHTWEIGHT_PROT 1, более менее стабильно работало только с ETH_RXBUFNB=1. Сейчас пробую с SYS_LIGHTWEIGHT_PROT 1 и ETH_RXBUFNB 5, на плате одновременно запущен TCP сервер и TCP клиент, работает это все уже часов 7, пока ничто не отвалилось но потихоньку накапливается lwip_stats.sys.mbox.err.

Константы выбираете исходя из задач и нагрузки. Добиваетесь отсутствия ошибок выделения памяти и записи в очередь на максимальной загрузке. У меня так:
Код
#define TCPIP_MBOX_SIZE                 150
#define DEFAULT_UDP_RECVMBOX_SIZE       20
#define DEFAULT_TCP_RECVMBOX_SIZE       70
#define DEFAULT_ACCEPTMBOX_SIZE         20
#define ETH_RXBUFNB 10

Попробуйте для начала заменить в функции sys_mbox_new
Код
*mbox = xQueueCreate( archMESG_QUEUE_LENGTH, sizeof( void * ) );

на
Код
*mbox = xQueueCreate( size, sizeof( void * ) );

и посмотрите как ведут себя счётчики переполнений.

Убедитесь, что все очереди успешно создаются. Они отъедают кучу FreeRTOS, которой может не хватать.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.