Jump to content

    

Помогите разобраться с LwIP!

Пытаюсь разобраться с LwIP под STM32F7.  За основу взята одна из демок Web-сервера без FreeRTOS. HTTP я  выбросил,  взяв от туда куски связанные с инициализацией LwIP.

Задача - просто передать пакет пот TCP от компа в контроллер.  Контроллер является сервером. Инициалицая, биндинг и соединение проходят (правда, не каждый раз, но это второй вопрос), а вот при получении пакета получается какая-то фигня:

 TCP_ACK_delay.thumb.png.39622dc170d533f5c797ffc8fc3d564a.png 

Контроллер получает пакет, но акнолидж почему-то  не отправляет.  Через пару секунд винда делает повторную посылку и тогда сразу отправляется два акнолиджа.  

Если отправлять большой кусок данных, то ситуация немного лучше:  акнолидж  на первый фрейм  так-же не приходит, пока не будет повтора,  а последующие подтверждаются примерно через 200мс.  Но скорость как-то все-равно не айс:  100к за 5 секунд.

TCP_ACK_delay2.thumb.png.218ee1be33b36931612d2f2e1922b533.png

 Вот код  инициализации и callback функции:

 /* Инициализация */

  MyPCB = tcp_new();
  tcp_setprio(MyPCB, 64);
  err = tcp_bind(MyPCB,IP_ADDR_ANY, 55);
  MyPCB = tcp_listen(MyPCB);
  tcp_arg(MyPCB, MyPCB);
  tcp_accept(MyPCB, MyTCPAccept);  


  /* Main loop */
  while (1)
  {
    LwIP_Pkt_Handle();
    LwIP_Periodic_Handle(timeCounter);
  }
}

/*Callback фуккции*/

static err_t MyTCPAccept(void *arg, struct tcp_pcb *pcb, err_t err)
{

  struct tcp_pcb_listen *lpcb = (struct tcp_pcb_listen*)arg;

  tcp_accepted(lpcb);
  tcp_setprio(pcb, 64);
  tcp_arg(pcb, 00);
  tcp_recv(pcb, MyTCPRecv);
  tcp_err(pcb, MyTCPErr);
  tcp_poll(pcb, 0, 4);
  tcp_sent(pcb, 0);
  return ERR_OK;
}

static err_t MyTCPRecv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
    printf ("Received %d\n",p->tot_len);
    tcp_recved(pcb, p->tot_len);
    pbuf_free(p);
    return ERR_OK;
}

static void MyTCPErr(void *arg, err_t err)
{
    printf ("LWP_ERR: %d\n",err);

}

Что я не так делаю?

TCP_ACK_delay.png

Share this post


Link to post
Share on other sites
  MyPCB = tcp_new();
...
  MyPCB = tcp_listen(MyPCB);
...

Так точно должно быть?

Edited by VladimirG
Фигню сморозил (

Share this post


Link to post
Share on other sites
25 minutes ago, b-volkov said:

взяв от туда куски связанные с инициализацией LwIP.

Задача - просто передать пакет пот TCP от компа в контроллер.

А это точно совместимо? Выкинуть инициализацию TCP/IP стека, и требовать передачи пакета по этому протоколу? Зачем вы удалили инициализацию? И какую?

Насколько я помни, lwIP требует грамотного драйвера MAC-контроллера, и файла связки между этим драйвером и самим стеком. Да, стек не совсем простой в настройке. Но за пару-тройку дней можно разобраться. У меня получилось. Два раза)

Share this post


Link to post
Share on other sites

В рассылке lwip регулярно появляются вопросы о поднятии lwip на STM32x7. Все дискуссии, как правило, заканчиваются сообщением: у ST глючный драйвер MAC и ссылкой на https://community.st.com/s/question/0D50X0000BOtfhnSQB/how-to-make-ethernet-and-lwip-working-on-stm32

Share this post


