Jump to content

    

lwip 1.4.0 и несколько потоков

Вот мне интересно разобраться с потоками в связке freertos и lwip 1.4.0. Одни говорят что этот стек не стабилет на несколько потоков вторые утверждают что все работает.

На сколько я понимаю, потоки - это freertos таски которые используют функционал lwip стека. То есть, если с нескольких тасков вызвать функции lwip то случится что-то страшное? Еще читал что в настройках самого стека есть дефайн, который включает мютексы и как бы эти проблемы решаются, но пока такого не нашел.

 

Я провожу следующий эксперемент:

Использую HTTP сервер. На нем крутится один сайт с java. То есть, браузер несколько раз в секунду аякс запросами запрашивает данные с сервера.

Использую HTTP клиент, который тоже несколько раз в секунду в считывает данные с одного девайса.

Вот у меня тут получается два потока.

 

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

 

Может просто надо сделать так, чтобы пока работает HTTP сервер, HTTP клиент ждал и не устанавливал никаких подключений. Но как это сделать? На ум прихрдят только критические секции и приостановка шедуллера. Может для этого есть возможности в самом lwip?

Share this post


Link to post
Share on other sites
Одни говорят что этот стек не стабилет

Не верте им,все стабильно работает, если все правильно настроено. LWIP заточен для работы с ОС. Еще вы не уточнили какой камень ? Судя по вашей проблемы ноги растут скорее всего от кривого драйвера МАС. Скажем так драйвера которые для STM32 предоставляются с всякими примерами работают глючно.

 

Пример: У меня на STM32 крутится FTP на 4 клиента, WEB на 8 одновременно передаваемых файла/клиента, 2 потока UDP(RTP) никаких проблем в связке FREERTOS + LWIP.

Share this post


Link to post
Share on other sites
У меня на STM32 крутится FTP на 4 клиента

FTP сами делали и где-то брался готовый, а то я из VxWorks выдирать собрался? Может что-то получше посоветуете?

Share this post


Link to post
Share on other sites
FTP сами делали и где-то брался готовый, а то я из VxWorks выдирать собрался? Может что-то получше посоветуете?

 

Сам делал, исходники где то на форуме выкладывал. http://electronix.ru/forum/index.php?showt...p;#entry1119629

Share this post


Link to post
Share on other sites
Еще вы не уточнили какой камень ?

Камень у меня stm32f207. Изначально взял пример веб сервера с их сайта.

Сделал измнения в файле ethernetif.c :

void ethernetif_input(void * pvParameters)
{
    struct pbuf *p;

    for (;;) {
        if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT) == pdTRUE) {
TRY_GET_NEXT_FRAGMENT:
            p = low_level_input(s_pxNetIf);
            if (p != NULL) {
                if (ERR_OK != s_pxNetIf->input(p, s_pxNetIf)) {
                    pbuf_free(p);
                    p = NULL;
                } else {
                    xSemaphoreTake( s_xSemaphore, 0);
                    goto TRY_GET_NEXT_FRAGMENT;
                }
            } else {
                //PHY buffer is empty, continue to wait for ISR
            }
        }
    }
}

 

static struct pbuf * low_level_input(struct netif *netif) 
{
  struct pbuf *p, *q;
  u16_t len;
  uint32_t l = 0, i = 0;
  FrameTypeDef frame;
  u8 *buffer;
  __IO ETH_DMADESCTypeDef *DMARxNextDesc;
  
  p = NULL;
  
  /* Get received frame */
  frame = ETH_Get_Received_Frame_interrupt();
  
  /* Check if really we have something or not */
  if (frame.descriptor==NULL) return p;
  
  /* check that frame has no error */
  if ((frame.descriptor->Status & ETH_DMARxDesc_ES) == (uint32_t) RESET) 
  {
    
    /* Obtain the size of the packet and put it into the "len" variable. */
    len = frame.length;
    buffer = (u8 *) frame.buffer;
    
    /* We allocate a pbuf chain of pbufs from the pool. */
    p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
    /* Copy received frame from eth....and so on the code under that text remains untouched*/
    
    if (p != NULL)
    { 
      for (q = p; q != NULL; q = q->next)
      {
        memcpy((u8_t*)q->payload, (u8_t*)&buffer[l], q->len);
        l = l + q->len;
      } 
    }
  }
  
