보드 하나에 W5500 2개를 이용 내부, 외부 통신

안녕하세요

패킷이 처음부터 캡쳐가 안되고 짤린것 같습니다.
보내주신 패킷상태로는 정상동작으로 보이고
소켓상태가 0x17이여야하는것이 맞습니다.

패킷과 같이 데이터가 오가는중에도 스테이터스 값이 0x15를 유지하나요?

발열관련해서는 여쭈어봤는데 그당시 회로상으로는 특별한 이상은 발견하지 못해서

WIZ850io를 제공했었다고 하시네요

혹시 WIZ850io로 테스트 해보셨나요?

패킷.zip (971.8 KB)

패킷과 같이 데이터가 오가는 중에도 0x15 로 유지 합니다.

안녕하세요

ESTABLISHED상태에서는 데이터 송수신을 할 수 없게 구현되어있습니다.
상태레지스터를 읽어오는 부분 코드 보여주시면 확인해드리겠습니다.

switch(get_state=getSn_SR(sNum))
{

  		case SOCK_CLOSED:
  			if(socket(sNum, Sn_MR_TCP, sPort, 0x00) != sNum)
  			{

#ifdef DBG_ON
printf(“%d : TCP Server Start Fail (sPort %d)\r\n”, sNum, sPort);
#endif
return -2;
}

  			//printf("%d : TCP Server Start (sPort %d)\r\n", sNum, sPort);

  			setSn_KPALVTR(sNum, 1);	// Keep Alive 5Sec

  			break;
  		case SOCK_INIT :
  			if(connect(0,IP_SET,sPort)!= SOCK_OK)
  			{

#ifdef DBG_ON
printf(“%d : TCP Server Listen Fail (sPort %d)\r\n”, sNum, sPort);
#endif
return -3;
}

#ifdef DBG_ON
printf(“%d : TCP Server Listen (sPort %d)\r\n”, sNum, sPort);
#endif

  			break;
  		case SOCK_ESTABLISHED:
  			if(getSn_IR(sNum) & Sn_IR_CON)
  			{
  				setSn_IR(sNum, Sn_IR_CON);

#ifdef DBG_ON
uint8_t dIp[4];
uint16_t dPort;

  				//getSn_DIPR(sNum, dIp);
  				//dPort = getSn_DPORT(sNum);


  				printf("%d : Connected - %d.%d.%d.%d (dPort %d)\r\n",sNum, dIp[0], dIp[1], dIp[2], dIp[3], dPort);

#endif

  				return 1;
  			}
  			break;
  	}

// }
}

return 1;

입니다.

패킷상에서는 W5500이 데이터를 전송하는 것으로 보이는데
코드상에서는 send하는 부분이 보이지 않습니다.
데이터 전송은 어디서 하고있는건가요??

상태레지스터가 계속 0x15라고 하신 뜻은
case문이 SOCK_ESTABLISEHED로 들어오지않는다는 말이신가요??

이부분은 디버깅으로 출력되시나요?

SOCK_ESTABLISEHED 이쪽으로 들어가지가 않군요…

어떻게 이럴수가 있는건지…

그리고

