WIZnet Developer Forum

Ping과 소켓 연결 질문 드립니다

정말 자주 질문드려서 죄송합니다… 한달이 넘도록 하고있는데 진도는 안나가고 별짓 다해봐도 성과가 없으니 답답해서 계속 질문만 드리게 되네요
소스는 nexp.tistory.com/365 이거랑
W5100_Driver_V180(0)을 참고하였습니다.

이제 랜선을 연결하면 W5100에 연결되어있는 LED들도 깜빡이고 SPI로 설정한 IP,Gateway, Sub net, MAC 를 Get 000 함수를 이용해서 읽어본 결과 설정값과 같았습니다.

그런데 PIng을 날려도 응답이 없고 PC에서 접속을 해도 실패하고

아래 소스가 메인문 중 While에서 계속 돌고 있습니다. 그런데 SOCK_CLOSE 상태만 계속 되더군요,

1 . midnightcow.tistory.com/entry/io … -100-활용하기2 여기 글을 보면 Error code를 볼수 있는거 같은데 그거는 어떻게 확인 할수 있는건가요?

  1. Ping 테스트를 할려면 별도의 소스가 더 필요한가요?

  2. 서버 모드에서 SOCK_ESTABLISHED는 클라이언트가 접속을 해야지 들어오는건가요?

switch (getSn_SR(SOCK_TCPS))
{
case SOCK_ESTABLISHED:
//데이터 수신 검사
if((len = getSn_RX_RSR(SOCK_TCPS)) > 0)
{
//if Rx data size is lager than TX_RX_MAX_BUF_SIZE
if (len > TX_RX_MAX_BUF_SIZE) len = TX_RX_MAX_BUF_SIZE;

		//데이터 수신
		len = recv(SOCK_TCPS, data_buf, len);			
		GR_LED = 1;
		WH_LED = 0;
		RE_LED = 0;
		// send the received data 
		//send(SOCK_MYTEST, data_buf, len);				

		EthernetTest(data_buf, len);
	}		
	break;
	
case SOCK_CLOSE_WAIT:                           		
	//If the client request to close
	disconnect(SOCK_TCPS);
	GR_LED = 0;
	WH_LED = 1;
	RE_LED = 0;
	m_SokStatus1 = 0;
	break;
	
case SOCK_CLOSED:
	if(!m_SokStatus1) 
	{
		m_SokStatus1 = 1;
	}

	GR_LED = 0;
	WH_LED = 0;
	RE_LED = 1;
	//reinitialize the socket 
	if(socket(SOCK_TCPS,Sn_MR_TCP, port,0x00) == 0)
	{
	//	DebugPrint("Fail to create socket.");
		m_SokStatus1 = 0;
	}
	else
	{
		listen(SOCK_TCPS);
	}
	
	break;
}

안녕하세요.

저희 github에 있는 Loopback 소스를 첨부드릴테니 비교 부탁드립니다.

github.com/Wiznet/ioLibrary_Driver

저희 칩은 하드웨어 적으로 State를 나타내어 상태가 변경됩니다.

그래서 올리신 소스를 보면 Sock_Closed에서 socket 생성 후 Sock_init으로 넘어가야하는 코드가 있어야하는데,

그 코드가 없기 때문에 에러가 발생한 것으로 보입니다.

저희 loopback 코드와 datasheet를 참고해주세요.

  1. Error코드를 보신거 같은데, 이 경우는 일부러 확인보다는 나중에 코딩 하셨을 때 나오는 Error와 비교 분석 하는 용도로 확인해주시면 될 것 같습니다.

  2. ping 테스트라는 것 자체가 H/W적으로 PHY 연결이 성사되었을 경우에 가능한 것입니다. 이 경우는 네트워크에 정상적으로 PHY가 연결되었을 경우 Ping이 되는 것이니 소스보단 설정을 정상적으로 하셨는지 확인이 필요합니다. ex) IP setting, LAN cable을 정상적으로 연결했나 등

  3. SOCK_ESTABLISHED는 클라이언트와의 Connection이 되었을 경우 발생합니다. 위 설명한바와 같이 코드를 다시 확인해주세요.

감사합니다.