Link to post
Share on other sites
1 hour ago, haker_fox said:

А это точно совместимо? Выкинуть инициализацию TCP/IP стека, и требовать передачи пакета по этому протоколу? Зачем вы удалили инициализацию? И какую?

Насколько я помни, lwIP требует грамотного драйвера MAC-контроллера, и файла связки между этим драйвером и самим стеком. Да, стек не совсем простой в настройке. Но за пару-тройку дней можно разобраться. У меня получилось. Два раза)

Так я не выкидывал инициализацию стека, просто это не попало в листинг :) . Я выкинул только HTTP-сервер

  EthHandle.Instance = ETH;
  EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
  EthHandle.Init.Speed = ETH_SPEED_100M;
  EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
  EthHandle.Init.MACAddr = &macaddr[0];
  EthHandle.Init.RxMode = ETH_RXPOLLING_MODE;
  EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
  EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
  EthHandle.Init.PhyAddress = 0;
  EthHandle.State = HAL_ETH_STATE_RESET;

  if (HAL_OK != HAL_ETH_Init(&EthHandle))
  {
    printf("ETH init fail!\n");
    while(1);
  }
  
   printf("ETH init OK.\n");
  /* Initialize Tx Descriptors list: Chain Mode */
  HAL_ETH_DMATxDescListInit(&EthHandle, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
  /* Initialize Rx Descriptors list: Chain Mode  */
  HAL_ETH_DMARxDescListInit(&EthHandle, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);

  /* Initilaize the LwIP stack */
  LwIP_Init();

Думаю, если бы МАС не был привязан к стеку, вообще бы ничего не работало. А тут просто непонятные задержки...

А что именно Вы настраивали в стеке? У меня такое ощущение, что либо не те настройки, либо я чего-то не делаю в callback-функции.

 

Share this post


Link to post
Share on other sites
1 hour ago, Сергей Борщ said:

В рассылке lwip регулярно появляются вопросы о поднятии lwip на STM32x7. Все дискуссии, как правило, заканчиваются сообщением: у ST глючный драйвер MAC и ссылкой на https://community.st.com/s/question/0D50X0000BOtfhnSQB/how-to-make-ethernet-and-lwip-working-on-stm32

Я запускал LwIP UDP на STM32H743 с драйвером MAC от ST.

Сутками конечно не гонял, но несколько часов работало.

Share this post


Link to post
Share on other sites
43 minutes ago, b-volkov said:

Думаю, если бы МАС не был привязан к стеку, вообще бы ничего не работало. А тут просто непонятные задержки...

Это и есть глючный драйвер

Share this post


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

Задача - просто передать пакет пот TCP от компа в контроллер.  Контроллер является сервером.

И зачем этот мастадонт ради такой задачи? Чтоб потом забибикаться с его динамической памятью, чуть где что не освободил, проспал по таймауту, потом решил освободить и попал в ассерт с полной перезагрузкой МК и всего остального... Берите что-то вроде uIP для такой задачи самое оно, вот если будете клиентские соединения поднимать, тогда в нем все это криво реализовано, мне пришлось переписывать...

Share this post


Link to post
Share on other sites

To: dimka76

 

UDP я пока не пробовал, хотелось бы с TCP разобраться...

Ваш проект с FreeRTOS (или какой другой OS)?  Просто я использую демку от IAR-STM32F746xx-SK которую сам переделывал под STM32F746-DISCOVERY. Эта не самая новая демка (main - файл датирован 14 годом)и, возможно, не самая "прямая", но это единственный проект, который я смог найти без  FreeRTOS,которая мне на фиг не нужна. Родной пример  для этого КИТа, увы, работает с RTOS,   а "выпилить" ее мне ума не хватило, слишком глубоко она там засела.  Мне TCP нужна исключительно для "получил/передал пакет" . По этому просьба: если у кого есть работающие примеры/проекты использования lwip БЕЗ всяких там осей - буду крайне признателен.

Share this post


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

Но скорость как-то все-равно не айс:  100к за 5 секунд.

По поводу подтверждений, тут надо настраивать размеры окна стек вроде как это умеет...

Share this post


Link to post
Share on other sites
17 minutes ago, b-volkov said:

To: dimka76

 

UDP я пока не пробовал, хотелось бы с TCP разобраться...

Ваш проект с FreeRTOS (или какой другой OS)?  Просто я использую демку от IAR-STM32F746xx-SK которую сам переделывал под STM32F746-DISCOVERY. Эта не самая новая демка (main - файл датирован 14 годом)и, возможно, не самая "прямая", но это единственный проект, который я смог найти без  FreeRTOS,которая мне на фиг не нужна. Родной пример  для этого КИТа, увы, работает с RTOS,   а "выпилить" ее мне ума не хватило, слишком глубоко она там засела.  Мне TCP нужна исключительно для "получил/передал пакет" . По этому просьба: если у кого есть работающие примеры/проекты использования lwip БЕЗ всяких там осей - буду крайне признателен.

Я для STM32H743 брал из STM32Cube_FW_H7_V1.3.2

Проект брал без FreeRTOS.

Share this post


Link to post
Share on other sites
3 minutes ago, mantech said:

И зачем этот мастадонт ради такой задачи? Чтоб потом забибикаться с его динамической памятью, чуть где что не освободил, проспал по таймауту, потом решил освободить и попал в ассерт с полной перезагрузкой МК и всего остального... Берите что-то вроде uIP для такой задачи самое оно, вот если будете клиентские соединения поднимать, тогда в нем все это криво реализовано, мне пришлось переписывать...

Совершенно с Вами согласен. Мало того, у меня уже есть реализация под другой камень  своего простенького (если не сказать - примитивненького) UDP, которого вполне хватает для моих задач. Просто надумал освоить STM32F7, купил КИТ и вижу, что в комплекте уже готовый полноценный IP-стек. В принципе, не исключена ситуация, что когда-нибудь моему девайсу придется работать с какой либо сторонней софтиной или железякой, которые могут только по TCP.  Вот и решил попробовать, не думал, что эта вещь такая капризная. 

Ну раз не получается с LwIP, тогда пойдем ниже. Тут уже писали ранее писали о глючности MAC-драйверов. Речь идет о HAL-драйвере эзернета? Как тогда быть?  Самому писать?

Share this post


Link to post
Share on other sites
7 минут назад, b-volkov сказал:

Речь идет о HAL-драйвере эзернета? Как тогда быть?  Самому писать?

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

Edited by mantech

Share this post


Link to post
Share on other sites
4 часа назад, b-volkov сказал:

Совершенно с Вами согласен. Мало того, у меня уже есть реализация под другой камень  своего простенького (если не сказать - примитивненького) UDP, которого вполне хватает для моих задач.

Ну раз опыт есть и UDP реализовывали, то дописать туда ещё TCP - это всего лишь примерно ещё 3 раза по столько. Зато будет своё, в котором легко разбираться.

Я свой TCP-стек уже много лет по разным камням таскаю (адаптирую). И не подводит.

Положить перед глазами "Рисунок 18.12 Диаграмма изменений состояния TCP" отсюда: http://www.xserver.ru/computer/protokol/tcpip/3/18.shtml

и по шагам (состояниям автомата состояний TCP) постепенно реализовать.

Share this post


Link to post
Share on other sites
4 hours ago, b-volkov said:

...Ну раз не получается с LwIP, ...  Самому писать?

 

- "А Вы за меня и есть будете?"

- "АГА!!!"

(из мультика)

 

А чего его там писать то? Зато можно оптимально и надёжно изобразить. A LwIP в своё время был один из немногих кто мог собирать дефрагментированные пакеты на IP уровне...

 

как то так

(круглый)

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