[INTERFACE]/AVR_W5100_EVM2008. 5. 25. 23:44

[Mega128 EVM] 이더넷 테스트 - TCP Server

[Mega128 EVM] 이더넷 테스트 - TCP Server

사용자 삽입 이미지


W5100, Atmega128  TCP Server 예제



[Mega128 EVM]에서 W5100제어는 direct, indirect, spi방식으로 제어 가능하고 J7 점퍼 설정으로 설정 가능하다.
소프트웨어에서 설정은 \01_drv\wiznet\mcu\types.h 에서 설정할 수 있다.


#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_DIRECT_MODE__
//#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_INDIRECT_MODE__
//#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_SPI_MODE__
    /*Enable SPI_mode*/



TCP서버의 일은 통신의 종단점을 설정해 놓고 클라이언트로 부터 연결 요구를 수동적으로 기다리는 것이다.
TCP로 서버로서 데이터를 송수신 하기 위한 절차는 아래와 같다.
1) NetInit()함수로 W5100초기화
2) socket()함수로 서버 설정
3) listen()함수로 클라이언트의 접속을 대기
4) 접속이 이루어 지면 recv(), send()함수로 데이터 송수신
 
 
 
 
1)최기화
먼저 W5100을 초기화 하기 위해 NetInit()함수에서 iinchip_init() 설정 초기화 및 MAC, IP, Sub NET, Gateway등을 설정하면 된다. 아주 간단히 W5100의 레지스터에 값을 설정하는 것 만으로 네트웍 초기화가 되고 ping테스트가 된다.
//-----------------------------------------------------------------------------
void NetInit(void)
{
	unsigned char mac[6]	= MY_NET_MAC;
	unsigned char sm[4]	= MY_SUBNET;
	unsigned char gwip[4]	= MY_NET_GWIP;

	//W5100 Chip Init
	iinchip_init();

	//Set MAC Address
	setSHAR(mac);

	//Set Gateway
	setGAR(gwip);

	//Set Subnet Mask
	setSUBR(sm);

	//Set My IP
	setSIPR(m_sip);
	
#ifdef __DEF_IINCHIP_INT__
	setIMR(0xEF);
#endif
	
	sysinit(MY_NET_MEMALLOC, MY_NET_MEMALLOC);
}
//-----------------------------------------------------------------------------


2)서버 설정
서버모드는 클라이언트 모드와 거의 유사하지만 socket()함수로 소켓을 생성한 후 listen()함수로
서버로부터 접속을 기다리게 된다.
//----------------------------------------------------------------------------- //Initialize socket - 서버 모드로 소켓 초기화 unsigned char InitSocketServer(unsigned int Socket, unsigned Port) { //initialize the socket if(socket(Socket,Sn_MR_TCP, Port,0x20) == 0) { DebugPrint("Fail to create socket."); return 0; } else { listen(Socket); } return 1; }

 
3)접속후 데이터 송수신 
데이터 수신은 접속후 getSn_SR(SOCK_TCPS)함수로 소켓의 상태를 체크하다 SOCK_ESTABLISHED상태,
즉 서버에 연결된 상태가 되었을때 getSn_RX_RSR()함수로 수신된 데이터가 있으면
recv()함수로 데이터를 수신할 수 있다.
클라이언트에 의해 접속 종료 요청이 오면 SOCK_CLOSE_WAIT 상태가 되고 disconnect()함수로 연결을 종료 할 수 있다.
이후 TCP상태는 SOCK_CLOSED가 되고 InitSocketServer()함수를 이용하여
다시 소켓을 초기화 해서 서버로 접속을 대기할 수 있다.












//-----------------------------------------------------------------------------
//수신데이터 처리 void EthernetTest(unsigned char *pRcvBuffer, unsigned int len) { unsigned int i; DebugPrint("Read Data[%d]\r\n", len); for(i=0;i<len;i++) { //if(i%16==0)DebugPrint("\r\n"); DebugPrint("%02X ", pRcvBuffer[i]); } DebugPrint("\r\nReceive OK!\r\n"); } //TCP-Server 처리 void ProcessTcpSever(void) { int len; unsigned char data_buf[TX_RX_MAX_BUF_SIZE]; uint16 port = MY_LISTEN_PORT; switch (getSn_SR(SOCK_TCPS)) { case SOCK_ESTABLISHED: //check Rx data 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; //read the received data len = recv(SOCK_TCPS, data_buf, len); //send the received data - loop back test send(SOCK_TCPS, data_buf, len); EthernetTest(data_buf, len); } break; case SOCK_CLOSE_WAIT: //If the client request to close disconnect(SOCK_TCPS); break; case SOCK_CLOSED: //if a socket is closed //reinitialize the socket InitSocketServer(SOCK_TCPS, port); break; } } //-----------------------------------------------------------------------------

 
테스트
Client는 PC프로그램 으로 하고 예전에 작성했던 TCP Server/Client Host Program(VC++) 예제 프로그램으로 테스트 한다. EthernetHost.exe

프로그램을 실행하고 Client모드로 설정하고 Port, IP설정후 Connect를 하면 접속된다.



서버에 접속후 원하는 데이터를 전송하면 시리얼 창에 전송된 데이터가 출력되는것을 확인 할 수 있다.







 
[Atmega128 EVM] W5100 TCP/IP Server 예제 소스코드

//=============================================================================
// Mega128 EVM Module Test Program
// by nexp76(nexp76@naver.com) http://cafe.naver.com/elab
// [tcps1.c]
//=============================================================================

