1. 개요

 

    이 문서는 시리얼 모듈을 루아에서 동작 시키기 위한 기능 중   리눅스 시스템 시리얼 목록을 구하고 필요한 정보 및 기능을   제공하는 시리얼 목록 객체 생성 함수인 serial_port_list() 함수   를 구현한 내용을 기록한 문서이다.
   
    이 문서에 대한 시험은 EZ-S3C2440 으로 하였다.

 

1.1 시험용 루아 데모 소스에 사용된 printf 팁

 

    C 에 익숙한 사람은 다음과 같이 printf 함수를  재선언 해줌으로써 C 의 printf 와 똑같은 감각으로  사용할 수 있다.
   
    printf = function(s,...) return io.write(s:format(...)) end;

 

2. 시리얼 장치 목록 모듈

 

    시리얼 장치 목록 객체는 다음과 같은 기능을 제공한다.
   
        - 시스템이 제공하는 시리얼 통신 장치 총 갯수
        - 장치 디바이스 파일 이름
        - 장치 주번호
        - 장치 부번호
        - 시스템내에 디바이스 파일 재 작성
       
2.1 시리얼 장치 목록 객체 생성과 소멸은 다음과 같다.

 

    m = require "serial";
    spl = m.port_list();    -- 생성
   
        --
        --
        --
   
    spl = nil'              -- 소멸(선언적 의미)
    m = nil;                -- 실제 소멸
           

2.2 시스템이 제공하는 시리얼 통신 장치 총 갯수

 

    변수명 : count
    변수형 : 정수
    내용   : 시스템이 제공하는 시리얼 통신 장치 총 갯수
    사용예 : 
             printf( "total = %d\n", spl.count );

 

2.3 장치 선택

 

    변수명 : select
    변수형 : 정수
    내용   : 객체 내부에 여러 장치가 있는데 정보를 얻고자 하는  장치를 선택한다.
            
             이 변수에 지정하는 값은 1 부터 시작 한다.
             이 변수 값은 count 값을 넘지 못한다.
             지정된 범위 값을 넘어서는 지정은 무시된다.


    사용예 :

             spl.select = 3;
            printf( "select = %d ", spl.select );
   
2.4 장치 디바이스 파일 이름

 

    변수명 : name
    변수형 : 문자열
    내용   : 선택된 장치의 디바이스 파일 이름
   
             이 파일 이름은 시스템 커널에서 정의되거나   파일 시스템의 /dev/ 디렉토리에 제공되는 것과는 다르다.
             임베디드 리눅스 시스템에 사용되는 형태가 통일 되어 있지 않아  객체 내부에서 재정의 하고 있다.
             이름 형태는 다음과 같다.
            
                /dev/ttyS1, /dev/ttyS2, /dev/ttyS3, ...
               
             시스템 내부에 이 객체에서 제공된 이름으로 장치 파일을 재 구축하고자 한다면  make_device_file() 함수를 사용한다.
            
    사용예 :
             printf( "device name = %s ", spl.name );

 

2.5 장치 주번호

 

    변수명 : major
    변수형 : 정수
    내용   : 선택된 장치의 디바이스 파일 주번호
    사용예 :
             printf( "major = %d ",       spl.major );

 

2.6 장치 부번호

 

    변수명 : minor
    변수형 : 정수
    내용   : 선택된 장치의 디바이스 파일 주번호
    사용예 :
             printf( "major = %d ",       spl.major );


2.7 시스템내에 디바이스 파일 재 작성

 

    함수명 : minor
    매개   : 없음
    반환   : 없음
    내용   : 객체에서 제공된 디바이스 파일 이름으로
             장치 파일을 재 구축한다.
    사용예 :
             spl.make_device_file();

 

2.8 시험용 루아 데모 소스

 

 #!/mnt/nfs/lua/lua
m = require "serial";
printf = function(s,...) return io.write(s:format(...)) end;
printf( ">> serial port list\n" );
spl = m.port_list();
printf( "   total = %d\n", spl.count );
printf( "   list  = " ); print( spl );
for i = 1, spl.count do
    spl.select = i;
    printf( "   " ); 
    printf( "select = %d ",      spl.select );
    printf( "device name = %s ", spl.name );
    printf( "major = %d ",       spl.major );
    printf( "minor = %s ",       spl.minor );
    printf( "\n" ); 
end;
spl.make_device_file();
m = nil;

