[W5100 EVM] 초간단 TCP서버 테스트
임베디드 시스템에서 이더넷을 통한 네트웍제어는 여러가지 솔루션이 있지만 특히 소형의 임베디드 환경에서는 상당한 부하를 차지한다. 임베디드 환경에서 좀더 쉽고 간단히 이더넷을 제어하기 위해 TCP/IP스택이 하드웨어적으로 처리되는 W5100을 이용하여 초간단 TCP서버를 구축해 보았다.
먼저 소형 [W5100 EVM] 모듈과 AVR128 보드, 확장 테스트보드(EXP-) 를 연결한다.
회로적으로 아래와 같이 연결된다.
소스코드
소스코드는 예전에 작성했던 코드를 좀더 간단하고 사용하기 편하도록 몇가지 수정을 했다.(좀더 자세한 내용은 [AVR TCP Server 테스트 예제 참고)
[config.h]
W5100의 SPI_CS핀은 PD5에 연결되어 있다.
[/01_drv/wiznet/mcu/types.h]
SPI모드 제어를 위한 설정
네트웍 초기화
MAC Address는 고유하 번호를 할당받아야 하지만 테스트용으로 충돌 나지 않는 할당하면 된다.
보드의 IP역시 충돌나지 않는 값으로 설정하면되지만 공유기를 사용하는 경우 자동 할당번호 내의 값으로 설정해야 한다.
TCP 서버 데이터 처리
ProcessTcpSever() 함수에서 TCP 시퀀스를 폴링으로 처리 한다.
소켓의 상태를 검사 하다 데이터가 수신되면 recv()함수로 수신된 바이트를 읽어오면 된다.
TCP클라이언트로 데이터가 수신되면 처리 하는 함수로 테스트 예제로 이번 예제에서 첫번째 데이터로 LED를 제어하고 있다. ->이부분을 원하는 형태로 수정하면 된다.
메인함수
W5100 TCP 서버 테스트
실행파일
보드가 서버로 동작하기 때문에 PC프로그램은 Client로 접속에서 데이터 전송할 수 있다. 예제에서는보드 IP인 192.168.0.101로 접속 가능하다.
W5100 테스트 동영상
TCP서버로 동작하는 보드에 접속하여 데이터를 전송해 LED를 제어 하는 예제. '1'을 전송하면 LED On, '0'을 전송하면 LED Off.
임베디드 시스템에서 이더넷을 통한 네트웍제어는 여러가지 솔루션이 있지만 특히 소형의 임베디드 환경에서는 상당한 부하를 차지한다. 임베디드 환경에서 좀더 쉽고 간단히 이더넷을 제어하기 위해 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)
//-----------------------------------------------------------------------------
// 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*/
//#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
#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;
}
}
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();
}
}
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();
}
}
//-----------------------------------------------------------------------------
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.
반응형