WIZnet Developer Forum

[WIZ830MJ] UDP 관련

W5300_Drv_AVR_V1.2.2에 나와 있는 loopback_udp 함수를 사용해서 데이터를 수신하고 있습니다.
PC에서 보내는 데이터의 용량이 500Byte 정도될 경우는 문제없이 수신이 되는데, 1KB이상 넘어가는 경우는 수신이 안됩니다.
아래 예제 소스에 if ((len=getSn_RX_RSR(s)) > 0) 조건문으로 들어가지가 않네요.
버퍼 사이즈를 키워야하는것인지… 그런데 loopback_tcps의 경우는 문제없이 수신이 되는 것으로 봐선 그것도 아닌것 같고…
조언 좀 부탁드립니다… ㅠㅠ

void loopback_udp(SOCKET s, uint16 port, uint8* buf, uint16 mode)
{
uint32 len;
uint8 destip[4];
uint16 destport;

switch(getSn_SSR(s))
{
case SOCK_UDP:
if ((len=getSn_RX_RSR(s)) > 0)
{
len = recvfrom(s,buf,len,destip,&destport);
if (len !=sendto(s,buf,len,destip,destport))
{
--------------------
}
}
break;
case SOCK_CLOSED:
close(s);
socket(s,Sn_MR_UDP,port,mode);
break;
default:
break;
}
}

안녕하세요

UDP mode의 경우 RX_RSR값보다 큰 사이즈의 패킷이 수신될경우
칩에서 패킷을 수신하지 않습니다.
혹시 소켓버퍼 사이즈가 1KB로 설정되어있을경우,
UDP 데이터 1KB 전송시 W5300에서는 헤더사이즈를 포함한 1032Byte가 수신되기 때문에
데이터를 수신하지 않습니다.
혹시 소켓버퍼 사이즈가 몇으로 설정되어있으신가요??

감사합니다.

안녕하십니까,

현재 버퍼 사이즈는 8KB로 설정되어 있습니다.

기본소스로 테스트한 결과 1472바이트까지 수신이 되고, 그 이후는 수신이 안되네요.

W5300_Drv_AVR_V1.2.2보면 디폴트로 8KB로 설정되어 있는 것으로 보이는데, 제가 잘못 이해하고 있는 부분이 있는지요?

이 부분 때문에 다음으로 넘어갈 수가 없네요… 조언 좀 부탁드립니다. ㅜㅜ

w5300.c 에서 sysinit함수는 디폴트로 아래와 같이 사용 중이며, main.c에서

uint8 rx_mem_conf[8] = {8,8,8,8,8,8,8,8};            // for setting RMSR regsiter

if(!sysinit(tx_mem_conf,rx_mem_conf))

{

*        printf*("MEMORY CONFIG ERR.\r\n");

        while(1);

}

위와 같이 8KB로 설정하도록 되어 있네요. 물론 iinchip_conf.h에서 MAX_SOCK_NUM은 8로 설정되어 있습니다.

uint8 sysinit(uint8* tx_size, uint8* rx_size)

