1. 개요

    이 문서는 루아에서 serail 통신을 지원하기 위해서 필요한 설계를 기술한다.

2. serial 을 지원하기 위한 C 함수들

2.1 시리얼 포트 사용시 사용하는 헤더 파일

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <termios.h>
    #include <fcntl.h>

2.2 시리얼 포트 열고 닫기 예

    int     fd;

    fd = open( "/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK );
    close( fd);
   
2.3 시리얼 포트 읽고 쓰기

    읽기 :
   
        char buff[4096];
        int  size;
   
        size = read( fd, buff, sizeof( buff ) );
   
    쓰기 :
   
        write( fd, "forum.falinux.com", 17);
   
2.4 시리얼 포트 통신 설정

    설정
   
        memset( &newtio, 0, sizeof(newtio) );
        tcflush (fd, TCIFLUSH );
           :
          설정 코드( 아래 참조 )
           :
        tcsetattr(fd, TCSANOW, &newtio );

    통신 속도
   
        110      :  B110  
        300      :  B300  
        120      :  B120  
        2400     :  B2400 
        4800     :  B4800 
        9600     :  B9600 
        19200    :  B19200
        28800    :  B28800
        38400    :  B38400
        57600    :  B57600
        115200   :  B115200

        예)
        newtio.c_cflag = B115200;           // 통신 속도 115200
       
    정지 비트
   
        1 STOP : 0
        2 STOP : RS_2_STOP_BIT 
       
        예)
        newtio.c_cflag |= RS_2_STOP_BIT;

    데이타 비트 와 패리티

        데이터 비트 5 : CS5
        데이터 비트 6 : CS6
        데이터 비트 7 : CS7
        데이터 비트 8 : CS8
       
        홀수 패리티   : PARODD | PARENB
        짝수 패리티   : PARENB
        패리티 없음   : 0

        예)
        newtio.c_cflag |= CS8;  // 데이터 비트가 8bit, 패리티 없음
       
       
    패리티 오류 무시 ( 기본적으로 사용 )
   
        newtio.c_iflag = IGNPAR;
   