3 구현 소스 목록

 

    2 항에서 설명한 내용을 구현하기 위한 소스 구성은 다음과 같다.
   
    Makefile           : 컴파일을 위한 메이크 파일
    run.lua            : 시험을 위한 루아 스크립트
    serial.c           : serial 모듈 전체를 위한 기본 구성 소스
    serial_port_list.h : 포트 목록 객체 구현을 위한 헤더 파일
    serial_port_list.c : 포트 목록 객체 구현을 위한 소스

 

4. serial.c 소스

 

    이 소스는 앞으로 만들어 갈 serial 모듈 전체를 관리한다.
    현재는  serial 모듈에서 시리얼 포트 목록 관리 객체를
    지원하기 위한 구조만으로 되어 있다.
   
    이 후 시리얼 객체가 추가되면 완성될 것이다. 
    

 #include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LUA_LIB
#include <lua.h>
#include <lauxlib.h>
#include <serial_port_list.h>
#define SERIAL      "SERIAL"
static int serial_create( lua_State *L )
{
    return 0;
}
static const struct luaL_Reg sm[] =
{
    { "port_list"   , serial_port_list  },
    { "create"      , serial_create     },
   
    { NULL, NULL }
};
LUALIB_API int luaopen_serial( lua_State *L )
{
    int top;
   
    luaL_register(L, "serial", sm );
    serial_port_list_new_metatable(L);
    return 1;
}

5. serial_port_list.h 헤더 파일

 

    이 헤더파일은 시리얼 목록 객체를 위한 C 헤더 파일이다.
    다음과 같은 내용을 다루고 있다.
   
    SERIAL_PORT_LIST : 이 매크로는 루아 내에서 시리얼 모듈 객체를 구별하기 위해서
                       정의된 문자열이다.
                      
    MAX_SERIAL_PORT  : 이 매크로는 시리얼 목록 객체가 관리 가능한
                       최대 시리얼 포트 목록수를 지정한다.

    serial_port_info_t : 시리얼 목록의 각 장치 정보를 다루도록 선언된 구조체이다.
    serial_port_list_t : 시리얼 목록 객체의 사용자 데이터 구조체이다.
   
    serial_port_list()               : 시리얼 목록 객체를 생성하는 실제 함수이다.
    serial_port_list_new_metatable() : 시리얼 목록 객체의 메타 테이블을 생성하는 함수이다.
   
5.1 serial_port_list_t 구조체

 

   이 구조체는 다음과 같은 필드를 가지고 있다.
   
    count  : 시스템에세 가지고 있는 시리얼 장치 총수
    select : 객체 외부에서 정보를 가지고 가기 위해서 선택하는 ports 변수에 사용될 인덱스
    ports  : 각 시리얼 장치의 정보를 가지고 있는 배열

 

5.2 serial_port_info_t 구조체

 

    이 구조체는 다음과 같은 필드를 가지고 있다.
   
    device_name : 시리얼 장치의 디바이스 파일명
    major       : 시리얼 장치의 주 번호
    minor       : 시리얼 장치의 부 번호

 

5.3 serial_port_list.h 헤더 파일 소스   

 #define SERIAL_PORT_LIST    "SERIAL_PORT_LIST"
#define MAX_SERIAL_PORT     256
typedef struct {
    char device_name[128];
    int  major;
    int  minor;
} serial_port_info_t;
typedef struct {
    int                 count;
    int                 select;
    serial_port_info_t  ports[MAX_SERIAL_PORT];
} serial_port_list_t;
extern int serial_port_list( lua_State *L );
extern int serial_port_list_new_metatable(lua_State *L );

6 Makefile

 

    모듈을 컴파일을 위한 메이크 파일이다.


 

 CROSS_PREFIX = arm-linux