{

   uint16 i;

   uint16 ssum=0,rsum=0;

   uint mem_cfg = 0;

   for(i=0; i < MAX_SOCK_NUM; i++)

   {

      if(tx_size[i] > 64)

      {

      #ifdef __DEF_IINCHIP_DBG__

         *printf*("Illegal Channel(%d) TX Memory Size.\r\n",i);

      #endif

         return 0;

      }

      if(rx_size[i] > 64)

      {

      #ifdef __DEF_IINCHIP_DBG__

         *printf*("Illegal Channel(%d) RX Memory Size.\r\n",i);

      #endif

         return 0;

      }

      ssum += (uint16)tx_size[i];

      rsum += (uint16)rx_size[i];

      TXMEM_SIZE[i] = ((uint32)tx_size[i]) << 10;

      RXMEM_SIZE[i] = ((uint32)rx_size[i]) << 10;

   }

   if( (ssum % 8) || ((ssum + rsum) != 128) )

   {

   #ifdef __DEF_IINCHIP_DBG__

      *printf*("Illegal Memory Allocation\r\n");

   #endif

      return 0;

   }

   IINCHIP_WRITE(TMSR0,tx_size[0]);

   IINCHIP_WRITE(TMSR1,tx_size[1]);

   IINCHIP_WRITE(TMSR2,tx_size[2]);

   IINCHIP_WRITE(TMSR3,tx_size[3]);

   IINCHIP_WRITE(TMSR4,tx_size[4]);

   IINCHIP_WRITE(TMSR5,tx_size[5]);

   IINCHIP_WRITE(TMSR6,tx_size[6]);

   IINCHIP_WRITE(TMSR7,tx_size[7]);

   IINCHIP_WRITE(RMSR0,rx_size[0]);

   IINCHIP_WRITE(RMSR1,rx_size[1]);

   IINCHIP_WRITE(RMSR2,rx_size[2]);

   IINCHIP_WRITE(RMSR3,rx_size[3]);

   IINCHIP_WRITE(RMSR4,rx_size[4]);

   IINCHIP_WRITE(RMSR5,rx_size[5]);

   IINCHIP_WRITE(RMSR6,rx_size[6]);

   IINCHIP_WRITE(RMSR7,rx_size[7]);

   for(i=0; i <ssum/8 ; i++)

   {

      mem_cfg <<= 1;

      mem_cfg |= 1;

   }

   IINCHIP_WRITE(MTYPER,(uint8)(mem_cfg >> 8));

   IINCHIP_WRITE(MTYPER1,(uint8)(mem_cfg & 0xff));

   #ifdef __DEF_IINCHIP_DBG__

      *printf*("Total TX Memory Size = %dKB\r\n",ssum);

      *printf*("Total RX Memory Size = %dKB\r\n",rsum);

      *printf*("Ch : TX SIZE : RECV SIZE\r\n");

      *printf*("%02d : %07dKB : %07dKB \r\n", 0, IINCHIP_READ(TMSR0),IINCHIP_READ(RMSR0));

      *printf*("%02d : %07dKB : %07dKB \r\n", 1, IINCHIP_READ(TMSR1),IINCHIP_READ(RMSR1));

      *printf*("%02d : %07dKB : %07dKB \r\n", 2, IINCHIP_READ(TMSR2),IINCHIP_READ(RMSR2));

      *printf*("%02d : %07dKB : %07dKB \r\n", 3, IINCHIP_READ(TMSR3),IINCHIP_READ(RMSR3));

      *printf*("%02d : %07dKB : %07dKB \r\n", 4, IINCHIP_READ(TMSR4),IINCHIP_READ(RMSR4));

      *printf*("%02d : %07dKB : %07dKB \r\n", 5, IINCHIP_READ(TMSR5),IINCHIP_READ(RMSR5));

      *printf*("%02d : %07dKB : %07dKB \r\n", 6, IINCHIP_READ(TMSR6),IINCHIP_READ(RMSR6));

      *printf*("%02d : %07dKB : %07dKB \r\n", 7, IINCHIP_READ(TMSR7),IINCHIP_READ(RMSR7));

      *printf*("\r\nMTYPER=%02x%02x\r\n",IINCHIP_READ(MTYPER0),IINCHIP_READ(MTYPER1));

   #endif

   return 1;

}

추가적으로 여러 문의글 찾아보니, UDP의 경우 최대 수신 용량이 1472바이트까지이며, 넘어갈 경우 자동으로 나눠서 수신되는 것으로 보입니다.

그렇다면 PC에서 W5300쪽으로 2000바이트를 보낼 경우, 수신 시 Loopback 함수의 if((len=getSn_RX_RSR(s)) > 0) 조건 안으로 2번 들어가야 하는 것이 아닌지요?

147바이트가 넘어가면 이 조건안으로 들어가지가 않네요…

제공되는 소스의 어느 부분을 수정해야 할까요…

loopback_tcpc 함수의 경우에는 문제없이 되는데… UDP는 안되네요… ;;

void loopback_udp(SOCKET s, uint16 port, uint8* buf, uint16 mode)

{

           uint32 len;

           uint8 destip[4];

           uint16 destport;

           switch(getSn_SSR(s))

           {

           case SOCK_UDP:

                     if((len=getSn_RX_RSR(s)) > 0)

                     {

                                len = recvfrom(s,buf,len,destip,&destport);

                     }

           break;

           case SOCK_CLOSED:

                     close(s);

                     socket(s,Sn_MR_UDP,port,mode);

                     break;

           default:

                     break;

           }

}

안녕하세요

TCP의 경우 신뢰성있는 통신으로 데이터를 받지 못할경우 재전송하는 알고리즘을 갖고 있기 때문에 UDP의 경우와는 다릅니다.

UDP 표준 규격이 최대 1472Byte이긴 하지만 간혹 규격을 맞추지않고 더 큰 size를 전송하는 경우도 있긴 합니다. 데이터를 전송하는쪽에서 패킷을 자동으로 나눠서 보내주고 있는지, 규격을 무시하고 전송하고 있는지 확인해봐야할 것 같습니다.
Wireshark를 통해 패킷 확인하는게 좋을 것 같습니다.

우선 case SOCK_UDP 부분을 아래의 코드로 변경해보세요

        case SOCK_UDP :
         if((size = getSn_RX_RSR(s)) > 0)
         {
            if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
            ret = recvfrom(s, buf, size, destip, (uint16_t*)&destport);
  여기서 DATA_BUF_SIZE는 2048      로 하시면 될것 같습니다.

한번 테스트해보시고 그래도 제대로 동작하지 않는지 알려주세요

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.