그렇군요 감사합니다.
일단 더 테스트를 해보겠습니다.

혹시 ping 테스트를 하기 위해서 설정해야 하는 단계와
소켓 init의 단계를 알수 있을까요?

알려주신 자료를 보고 테스트를 계속 해보겠습니다. 매번 도와주셔서 감사합니다.

아 그리고 일단 ping 테스트가 되야 서버든 클라이언트든 TCP모드로 동작 시킬수 있는것이 맞는거죠?

네 맞습니다.

ping이 되야 PHY가 정상 연결이 된 것입니다.

ping은 H/W로 연결이 되면 되야 정상입니다.

ping이 되기 위해서는 LAN Cable을 모듈과 연결 시 Ethernet LED가 한쪽은 켜져있는 상태로, 다른 한쪽은 점등되는 상태로 되야 정상동작하는 상태입니다.

일단 이 상태까지만 되면 ping이 되야하는데, 만약에 되지 않는다면 IP도 같은 대역으로 맞춰서 한번 해보시길 바랍니다.

소켓 init 단계는 W5100 Datasheet에 있습니다.

wiznet.co.kr/wp-content/uplo … v1.2.6.pdf

27page 확인바랍니다.

그리고 Datasheet와 Loopback 예제코드랑 비교하시면서 보셔야 쉽게 이해되십니다.

감사합니다.

네 감사합니다. 이제 ping 문제도 해결되었고 소켓 접속과 종료까지는 되고 받는 데이터를 그대로 UART로 쏘게 했는데요 아마 데이터 사이즈 많큼 다 보내는것 같습니다. 그리고 이 뒤에는 소켓 접속 하고 종료도 잘 되고 그러는데 데이터는 쓰레기 값이 계속 올라옵니다.
제가 보내는 데이터는 "1"인데 FC 든 A0 든 이런 쓰레기값을 계속 보내는거 같습니다. 보내는 데이터를 바꿔도 같은값이 올라올때도 있고요…

MCU가 쓰레기값을 보내는동안 SPI 통신에서 MOSI와 MISO핀에서도 일정한 데이터가 계속 올라오고 그럽니다.
아마 MCU에서 보내서 그런거 같은데 RCR 레지스터를 수동으로 클리어 해줘야 하나요?

void InitWiznet(void)
{
u8 gw[4], sn[4], sip[4];
u8 mac[6];
#if (DEF_IINCHIP_BUS == DEF_IINCHIP_SPI_MODE)
//SPI Initialize

IINCHIP_SpiInit();

IINCHIP_CSInit();
IINCHIP_CSon();

#endif  

getSHAR(mac);
getGAR(gw);  getSUBR(sn);  getSIPR(sip);
setMR(MR_RST);
IINCHIP_READ(MR);

setSHAR(mac);
setGAR(gw);
setSUBR(sn);
setSIPR(sip);

sysinit(0x55, 0x55);

}

