W5300을 사용한 lan통신 프로그램 소스 관련 질문입니다

#1

w5300을 클라이언트로 PC를 서버로 사용하고 있습니다.

PC에서 labview로 제작한 서버 프로그램을 먼저 실행한 후 서버에 전원넣은경우에는

데이터 전송이 잘 되었습니다.

하지만 서버에 전원을 먼저 넣고, PC 서버 프로그램을 실행한 경우

서로 연결(connect)이 안되는 문제가 발생하였습니다.

  1. 제공되는 예제 프로그램에는 반복적으로 서버에 접속을 시도하지 않는것인가요?

아니면 수정해야 하는 부분이 있는것인가요?

프로그램에 브레이크를 걸어가며 확인해 본바

아래 Connect 함수 중 while문에서 빠저나가지 못하여 아래와 같이 while문을 제거 하였습니다.

프로그램을 수정함으로서 1번 문제가 해결되는듯 보였으나

연결이 될 때도 있고, 한참뒤(약2분뒤)에 접속이 되는 것을 확인하였습니다.

uint8 connect(SOCKET s, uint8 * addr, uint16 port)
{

// Connect
ApplySubnet();
setSn_CR(s,Sn_CR_CONNECT);

// while( IINCHIP_READ(Sn_SSR(s)) != SOCK_SYNSENT )
// {
if(IINCHIP_READ(Sn_SSR(s)) == SOCK_ESTABLISHED)
{
// break;
}
//if(getSn_IR(s) & Sn_IR_TIMEOUT) // original
if((getSn_IR(s) & Sn_IR_TIMEOUT) || (getSn_IR(s) & Sn_IR_DISCON))//remaked
{
setSn_IR(s,(Sn_IR_TIMEOUT));
// break;
}
a=getSn_IR(s);
// }
ClearSubnet();
return 1;
}

설정시 timeout은 아래와 같이 설정하였습니다.
setRTR(1000); //time_out : 100ms
setRCR(10);

#2

서버 동작 전에 client가 접속을 요구할 경우 SYN pakcet의 재전송이 발생할 우려가 있습니다.
일반적으로 재전송을 하는 동안 서버가 동작하여 접속을 받아줍니다.
하지만 재전송 인터벌이 길다면 그만큼 늦게 서버가 접속을 받아 줍니다.

//설정시 timeout은 아래와 같이 설정하였습니다.
setRTR(1000); //time_out : 100ms
setRCR(10);

의 설정은 하기와 같은 재전송을 하도록 합니다.
1 재전송 : 0.1s 이후
2 재전송 : 0.2s 이후
3 재전송 : 0.4s 이후
4 재전송 : 0.8s 이후
5 재전송 : 1.6s 이후
6 재전송 : 3.2s 이후
7 재전송 : 6.4s 이후
8 재전송 : 12.8s 이후
9 재전송 : 25.8s 이후
10 재전송 : 51.2s 이후
11 재전송 : 102.4s 이후

Timeout : 204.5s <-- 이 시간 이후 Sn_IR_TMEOUT 설정됨.

서버가 언제 동작할지 모르는 상황이라면
RTR와 RCR 값을 적당한 값을 설정하셔야 합니다. RCR값을 5 정도로 설정하시면 1.6s 이후 Timeout 발생하고 Socket은 Close 됩니다.
Client Example 처럼 socket이 close될 경우 socket을 재open하고 다시 connect()를 시도하면,
매 1.6s 마다 서버 접속을 시도합니다.

#3

전번에 제가 질문을 잘못드린것 같아 다시 질문드립니다.

w5300을 클라이언트로 PC를 서버로 사용하고 있습니다. MCU로는 DSP(TMS320C28346)를 사용하고 있습니다.

PC에서 서버 프로그램을 먼저 실행한 후 클라이언트(w5300)를 동작시키는 경우에는 데이터 전송이 잘 됩니다.

데이터 전송중에 PC 서버 프로그램을 종료 후 다시 동작시킨 경우

서로 연결(connect)이 안되는 문제가 발생하였습니다.

코딩한 프로그램에 브레이크를 걸어가며 확인해 보니

아래 Connect 함수 중 while문에서 빠져나가지 못하고 있었습니다.

