본문 바로가기

[INTERFACE]/WIZNET_EVM

[W5100 EVM] 초간단 TCP서버 테스트

[W5100 EVM] 초간단 TCP서버 테스트


임베디드 시스템에서 이더넷을 통한 네트웍제어는 여러가지 솔루션이 있지만 특히 소형의 임베디드 환경에서는 상당한 부하를 차지한다. 임베디드 환경에서 좀더 쉽고 간단히 이더넷을 제어하기 위해 TCP/IP스택이 하드웨어적으로 처리되는 W5100을 이용하여 초간단 TCP서버를 구축해 보았다.

먼저 소형 [W5100 EVM] 모듈과 AVR128 보드, 확장 테스트보드(EXP-) 를 연결한다.


회로적으로 아래와 같이 연결된다.




소스코드
소스코드는 예전에 작성했던 코드를 좀더 간단하고 사용하기 편하도록 몇가지 수정을 했다.(좀더 자세한 내용은 [AVR TCP Server 테스트 예제 참고)


[config.h]
W5100의 SPI_CS핀은 PD5에 연결되어 있다.
//-----------------------------------------------------------------------------
// W5100 Driver
#define IINCHIP_SpiInit     SPI0_Init
#define IINCHIP_SpiSendData    SPI0_SendByte 
#define IINCHIP_SpiRecvData    SPI0_RxData

#define IINCHIP_CS_BIT     BIT5
#define IINCHIP_CS_DDR     DDRD
#define IINCHIP_CS_PORT     PORTD

#define IINCHIP_CSInit()    Sbi(IINCHIP_CS_DDR, IINCHIP_CS_BIT)
#define IINCHIP_CSon()     Sbi(IINCHIP_CS_PORT, IINCHIP_CS_BIT)
#define IINCHIP_CSoff()     Cbi(IINCHIP_CS_PORT, IINCHIP_CS_BIT)
//-----------------------------------------------------------------------------


[/01_drv/wiznet/mcu/types.h]
SPI모드 제어를 위한 설정
//#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*/


네트웍 초기화
MAC Address는 고유하 번호를 할당받아야 하지만 테스트용으로 충돌 나지 않는 할당하면 된다.
보드의 IP역시 충돌나지 않는 값으로 설정하면되지만 공유기를 사용하는 경우 자동 할당번호 내의 값으로 설정해야 한다.
#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} //Gateway     : 192.168.0.1
#define MY_SOURCEIP   {192,  168, 0,  101} //보드 IP     : 192.168.0.101
#define MY_SUBNET   {255, 255, 255,   0}

#define MY_LISTEN_PORT  5000  //서버 포트 : 5000


TCP 서버 데이터 처리
ProcessTcpSever() 함수에서 TCP 시퀀스를 폴링으로 처리 한다.
소켓의 상태를 검사 하다 데이터가 수신되면 recv()함수로 수신된 바이트를 읽어오면 된다.
//TCP-Server 처리
void ProcessTcpSever(void)
{
 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((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);   
   
   // 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);
  
  m_SokStatus1 = 0;
  break;
  
 case SOCK_CLOSED:
  if(!m_SokStatus1)
  {
   m_SokStatus1 = 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;
 }
}


TCP클라이언트로 데이터가 수신되면 처리 하는 함수로 테스트 예제로 이번 예제에서 첫번째 데이터로 LED를 제어하고 있다. ->이부분을 원하는 형태로 수정하면 된다.
//수신데이터 처리
void EthernetTest(unsigned char *pRcvBuffer, unsigned int len)
{
 unsigned int i;

 DebugPrint("Read Data[%d]\r\n", len);
 
 for(i=0;i<len;i++)
 {
  //수신데이터 표시
  DebugPrint("%c ", pRcvBuffer[i]);
 }

 //데이터 처리 - LED제어
 if(pRcvBuffer[0] == '1')
 {
  Led1On();
 }
 else if(pRcvBuffer[0] == '0')
 {
  Led1Off();
 }
}



메인함수
//-----------------------------------------------------------------------------
int main(void)
{
 SystemInit();

 //Serial Init
 DebugInit(BAUD_115200);
 DebugPrint("W5100 TCP Server Program\r\n");

 Led1Init();
 Led1On();

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

 //설정된 IP 표시
 DisplayConfig();

 while(1)
 {
  //TCP Server Process
  ProcessTcpSever();
 }
}
//-----------------------------------------------------------------------------


W5100 TCP 서버 테스트
실행파일


보드가 서버로 동작하기 때문에 PC프로그램은 Client로 접속에서 데이터 전송할 수 있다. 예제에서는보드 IP인 192.168.0.101로 접속 가능하다.



W5100 테스트 동영상
TCP서버로 동작하는 보드에 접속하여 데이터를 전송해 LED를 제어 하는 예제. '1'을 전송하면 LED On, '0'을 전송하면 LED Off.




반응형