  /* Release descriptors to DMA */
  /* Check if received frame with multiple DMA buffer segments */
  if (DMA_RX_FRAME_infos->Seg_Count > 1)
  {
    DMARxNextDesc = DMA_RX_FRAME_infos->FS_Rx_Desc;
  }
  else
  {
    DMARxNextDesc = frame.descriptor;
  }
  
  /* Set Own bit in Rx descriptors: gives the buffers back to DMA */
  for (i=0; i<DMA_RX_FRAME_infos->Seg_Count; i++)
  {  
    DMARxNextDesc->Status = ETH_DMARxDesc_OWN;
    DMARxNextDesc = (ETH_DMADESCTypeDef *)(DMARxNextDesc->Buffer2NextDescAddr);
  }
  
  /* Clear Segment_Count */
  DMA_RX_FRAME_infos->Seg_Count =0;
  
  
  /* When Rx Buffer unavailable flag is set: clear it and resume reception */
  if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)  
  {
    /* Clear RBUS ETHERNET DMA flag */
    ETH->DMASR = ETH_DMASR_RBUS;
    
    /* Resume DMA reception */
    ETH->DMARPDR = 0;
  }  
  
  return p;
}

 

Все эти изменения были описаны на этом же фоуме. Так получается еще что-то надо подправлять?

Share this post


Link to post
Share on other sites

Да да, это тот кривой драйвер, я не стал сильно разбираться в нем, написал свой и больше не знаю проблем.

Share this post


Link to post
Share on other sites

Еще вот такой вопрос. Что вы подразумиваете под драйвером для эзернета?

 

Тут два файла:

 

ethernetif.c

stm32f2x7_eth.с

 

Проблемы только с ethernetif.c или с stm32f2x7_eth.с тоже?

Share this post


Link to post
Share on other sites
Еще вот такой вопрос. Что вы подразумиваете под драйвером для эзернета?

Это тот кусок кода который свяжет аппаратный модуль МАС с LwIP.

 

Где там проблема я не знаю, но она там точно есть. Я писал свой драйвер без использования STM32 библиотеки и заточенного под FREERTOS.

Share this post


Link to post
Share on other sites
Я писал свой драйвер без использования STM32 библиотеки и заточенного под FREERTOS.

 

Тоесть у вас нету таких файлов как ethernetif.c и stm32f2x7_eth.с. Вы сам написали функции инициализации эзернет переферии для stm32 и аналоги функций типа void ethernetif_input( void * pvParameters ) и static struct pbuf * low_level_input(struct netif *netif) для передачи данных в lwip.

 

Используеты ли вы DMA?

 

Не могли бы вы поделиться вашим драйвером в качестве примера?

Share this post


Link to post
Share on other sites
Тоесть у вас нету таких файлов как ethernetif.c и stm32f2x7_eth.с. Вы сам написали функции инициализации эзернет переферии для stm32 и аналоги функций типа void ethernetif_input( void * pvParameters ) и static struct pbuf * low_level_input(struct netif *netif) для передачи данных в lwip.

 

Используеты ли вы DMA?

 

Не могли бы вы поделиться вашим драйвером в качестве примера?

 

Совершенно верно я писал сам, да DMA и прерывания используются. Поделится могу

eth.ZIP

Share this post


Link to post
Share on other sites

Всем доброго! Есть вопрос. Как насчет глюков драйвера, без использования ОС? Запустил пример tcp_echo_server, проект lwIP без операционной системы микроконтроллер stm32f207, создаю подключение с 2-х ПК к одной плате и запускаю обмен по 500 байт каждые 100mS. Спустя 40-50 мин перестает отвечать но под отладчиком видно что tcp_timer вызывается и обработчик прерывания по DMA срабатывает(глубже копнуть нехватает смелости). Если из вашего драйвера убрать код работы с ОС будет работать?

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
Sign in to follow this