3. 시리얼 통신 함수의 사용예

    시리얼 통신 함수는 다음과 같은 일반적인 사용법을 갖는다.
   
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <termios.h>
    #include <fcntl.h>
   
    int main( void)
    {
       int fd;
       struct termios newtio;
   
       fd = open( "/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK );
   
       memset( &newtio, 0, sizeof(newtio) );
   
       newtio.c_cflag = B115200;   // 통신 속도 115200
       newtio.c_cflag |= CS8;      // 데이터 비트가 8bit
       newtio.c_cflag |= CLOCAL;   // 외부 모뎀을 사용하지 않고 내부 통신 포트 사용
       newtio.c_cflag |= CREAD;    // 쓰기는 기본, 읽기도 가능하게
       newtio.c_iflag = 0;         // parity 비트는 없음
       newtio.c_oflag = 0;
       newtio.c_lflag = 0;
       newtio.c_cc[VTIME] = 0;
       newtio.c_cc[VMIN] = 1;
   
       tcflush (fd, TCIFLUSH );
       tcsetattr(fd, TCSANOW, &newtio );   // 포트에 대한 통신 환경을 설정합니다.
      
       write( fd, "forum.falinux.com", 17);
      
       close( fd);
      
       return 0;
    }
   
4. 루아에서 지원하도록 하는 serial 모듈 함수들 및 특징

    루아에서는 다음과 같은 함수를 사용 할 수 있도록 한다.
   
    serial.port_list();

        설명 : serial 모듈에서 시스템의 포트 목록을 테이블로 반환한다.
        매개 : 없음
        반환 : 포트 목록 테이블

    serial.create();

        설명 : serial 모듈에서 com 객체(통신 객체)를 생성한다.
        매개 : 없음
        반환 : com 객체

    com.free();    

        설명 : 할당된 com 객체를 해제 한다.
        매개 : 없음
        반환 : 없음

    com.port

        설명 : com 객체에서 사용할 포트를 지정한다.
               /dev/ttyS1 과 같은 string으로 디바이스 파일명을 지정한다.
               open() 함수를 호출 했을때 적용된다.

    com.baud

        설명 : com 객체에서 속도를 지정한다.
               115200 과 같은 number 로 지정한다.
               open() 함수를 호출 했을때 적용된다.
              
    com.stop

        설명 : com 객체에서 통신에 사용될 정지 비트 수를 지정한다.
               1 과 같은 number 로 지정한다.
               open() 함수를 호출 했을때 적용된다.
              
    com.data

        설명 : com 객체에서 통신에 사용될 데이터 비트 수를 지정한다.
               8 과 같은 number 로 지정한다.
               open() 함수를 호출 했을때 적용된다.
       
    com.parity
   
        설명 : com 객체에서 통신에 사용될 패리티 타입을 지정한다.
               "none"와 같은 string으로 지정한다.
               open() 함수를 호출 했을때 적용된다.
   
    com.fd

        설명 : com 객체가 open 되었을때 파일 디스크립터를 갖는다.
               오픈 되지 않았다면 -1 값을 갖는다.
               open() 함수를 호출 했을때 적용된다.
               close() 함수는 이 값을 -1로 만든다.

    com.open();
   
        설명 : com 객체의 통신 포트를 연다.
               실질적인 통신 인자는 여기서 처리 된다.
        매개 : 없음
        반환 : true  - 정상적인 처리가 됨
               false - 열기 실패
                       이때 fd 는 -1로 설정된다.

    com.close();
   
        설명 : com 객체의 통신 포트를 닫는다.
               fd 는 -1로 만든다.
        매개 : 없음
        반환 : 없음

    com.read();
   
        설명 : com 객체의 통신 포트에서 데이터를 읽는다.
        매개 : 없음
        반환 : rxdata,rxsize
               rxsize : 읽기에 실패 했다면 -1
                        읽기에 설공했다면 읽은 데이터 수를 반환한다.
               rxdata : 읽은 데이터        
       
    com.write( data, size );
   
        설명 : com 객체의 통신 포트에서 데이터를 써 넣는다.
        매개 : data      - string   써 넣을 데이터
               size      - number   써 넣을 크기 (바이트 단위) 기본값 data 크기
                                    만약 이 값이 data 의 크기보다 크다면 data 크기로 보정되어 써 넣어 진다.
        반환 : number - 써 넣어진 데이터 크기
                        이 값이 0 보다 작다면 실패한 것이다.

    serial.print_hex( data, size )
   
        설명 : data 의 값을 바이트 단위로 size 만큼 출력한다.
        매개 : data      - string   출력할 데이터
               size      - number   출력할 크기 (바이트 단위) 기본값 data 크기
                                    만약 이 값이 data 의 크기보다 크다면 data 크기로 보정되어 진다.
        반환 : 없음

    serial.print_ascii( data, size )
   
        설명 : data 의 값을 ascii 문자로 size 만큼 출력한다.
               제어 문자는 '.' 로 출력된다.
        매개 : data      - string   출력할 데이터
               size      - number   출력할 크기 (바이트 단위) 기본값 data 크기
                                    만약 이 값이 data 의 크기보다 크다면 data 크기로 보정되어 진다.
        반환 : 없음

5. 루아에서 사용하는 예

    poll_module = require "poll";
    serial_module = require "serial";
   
    ports = serial_module.port_list();
   
    print( "system port list" );
    for k,v in pairs(ports) do
        print( v );
    end;
   
    com  = serial_module.create();
   
    com.port = "/dev/ttyS1";
    com.baud = 115200;
    com.stop  = 1;
    com.data  = 8;
    com.parity = "none"
   
    com.open();
   
    poll = poll_module.create(3);

    while true do
   
        if poll.clear()  == false then break; end;
        if poll.event(com.fd) == false then break; end;
       
        if poll.wait( 3000 ) == false then break; end;
       
        if poll.is_timeout() then
       
           print( "poll time out\n" );
          
        else
       
            if poll.is_read( com.fd ) then

              print( "serial read event\n" );
              rxdata, rxsize = com.read();
              com.write( rxdata.."\n" );
            end;
       
        end;

    end;
   
    com.close();
    com.free();
    serial_module = nil;
   
    poll.free();
    poll_module = nil;

        C000_lua.gif