
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