uint8 connect(SOCKET s, uint8 * addr, uint16 port)
{

// Connect
ApplySubnet();
setSn_CR(s,Sn_CR_CONNECT);

while( IINCHIP_READ(Sn_SSR(s)) != SOCK_SYNSENT )
{
if(IINCHIP_READ(Sn_SSR(s)) == SOCK_ESTABLISHED)
{
break;
}
if(getSn_IR(s) & Sn_IR_TIMEOUT) // original
{
setSn_IR(s,(Sn_IR_TIMEOUT));
break;
}
ClearSubnet();
return 1;
}

  1. 서버와 연결이 끊기면 설정된 Time_out시간이 지나면 break되어 while문을 빠져나오는 것이 아닌가요?

설정시 timeout은 아래와 같이 설정하였고, 약3분가량 기다렸으나 while문을 빠져나오지 않았습니다.
setRTR(14);
setRCR(8);

  1. timeout관련 설정은 위의 두가지만 (setRTR(14); setRCR(8); ) 하였는데,

이 외에 timeout관련 레지스터를 설정해야 하나요?

  1. getSn_SSR(s) 값이 0x10인 경우에는 w5300자체를 리셋해주어야 하나요?
#4

위에 질문드린 3번에 관해 추가 질문드립니다.

Sn_SSR이 0x10에서 변하지 않는 내용에 관한문제가 "erratum1"인것으로 보이는데

이미 제공된 예제의 Close()함수에 이 내용이 들어가 있는 것을 보입니다.

if(loop_cnt++ > 10)
{
uint8 destip[4];
// M_11252008 : modify dest ip address
//getSIPR(destip);
destip[0] = 0;destip[1] = 0;destip[2] = 0;destip[3] = 1;
socket(s,Sn_MR_UDP,0x3000,0);
sendto(s,(uint8*)“x”,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
break; // M_11252008 : added break statement
}

그런데도 0x10을 계속 유지하는데,

원인 및 해결책이 따로 있을 까요?

#5

[quote]1. 서버와 연결이 끊기면 설정된 Time_out시간이 지나면 break되어 while문을 빠져나오는 것이 아닌가요?

설정시 timeout은 아래와 같이 설정하였고, 약3분가량 기다렸으나 while문을 빠져나오지 않았습니다.
setRTR(14);
setRCR(8);
[/quote]
이론적으로 보면 1.4ms(1st) + 2.8ms(2nd) + 3.6ms(3rd) + 7.2ms(4th) + 14.4ms(5th) + 28.4ms(6th) + 56.8ms(7th) + 103.6ms(8th) + 204.2ms(9th) = 4214ms 이후에 타임아웃이 발생하여 합니다.
Timeout이 발생하지 않을 경우는 패킷이 재전송중이 아닐 가능성이 큽니다. 이부분은 Wireshark로 분석해봐야지 정확한 분석이 가능합니다. Ack를 수신하지 못한 패킷이 4.2s 동안 재전송이 일어나지 않는 경우는 비정상적인 동작입니다. 가능하시면 패킷을 캡쳐하셔서 보내주세요.

이외에 설정은 필요없습니다. 다만 RTR과 RCR은 전체 Socket에 영향을 주므로 설정 전에 다른 socket에 영향을 주지 않느지 고려하셔야 합니다.

제일 확실한 방법은 Reset을 해주는 것이 좋습니다. 하지만 Erratum 1에 명시되어 있는 것 처럼.
강제로 타임아웃을 발생시킬 경우 해당 문제는 해결이 됩니다.

질문에 close에 적용된 Erratum 을 실행해도 계속 그 0x10으로 남겨져 있다고 하셨는데, sendto return이 Timeout 을 발생시키는지 다시 한번 확인 부탁드립니다.

#6

패킷을 캡처하여 올립니다.

w5300의 ip는 192.168.0.230입니다.

서버를 먼저 동작시킨 후에 클라이언트(w5300)을 동작시켰습니다.

그 결과 데이터 전송이 잘 이뤄지는 것을 확인하였습니다.

그 후 서버를 off하였을 때 빨간색으로 재전송이 9번 시도되는 것으로 보여지는 것을 확인하였습니다.

하지만 그 이후로는 아무런 변화도 없었습니다.

서버를 다시 on 시킨뒤에도 마찬가지 였습니다.

프로그램에 브레이크를 걸어 다시 확인해 봤더니

위에서 질문드렸던 내용중에서 처럼 while문을 계속돌고 있었습니다.

이때의 Sn_SSR값은 0x10이고, Sn_IR값 역시 0x10이 었습니다.

제가 통신쪽은 초보라 많이 부족합니다.

검토 부탁드립니다.

#7

패킷을 세밀히 분석한 후 Post 해드리겠습니다.