реклама на сайте
подробности

 
 
> lwip 1.4.0 и несколько потоков, Возможна ли стабильная работа lwip на несколько потоков?
Kalyan
сообщение Dec 28 2012, 13:52
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 108
Регистрация: 4-11-10
Пользователь №: 60 656



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

Я провожу следующий эксперемент:
Использую HTTP сервер. На нем крутится один сайт с java. То есть, браузер несколько раз в секунду аякс запросами запрашивает данные с сервера.
Использую HTTP клиент, который тоже несколько раз в секунду в считывает данные с одного девайса.
Вот у меня тут получается два потока.

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

Может просто надо сделать так, чтобы пока работает HTTP сервер, HTTP клиент ждал и не устанавливал никаких подключений. Но как это сделать? На ум прихрдят только критические секции и приостановка шедуллера. Может для этого есть возможности в самом lwip?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Kalyan
сообщение Jan 2 2013, 07:35
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 108
Регистрация: 4-11-10
Пользователь №: 60 656



Цитата
Еще вы не уточнили какой камень ?

Камень у меня 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;
}


Все эти изменения были описаны на этом же фоуме. Так получается еще что-то надо подправлять?
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 30th July 2025 - 16:37
Рейтинг@Mail.ru


Страница сгенерированна за 0.01365 секунд с 7
ELECTRONIX ©2004-2016