/*
 - [W5100] EVM Tcp Server Test Program
 - MY_LISTEN_PORT(5000)로 접속 대기하여 수신한 데이터 시리얼로 표시 예제
*/

#include "..\00_hal\system.h"
#include "..\01_drv\serial.h"

#include "../01_drv/wiznet/mcu/types.h"
#include "../01_drv/wiznet/iinchip/w5100.h"
#include "../01_drv/wiznet/iinchip/socket.h"
#include "../01_drv/wiznet/iinchip/wiznet.h"


//-----------------------------------------------------------------------------
#define MY_NET_MAC			{0x00, 0x08, 0xdc, 0x00, 0x00, 0x00}	// MY Mac Address : 00.08.DC.00.00.00

#define MY_NET_GWIP		{192,  168, 0,    1}	// MY Gateway IP    : 192.168.0.1
#define MY_DESTINATIONIP		{192,  168, 0,  154}	// MY Destination   : 192.168.0.154
#define MY_SOURCEIP		{193,  168, 0,  100}	// MY Source IP     : 192.168.0.100
#define MY_SUBNET			{255, 255, 255,   0}

#define MY_NET_MEMALLOC		0x55					// MY iinchip memory allocation

#define MY_LISTEN_PORT		5000					// MY Listen Port  : 5000 
#define MY_CONNECT_PORT		3000					// MY Connect Port : 3000

#define TX_RX_MAX_BUF_SIZE	1024
#define SOCK_TCPC			0
#define SOCK_TCPS			1
//-----------------------------------------------------------------------------

unsigned char m_dip[4]	= MY_DESTINATIONIP;			//Destination IP	: 192.168.0.154
unsigned char m_sip[4]	= MY_SOURCEIP;				//Source IP     	: 192.168.0.100

//-----------------------------------------------------------------------------
void NetInit(void)
{
	unsigned char mac[6]	= MY_NET_MAC;
	unsigned char sm[4]	= MY_SUBNET;
	unsigned char gwip[4]	= MY_NET_GWIP;

	//W5100 Chip Init
	iinchip_init();

	//Set MAC Address
	setSHAR(mac);

	//Set Gateway
	setGAR(gwip);

	//Set Subnet Mask
	setSUBR(sm);

	//Set My IP
	setSIPR(m_sip);
	
#ifdef __DEF_IINCHIP_INT__
	setIMR(0xEF);
#endif
	
	sysinit(MY_NET_MEMALLOC, MY_NET_MEMALLOC);
}
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
//Initialize socket - 서버 모드로 소켓 초기화
unsigned char InitSocketServer(unsigned int Socket, unsigned Port)
{
	//initialize the socket 
	if(socket(Socket,Sn_MR_TCP, Port,0x20) == 0)
	{
		DebugPrint("Fail to create socket.");

		return 0;
	}
	else
	{
		listen(Socket);
	}

	return 1;
}

//-----------------------------------------------------------------------------
//수신데이터 처리
void EthernetTest(unsigned char *pRcvBuffer, unsigned int len)
{
	unsigned int i;

	DebugPrint("Read Data[%d]\r\n", len);
	
	for(i=0;i<len;i++)
	{
		//if(i%16==0)DebugPrint("\r\n");
		DebugPrint("%02X ", pRcvBuffer[i]);
	}

	DebugPrint("\r\nReceive OK!\r\n");
}


//TCP-Server 처리
void ProcessTcpSever(void)
{
	int len;							
	unsigned char data_buf[TX_RX_MAX_BUF_SIZE];

	uint16 port = MY_LISTEN_PORT;
	
	switch (getSn_SR(SOCK_TCPS))
	{
	case SOCK_ESTABLISHED:
		//check Rx data
		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;	
			
			//read the received data
			len = recv(SOCK_TCPS, data_buf, len);

			//send the received data - loop back test
			send(SOCK_TCPS, data_buf, len);	
			
			EthernetTest(data_buf, len);
		}		
		break;
		
	case SOCK_CLOSE_WAIT:                           		
		//If the client request to close
		disconnect(SOCK_TCPS);
		break;
		
	case SOCK_CLOSED:
		//if a socket is closed
		
		//reinitialize the socket 
		InitSocketServer(SOCK_TCPS, port);
		break;
	}
}
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// Main Routine
//-----------------------------------------------------------------------------
int main(void)
{
	SystemInit();
	
	//Serial Init
	DebugInit(BAUD_115200);
	DebugPrint("[Mega128 EVM] Test Program. - TCP Server\r\n");

	//W5100 Chip Initialize
	//----------------------------
	InitWiznet();

	NetInit();
	//----------------------------
	
	//Display Net Configuration..
	DisplayConfig();
	
	//Initialize TCP Server
	InitSocketServer(SOCK_TCPS, MY_LISTEN_PORT);
	
	while (1)
	{
		//TCP Server Process
		ProcessTcpSever();
	}		
}
//-----------------------------------------------------------------------------

Posted by nexp

댓글을 달아 주세요

  1. 곽상훈

    안녕하세요
    혹시 AVR로 Wiznet 제어 하셨자나요
    Direct 모드로 LM3s2965로 제어를 하려고 하는데요
    레지스트리 R/W가 잘안되네요..
    2965에는 외부메모리를 쓰는것이 없어서 16Bit BUS 통신으로 제어를하고 있습니다.
    도와주세요~

    2010.07.03 14:20 [ ADDR : EDIT/ DEL : REPLY ]