LUA_MODULE = serial.so
TARGET     = $(LUA_MODULE)
TARGET_NFS = /nfs/lua
LIB_LUA_A  = liblua.a
C_SRCS =
LUA_SRCS =
LUA_LIBS_SRCS =
C_SRCS      += serial.c
C_SRCS      += serial_port_list.c
LUA_SRCS    += run.lua
# LUA Support  -- CORE
LUA_LIBS_SRCS =
LUA_LIBS_SRCS += ../../lua_lib/lapi.c
LUA_LIBS_SRCS += ../../lua_lib/lcode.c
LUA_LIBS_SRCS += ../../lua_lib/ldebug.c
LUA_LIBS_SRCS += ../../lua_lib/ldo.c
LUA_LIBS_SRCS += ../../lua_lib/ldump.c
LUA_LIBS_SRCS += ../../lua_lib/lfunc.c
LUA_LIBS_SRCS += ../../lua_lib/lgc.c
LUA_LIBS_SRCS += ../../lua_lib/llex.c
LUA_LIBS_SRCS += ../../lua_lib/lmem.c
LUA_LIBS_SRCS += ../../lua_lib/lobject.c
LUA_LIBS_SRCS += ../../lua_lib/lopcodes.c
LUA_LIBS_SRCS += ../../lua_lib/lparser.c
LUA_LIBS_SRCS += ../../lua_lib/lstate.c
LUA_LIBS_SRCS += ../../lua_lib/lstring.c
LUA_LIBS_SRCS += ../../lua_lib/ltable.c
LUA_LIBS_SRCS += ../../lua_lib/ltm.c
LUA_LIBS_SRCS += ../../lua_lib/lundump.c
LUA_LIBS_SRCS += ../../lua_lib/lvm.c
LUA_LIBS_SRCS += ../../lua_lib/lzio.c
# LUA Support  -- LIB
LUA_LIBS_SRCS += ../../lua_lib/lauxlib.c
LUA_LIBS_SRCS += ../../lua_lib/lbaselib.c
LUA_LIBS_SRCS += ../../lua_lib/ldblib.c
LUA_LIBS_SRCS += ../../lua_lib/liolib.c
LUA_LIBS_SRCS += ../../lua_lib/lmathlib.c
LUA_LIBS_SRCS += ../../lua_lib/loslib.c
LUA_LIBS_SRCS += ../../lua_lib/ltablib.c
LUA_LIBS_SRCS += ../../lua_lib/lstrlib.c
LUA_LIBS_SRCS += ../../lua_lib/loadlib.c
LUA_LIBS_SRCS += ../../lua_lib/linit.c
INCLUDES += -I.
INCLUDES += -I/usr/local/include
INCLUDES += -I/usr/$(CROSS_PREFIX)/include
INCLUDES += -I../include
INCLUDES += -I../../lua_include
LDFLAGS += -L./
LDFLAGS += -L../../lua_lib/
LDFLAGS += -L/usr/$(CROSS_PREFIX)/lib
LIBS  = -lm -ldl -llua
CFLAGS   += $(INCLUDES)
CFLAGS   += -Wall -O2 -g -DLUA_USE_LINUX
CPPFLAGS += $(DEFINES)
ARFLAGS = rs
#---------------------------------------------------------------------
CC           = $(CROSS_PREFIX)-gcc
CXX          = $(CROSS_PREFIX)-g++
AR           = $(CROSS_PREFIX)-ar rcu
AR2          = $(CROSS_PREFIX)-ranlib
RANLIB       = $(CROSS_PREFIX)-ranlib
LD           = $(CROSS_PREFIX)-ld
NM           = $(CROSS_PREFIX)-nm
STRIP        = $(CROSS_PREFIX)-strip
OBJCOPY      = $(CROSS_PREFIX)-objcopy
CP = cp
MV = mv
#--------------------------------------------------------------------
C_OBJS          = $(C_SRCS:%.c=%.o)
LUA_LIBS_OBJS   = $(LUA_LIBS_SRCS:%.c=%.o)
#
# Compilation target for C files
#
%.o:%.c
    @echo "Compiling $< ..."
    $(CC) -c $(CFLAGS) -o $@ $<

%.o:%.cc
    @echo "Compiling $< ..."
    $(CXX) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<
#
# Compilation target for C++ files
#
%.o:%.cc
    @echo "C++ compiling $< ..."
    $(CXX) -c $(CFLAGS) $(CXXFLAGS) -o $@ $<
all : $(LIB_LUA_A) $(LIB_GXLIB_A) $(TARGET)
    cp -a $(LUA_MODULE) $(TARGET_NFS)
    cp $(LUA_SRCS) $(TARGET_NFS)
$(LIB_LUA_A) : $(LUA_LIBS_OBJS)
    $(AR) $@ $?
    $(RANLIB) $@
$(TARGET) : $(C_OBJS)
    $(CC) $(LDFLAGS)  -shared -Wl,-soname,$(TARGET) $(C_OBJS) -o $@ $(LIBS)
dep :
    $(CC) -M $(INCLUDES) $(C_SRCS) > .depend
clean:
    rm -f *.bak
    rm -f *.map
    rm -f *.o
    rm -f *.so
    rm -f $(C_OBJS)
    rm -f $(LUA_LIBS_OBJS)
    rm -f $(LIB_LUA_A)
    rm -f $(TARGET) core
distclean: clean
    rm -rf .depend
ifeq (.depend,$(wildcard .depend))
include .depend
endif


    C000_lua.gif