int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
{
   CHECK_SOCKNUM();
   CHECK_SOCKMODE(Sn_MR_TCP);
   CHECK_SOCKINIT();
   //M20140501 : For avoiding fatal error on memory align mismatched
   //if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
   {
      uint32_t taddr;
      taddr = ((uint32_t)addr[0] & 0x000000FF);
      taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
      taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
      taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
      if( taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID;
   }
   //
	
	if(port == 0) return SOCKERR_PORTZERO;
	setSn_DIPR(sn,addr);
	setSn_DPORT(sn,port);
	setSn_CR(sn,Sn_CR_CONNECT);
    while(getSn_CR(sn)); //67
   if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
 /*  
   while(getSn_SR(sn) != SOCK_ESTABLISHED)
   {
		if (getSn_IR(sn) & Sn_IR_TIMEOUT)
		{
			setSn_IR(sn, Sn_IR_TIMEOUT);
            return SOCKERR_TIMEOUT;
		}

		if (getSn_SR(sn) == SOCK_CLOSED)
		{
			return SOCKERR_SOCKCLOSED;
		}
	}
  */
   return SOCK_OK;

이 함수에 while 문 주석처리 안하면 계속 리셋 됩니다.
그래서 주석처리 했구요 ,

도대체 무엇이 문제 인지ㅜㅜ…

안녕하세요

위에서도 말씀드렸지만 패킷상에서는 W5500이 데이터를 전송하고있는데 전송은 어디서 하고있는건가요??
패킷도 칩과 connection 과정 하는 부분에대한 부분이 없습니다
다시 캡쳐 부탁드립니다.

이해가 가지 않습니다만 소캣오픈 안에 있는 while 문 주석처리 한걸 다시 풀었는데 상태값이 나옵니다
위즈넷에서 라아브러리에는 while 문이 없문대요 …

어렵군요 하나 해결하면 또 나오고 ㅜㅜ

안녕하세요

우선 data send하는 함수를 return 1; 위로 넣는걸로 수정해주세요

sssssss.zip (2.2 MB)

TCP Retransmission 뜨는 이유가 timeout 이 짧아서 그런가요 ?

안녕하세요

패킷을 확인해봤는데 여러번의 TCP 통신이 묶여있네요

혹시 문제가 되셨던 통신의 TCP Server. Client IP 주소와 네트워크 환경(TCP Server와 Client를 어떻게 구현하셨는지, 하드웨어적으로 어떻게 연결하셨는지 등)을 알 수 있을까요?

TCP server 192.168.1.150 입니다.
Client IP 192.168.1.211 입니다
네트워크 환경? TCP server는 PLC 며 중간에 허브를 통해 Client (저의 보드)를 통해 상호 통신을 합니다.
중간 허브에 PC를 연결하여 와이어샤크로 캡쳐 하였습니다.
여러번 통신이 묶여 있다는게 어떤 말씀이신지요?

Sn_SR 가 0x15라는 것은 SYN 패킷을 보낸상태이고, 아직SYN+ACK를 받지 못한 상태입니다.
그렇기 때문에 ESTABLISHED상태로 들어가지 않는것입니다,

w5500 이상현상에 관련된 리스트 입니다.

  1. send 함수 안에

while(1){

freesize=getSn_tx_FSR;

if( len<=fressize) break;

}

fressize 값 2048 <-> 2001 1~2초 반복, 후 1~2초 가 지난 후 fressize 0 가 됨 즉. len 값보다 작아 break 가 안됩니다.

  1. 저의 보드에 값을 증가 지속 함, PLC GX work2 메모리에 보면 초기 증가함, 하지만 5초 정도 지나면 증가하지 않고 GX work2 또한 느려집니다.
    그리고 5초 정도 지나면 메모리에 증가 값이 확 증가하며 GX work2 도 잘 작동합니다.
    이런식으로 반복합니다.
    1_PLC로 테스트 시 패킷 정보 파일첨부
    2_PC로 테스트 시 패킷 정보 파일첨부Desktop.zip (458.4 KB)

  2. PC(이더넷 테스트 프로그램 ) 으로 실행시키면 1, 2번 과 같은 현상은 없습니다.

  3. /*
    while(getSn_SR(sn) != SOCK_ESTABLISHED)
    {
    if (getSn_IR(sn) & Sn_IR_TIMEOUT)
    {
    setSn_IR(sn, Sn_IR_TIMEOUT);
    return SOCKERR_TIMEOUT;
    }

      if (getSn_SR(sn) == SOCK_CLOSED)
      {
          return SOCKERR_SOCKCLOSED;
      }
    

    }
    */

이 부분을 주석처리 안하면 와치독 발생
주석처리 시 와치독 없음
제가 timeout 을 4000, retry_cnt 1 설정 하였습니다.
하지만 계속 와치독 발생 입니다.
이상합니다.

안녕하세요 답변이 늦었습니다.

  1. freesize는 sock이 전송할 수 있는 버퍼가 남아있냐는 것을 의미합니다. freesize가 0인 것은 이전 send data가 아직 전송되지 않거나 버퍼가 꽉 차있다는 의미입니다.
    그리고 아래의 코드가 저희가 제공하는 라이브러리의 코드입니다.
    보시면 while안에서 확인하지 않고 break로 나오지 않습니다.
    코드가 저희가 제공하는 라이브러리와 맞는지 다시한번 확인해주세요

image

  1. PLC 패킷을 확인해봤습니다만 의문이 드는게 있습니다.
    PC패킷의 경우 210에서 150으로 47byte의 데이터를 지속적으로 전송합니다.
    그러나 PLC의 경우 그렇지 않습니다.
    아래 그림에 보시면 150의 ACK가 지속적으로 증가합니다. 그뜻은 210에서 94byte를 지속적으로 전송합니다.

    그리고 여기서 부터는 150이 11byte의 데이터를 지속적으로 전송하면서 이제는 210으로 부터 47byte의 데이터를 받기 시작합니다.

그리고 이때부터는 다시 150이 데이터를 받기만 합니다.


마지막으로 수신만 하던 150은 버퍼 사이즈가 없어서 알림메시지만 지속적으로 보냅니다.

결과적으로 PC패킷과 PLC패킷의 동작은 전혀 다른 동작을 수행하고 있습니다.
이부분에 대한 정확한 설명이 필요해보입니다.

  1. 2번과 동일하게 현재 PC와 PLC와는 서로 다른 동작을 하고 있는 듯 보입니다.

  2. retry_cnt를 증가시켜주세요 1은 재전송이 한번이라도 발생하면 바로 TIMEOUT이 발생합니다.

감사합니다

답변 주셔서 감사합니다.

  1. while(1)
    {
    freesize = getSn_TX_FSR(sn);
    tmp = getSn_SR(sn);
    if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
    {
    socketclose(sn);
    return SOCKERR_SOCKSTATUS;
    }
    if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
    if(len <= freesize) break; 이부분 에 있습니다.
    }

  2. PC와 PLC 서로 다른 동작을 하고 있는건 알고 있습니다.
    PC와 w5500 바로 연결 하였으며 테스트 프로그램은 SerialPortMon 이라는 프로그램을 사용하고 있습니다.
    PLC 는 허브로 연결, w5500 또한 허브로 연결 , PC 또한 허브로 연결 하였습니다. 그리고 와어샤크로 패킷정보
    를 보았습니다.

여기 참조하시면 됩니다.

참고로 위의 라이브러리라 공식적인 최종 라이브러리입니다.

혹시 함수의 지속적인 오류가 있으시면 위의 라이브러리로 교체하시는걸 추천드립니다

감사합니다

해당 내용은 위의 코드에서 send() 함수를 참조하시면 됩니다.