W5500으로 이더넷 구현하기 (Echo Server)

W5500으로 이더넷 구현하기

목차

  1. 개발 환경 구축

    • LPCXpresso 설치
    • Flash Magic 설치
    • 신규 프로젝트 생성 방법
  2. W5500 드라이버 포팅

    • W5500-EVB W5500 Interface (SPI)
    • W5500 Driver Import
    • 초기화 함수 구현
      • W5500 초기화 Flow
      • MCU Interface 초기화 함수
      • Call Back 함수 구현
      • W5500 Chip 초기화 함수
      • Network 설정 함수
    • Main 함수 구현
    • Firmware 적용 및 테스트
  3. Echo-Server 구현

    • Echo-Server 구현

Echo-Server 구현

Echo-Server 구현

먼저 이 내용은 앞서 포스팅 한 “W5500 드라이버 포팅” 과정까지 마무리 한 상태에서 진행된다. 즉, 새로운 프로젝트를 생성하고 W5500 드라이버까지 포팅된 상태에서 Echo-Server를 구현한다.
W5500으로 이더넷 구현하기(개발환경구축)
W5500으로 이더넷 구현하기(W5500 드라이버 포팅)

기본적으로 W5500 드라이버는 Bsd Socket Interface를 지원한다. 즉, 이더넷 통신을 하기 위해서 Socket을 생성하고 Connect하며 데이터를 송수신하게 된다.

W5500 드라이버를 사용하여 이더넷 통신을 하기 위해서는 “Socket Status Register”의 상태에 따라 동작을 정의 하는 방식으로 구현하게 된다. Socket Status Register 상태는 다음과 같이 정의 된다.

Socket status Description Use API
SOCK_CLOSED Socket이 Close 된 상태 socket
SOCK_INIT Socket이 TCP Mode로 Open 된 상태 connect / listen
SOCK_LISTEN Socket이 TCP Server Mode로 Open 된 상태 close
SOCK_ESTABLISHED TCP 연결이 성립된 상태 recv / send / close
SOCK_CLOSE_WAIT Peer로부터 disconnect-request를 수신한 상태 close
SOCK_UDP Socket이 UDP Mode로 Open 된 상태 recvfrom / sendto

다음은 TCP를 사용할 때의 State Diagram이다.
141029_echo_server1

다음은 UDP를 사용할 때의 State Diagram이다.
141029_echo_server2

여기서는 TCP Base Echo Server를 구현하는 것으로 설명을 진행한다. 먼저 State에 따른 처리를 하기 위해 기본적은 골격은 다음과 같이 작성한다. State 상태에 따라 동작을 정의 하는 것이다.

{
    ...
    switch(getSn_SR(sn)) {
    case SOCK_CLOSED:
        /* Socket Closed State */

        break;
    case SOCK_INIT:
        /* TCP Socket Creatation */

        break;
    case SOCK_LISTEN:
        /* TCP Server Mode */

        break;
    case SOCK_ESTABILSHED:
        /* TCP ESTABLISHED */

        break;
    case SOCK_CLOSE_WAIT:
        /* Disconnect request */

        break;
    }
    ...
}

위의 골격을 기초로 하여 TCP Echo Server 기능을 하는 함수를 W5500-EVB.c 파일에 구현한다.

int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port)
{
    int32_t ret;
    uint16_t size = 0, sentsize=0;
    switch(getSn_SR(sn)) {
        case SOCK_ESTABLISHED :
            if(getSn_IR(sn) & Sn_IR_CON) {
                printf("%d:Connected\r\n",sn);
                setSn_IR(sn,Sn_IR_CON);
            }
            if((size = getSn_RX_RSR(sn)) > 0) {
                if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
                ret = recv(sn,buf,size);
                if(ret <= 0) return ret;
                sentsize = 0;
                while(size != sentsize) {
                    ret = send(sn,buf+sentsize,size-sentsize);
                    if(ret < 0) {
                        close(sn);
                        return ret;
                    }
                    sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
                }
            }
            break;
        case SOCK_CLOSE_WAIT :
            printf("%d:CloseWait\r\n",sn);
            if((ret=disconnect(sn)) != SOCK_OK) return ret;
            printf("%d:Closed\r\n",sn);
            break;
        case SOCK_INIT :
            printf("%d:Listen, port [%d]\r\n",sn, port);
            if( (ret = listen(sn)) != SOCK_OK) return ret;
            break;
        case SOCK_CLOSED:
            printf("%d:LBTStart\r\n",sn);
            if((ret=socket(sn,Sn_MR_TCP,port,0x00)) != sn)
                return ret;
            printf("%d:Opened\r\n",sn);
            break;
        default:
            break;
    }
    return 1;
}

SOCK_ESTABLISHED 상태에서는 TCP 연결이 성립된 상태이므로 수신한 데이터를 다시 전송하는 기능을 구현한다. SOCK_CLOSE_WAIT 상태에서는 Client로부터 disconnect request를 받은 상태이므로 disconnect 함수를 호출하면 자연스럽게 소켓이 close 상태가 된다. SOCK_INIT 상태에서는 TCP Echo Server 이므로 listen 함수를 호출하여 Clinet 연결을 기다리는 상태 SOCK_LISTEN 상태로 진행한다. SOCK_CLOSED 상태에서는 Socket 함수를 호출하여 통신에 사용할 Socket을 생성한다.

W5500 Socket Interface를 사용하기 위해 w5500.h를 include 한다.

#include "socket.h"

그 외 매크로와 상수를 선언한다.

#define SOCK_TCPS0       0
#define DATA_BUF_SIZE   2048
uint8_t gDATABUF[DATA_BUF_SIZE];

구현이 완료되면 프로젝트를 빌드하여 생성된 Firmware 이미지를 W5500-EVB 보드에 적용한다. 이 과정은 이전 포스팅에서 설명하였으므로 따로 설명하지 않겠다.

Firmware 적용 후 시리얼 터미널을 연결하고 Reset 버턴을 누르면 다음의 메시지를 볼 수 있다.
141029_echo_server3 다음 상태는 TCP Socket을 생성하고 Listen 상태에 있는 것이다.

먼저 Test할 PC와 W5500-EVB를 같은 서브넷으로 구성한다. Test PC에서 TCP Client 프로그램인 Hercules를 실행한다. Hercules는 아래의 링크에서 다운받을 수 있다.
Hercules : 다운로드

Hercules를 실행하고 TCP Client 탭을 선택한다. TCP 부분의 Module IP 부분에 Echo Server IP “192.168.1.100”을 입력한다. Port 부분에 5000을 입력하고 Connect 버튼을 누르면 W5500-EVB Echo Server로 접속 된다.
141029_echo_server4 141029_echo_server5

Hercules Send 창에서 메시지를 입력하여 전송하면, 그 메시지가 다시 돌아오는 것을 확인할 수 있다.
141029_echo_server6

프로젝트 파일 : 다운로드

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

This site uses Akismet to reduce spam. Learn how your comment data is processed.