Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос по LwIP
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
l_fin_l
Здравствуйте, использую LwIP порт для stm32f207(компилятор IAR), при работе более 24 часов, функция netconn_recv возвращает ошибку ERR_MEM. Не могу понять где не хватает памяти, как я понял стек выделяет для приема память из PBUF_POOL. Возможно я что-то недопонимаю, заранее спасибо.
scifi
Цитата(l_fin_l @ Dec 28 2016, 08:19) *
Не могу понять где не хватает памяти

Для таких случаев там есть возможность сбора статистики. Включите её и посмотрите, что там кончилось.
l_fin_l
lwip_stats выдает в поле "NETBUF" следущее:
-avail:6
-used:2
-max:3
-err:1
-illegal:0
т.е. как я понимаю, он не смог выделить память под структуру netbuf, хотя разрешенное мной кол-во составляет 6, а откуда он черпает память для выделения под структуры этого типа?
scifi
Цитата(l_fin_l @ Dec 28 2016, 14:06) *
т.е. как я понимаю, он не смог выделить память под структуру netbuf

Интересно, откуда это следует?
Правильнее будет сохранять всю статистику каждый час. Потом можно посмотреть, что утекает со временем.
l_fin_l
Цитата
Правильнее будет сохранять всю статистику каждый час. Потом можно посмотреть, что утекает со временем.

С другими типами структур все в порядке, всего хватает.
Pridnya
Цитата(l_fin_l @ Dec 28 2016, 08:19) *
Здравствуйте, использую LwIP порт для stm32f207(компилятор IAR), при работе более 24 часов, функция netconn_recv возвращает ошибку ERR_MEM. Не могу понять где не хватает памяти, как я понял стек выделяет для приема память из PBUF_POOL. Возможно я что-то недопонимаю, заранее спасибо.

Укажите хотя бы версию LwIP, а то люди отвечают даже не зная какая у вас версия (1.3.2...2.0.0). rolleyes.gif
И версию компилятора тоже можно указать.
l_fin_l
LwIP 1.4.0, IAR - 7.80.2
scifi
Кстати, ERR_MEM не обязательно означает, что кончилась память. Если заглянуть в исходники lwip, в некоторых ситуациях этот код возвращается не из-за исчерпания памяти, а из-за достижения других ограничений.
В общем, хорошо бы поймать в отладчике момент, когда возникает этот код, и установить точную причину.
Кстати, неплохо было бы включить вывод диагностической информации. Там точно будет сообщение о причине ERR_MEM.
l_fin_l
Ошибка вылетает в функции netconn_recv, когда пытается выделить память под MEMP_NETBUF(api_lib.c):
Код
  if (conn->type == NETCONN_TCP) {
    struct pbuf *p = NULL;
    /* This is not a listening netconn, since recvmbox is set */

    buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
    if (buf == NULL) {
      NETCONN_SET_SAFE_ERR(conn, ERR_MEM);
      return ERR_MEM;
    }

Ну и в самом маллоке вылетает ошибка(memp.c):
Код
  if (memp != NULL) {
    memp_tab[type] = memp->next;
#if MEMP_OVERFLOW_CHECK
    memp->next = NULL;
    memp->file = file;
    memp->line = line;
#endif /* MEMP_OVERFLOW_CHECK */
    MEMP_STATS_INC_USED(used, type);
    LWIP_ASSERT("memp_malloc: memp properly aligned",
                ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
    memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE);
  } else {
[b]    LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));
    MEMP_STATS_INC(err, type);[/b]
  }

Pridnya
Цитата(scifi @ Dec 29 2016, 11:43) *
Кстати, неплохо было бы включить вывод диагностической информации. Там точно будет сообщение о причине ERR_MEM.

Для этого нужно настроить какой-нибудь UART на вывод, переопределить макрос, который выводит отладочные строки в конкретный UART, и в настройках стека разрешить вывод отладочной информации вообще и в конкретных ситуациях.
l_fin_l
Цитата
Для этого нужно настроить какой-нибудь UART на вывод, переопределить макрос, который выводит отладочные строки в конкретный UART, и в настройках стека разрешить вывод отладочной информации вообще и в конкретных ситуациях.

Завтра сделаю, но я все-равно не могу понять что происходит, вроде как место под структуру должно быть, т.к всего 6(используется 2, максимально 3), и он не может выделить память, попадает в:
Код
  } else {
    LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));
    MEMP_STATS_INC(err, type);
  }
l_fin_l
Цитата
В общем, хорошо бы поймать в отладчике момент, когда возникает этот код, и установить точную причину.

При помощи отладчика увидел проблему, функция memp_malloc при выделении памяти переменной memp(memp_tab[5]) назначает NULL(т.е. не может выделить память)



Хотя потом продолжает дальше работать
Сергей Борщ
QUOTE (l_fin_l @ Jan 5 2017, 14:23) *
При помощи отладчика увидел проблему, функция memp_malloc при выделении памяти переменной memp(memp_tab[5]) назначает NULL(т.е. не может выделить память)
Это больше похоже на признак конца связанного списка. Отладчику это ничего не говорит и он продолжает честно показывать список дальше - это наблюдающий за отладчиком программист должен понять, что за нулевым указателем искать дальше нечего.
l_fin_l
Я понимаю, что это маркер конца списка, просто сам список состоит далеко не из шести элементов. Хотя на этапе инициализации создается список из шести элементов. Или он изменяется в процессе работы?
Сергей Борщ
QUOTE (l_fin_l @ Jan 5 2017, 16:55) *
просто сам список состоит далеко не из шести элементов
Я на вашей картинке вижу, что memp_tab[5] содержит список из трех элементов. При чем тут число шесть, я не понимаю. На указателе, хранящем ноль список заканчивается. Не нужно раскрывать этот элемент - данных по адресу ноль (очередного элемента списка) быть не может (это написано в Стандарте языка Си). Встретили ноль - остановилсь. Список закончился. Дальше данных нет. Указатель "ноль" - это бездна и заглядывать в нее не нужно. По адресу ноль физически располагается начало таблицы векторов прерываний и нет никакого смысла пытаться рассматривать часть ее как элемент списка. Отладчик таких тонкостей не знает и раскроет вам указатель, показывающий куда угодно. Но вы же человек, вы должны думать. Если вы посмотрите исходники, то увидите, что просмотр списка прекращается как только в указателе нашли NULL, а это и есть этот самый ноль.
l_fin_l
В режиме отладки выдает следующую ошибку(после нескольких часов работы):
memp_malloc: out of memory in pool NETBUF
В структуре lwip_stats в поле NETBUF, находятся следующие значения:
- avail: 6;
- used: 3;
- max: 3;
- err: 1;
И продолжает работать дальше...
l_fin_l
Как я понимаю, это утечка памяти. Но почему он выдает ошибку out of memory in pool NETBUF, если еще есть свободных три блока, ладно если все шесть блоков были заняты. Может кто сталкивался с таким?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.