void sysinit(
uint8 tx_size, /< tx_size Tx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte) */
uint8 rx_size /
< rx_size Rx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte) */
)
{
int16 i;
int16 ssum,rsum;

#ifdef DEF_IINCHIP_DBG
printf(“sysinit()\r\n”);
#endif

ssum = 0;
rsum = 0;

IINCHIP_WRITE(TMSR,tx_size); /* Set Tx memory size for each channel */
IINCHIP_WRITE(RMSR,rx_size);	 /* Set Rx memory size for each channel */

SBUFBASEADDRESS[0] = (uint16)(__DEF_IINCHIP_MAP_TXBUF__);		/* Set base address of Tx memory for channel #0 */
RBUFBASEADDRESS[0] = (uint16)(__DEF_IINCHIP_MAP_RXBUF__);		/* Set base address of Rx memory for channel #0 */

#ifdef DEF_IINCHIP_DBG
printf(“Channel : SEND MEM SIZE : RECV MEM SIZE\r\n”);
#endif

for (i = 0 ; i < MAX_SOCK_NUM; i++) // Set the size, masking and base address of Tx & Rx memory by each channel
{
SSIZE[i] = (int16)(0);
RSIZE[i] = (int16)(0);
if (ssum < 8192)
{
switch((tx_size >> i2) & 0x03) // Set Tx memory size
{
case 0:
SSIZE[i] = (int16)(1024);
SMASK[i] = (uint16)(0x07FF);
break;
case 1:
SSIZE[i] = (int16)(2048);
SMASK[i] = (uint16)(0x07FF);
break;
case 2:
SSIZE[i] = (int16)(4096);
SMASK[i] = (uint16)(0x07FF);
break;
case 3:
SSIZE[i] = (int16)(8192);
SMASK[i] = (uint16)(0x07FF);
break;
}
}
if (rsum < 8192)
{
switch((rx_size >> i
2) & 0x03) // Set Rx memory size
{
case 0:
RSIZE[i] = (int16)(1024);
RMASK[i] = (uint16)(0x07FF);
break;
case 1:
RSIZE[i] = (int16)(2048);
RMASK[i] = (uint16)(0x07FF);
break;
case 2:
RSIZE[i] = (int16)(4096);
RMASK[i] = (uint16)(0x07FF);
break;
case 3:
RSIZE[i] = (int16)(8192);
RMASK[i] = (uint16)(0x07FF);
break;
}
}
ssum += SSIZE[i];
rsum += RSIZE[i];

  if (i != 0)             // Sets base address of Tx and Rx memory for channel #1,#2,#3
	{
		SBUFBASEADDRESS[i] = SBUFBASEADDRESS[i-1] + SSIZE[i-1];
		RBUFBASEADDRESS[i] = RBUFBASEADDRESS[i-1] + RSIZE[i-1];
	}

#ifdef DEF_IINCHIP_DBG
printf("%d : %.4x : %.4x : %.4x : %.4x\r\n", i, (uint16)SBUFBASEADDRESS[i], (uint16)RBUFBASEADDRESS[i], SSIZE[i], RSIZE[i]);
#endif
}
}

void ProcessTcpSever(void)
{
int32_t ret;
uint16_t size = 0, sentsize=0;
u8 text5[20] = " ";
int len;
unsigned char data_buf[TX_RX_MAX_BUF_SIZE];
unsigned int port = MY_LISTEN_PORT;

switch(getSn_SR(SOCK_TCPS))
{
	case SOCK_ESTABLISHED :
		if(getSn_IR(SOCK_TCPS) & Sn_IR_CON)
		{
			GR_LED = 1;
			IINCHIP_WRITE(Sn_IR(SOCK_TCPS),Sn_IR_CON);
		}
		if((size = getSn_RX_RSR(SOCK_TCPS)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur.
		{
			if(size > TX_RX_MAX_BUF_SIZE) size = TX_RX_MAX_BUF_SIZE;
			ret = recv(SOCK_TCPS,data_buf, size);

			//if(data_buf[0] == 0xDA) WH_LED ^= 1;
			//else RE_LED ^= 1;
			
			//if(ret <= 0) return ret;      // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.
			sentsize = 0;	

/*
if(RE_LED == 1)
{
sprintf(text5,"%d %d",data_buf[0],data_buf[1]);
LCD_Display(7,text5,0,0,0,0,1);
Deletestr(text5,text5,0,strlen(text5));
RE_LED = 0;
}
*/ UART0_PUT_BYTE(data_buf[0]);
while(size != sentsize)
{
ret = send(SOCK_TCPS, data_buf+sentsize, size-sentsize);
if(ret < 0)
{
close(SOCK_TCPS);
// return ret;
}
sentsize += ret; // Don’t care SOCKERR_BUSY, because it is zero.
}
//RE_LED = 1;
//UART0_PUT_BYTE(size >> 8);
//UART0_PUT_BYTE(size & 0x00FF);
}
break;

	case SOCK_CLOSE_WAIT :
		disconnect(SOCK_TCPS);
	//	RE_LED =1; //return ret;
		break;
		
	case SOCK_INIT :
		ret = listen(SOCK_TCPS);
	//	WH_LED =1;
		break;
		
	case SOCK_CLOSED:
		ret = socket(SOCK_TCPS, Sn_MR_TCP, port, 0x00);
		//GR_LED =0;
		//RE_LED = 1;
		break;
		
	default:
		break;
}

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