본문 바로가기
코스웨어/15년 스마트컨트롤러

20151207 임현수 업무일지 리눅스 시리얼통신

by 알 수 없는 사용자 2015. 12. 8.
728x90
반응형
■ 리눅스 시리얼통신



이름만 미리 만들어놨음.

▲ 리눅스에서 입력하면 윈도우 포트로 나간다.

■ VM웨어 시리얼 포트 추가






■ (길에서 주운 USB에 들어있는)가상 시리얼 포트 설치

가상 Com포트를 만들어 낼 수 있다.


▲ 가상포트 생성. 항상 두개가 한셋트이다.
가상포트 추가해놓고 프로그램 껏다켜도 그대로 남아있다.(반영구)


▲ 가상포트 삭제


암호문 - 고대언어로부터 시작되었다.

암호해독
가장많이쓰는 알파벳 추출
빅데이터에 모은다.
제일많이나오는 글자와 매칭.

▲ 우리가 만든 프로그램을 거쳐서 나가도록하면 도청이 가능.

▲ 원래대로라면 윈도우의 7-1을 연결해서 통신을 하면 되겠지만,
가상포트를 2개 추가하고 그 사이를 Z란 프로그램으로 통과하도록 만들면 도청이 된다.
내부프로그램입장에서는 데이터를 주고받는데 문제가 없음.

핸드폰에서 나갈때는 암호화되서 나가는데, 기지국을 거쳐 나갈때는 무방비상태???

termio 구조체 - 시리얼 포트의 입출력을 담당하는 구조체

POSIX - 운영체제 표준안
POSIX 가 확립된것은 유닉스 때문이다. 유닉스 정도가 되야 운영체제라고 할 수 있다.


엔터키입력을 입력 끝으로 받아들인다. 도스방식도 동일하다고 볼 수 있다.
C언어에서는 널(End of Line)
데이터 크기 고정 안됨을 의미한다.


데이터 크기가 고정을 의미한다.

데이터 크기의 지정의 의미는 데이터가 아직 오고있는가 아닌가를 판단할 수 있게 하는 기준이다.


Non-Canonical의 +알파




▲ vmware포트를 가상포트로 설정


#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#define SPEED B19200
#define SPORT "/dev/ttyS0"

main()
{
     char cBuff[255]; // 수신용 버퍼
     int iDev = 0; // 장치 데스크립션
     int iRet = 0; // 반환값
     struct termios stOldState; // 기존 Serial Port 상태 정보
     struct termios stNewState; // 새로운 Serial Port 상태 정보
     iDev = open(SPORT, O_RDWR | O_NOCTTY); // Serial Port Open
     if (0 > iDev) // 시리얼 포트 Open Error
     {
          perror(SPORT);
          exit(-100);
     }

     tcgetattr(iDev, &stOldState); // 현재 Serial Port 상태 저장
     bzero(&stNewState, sizeof(stNewState)); // 구조체 초기화
     // SPEED : 전송 속도, cfsetispeed(), cfsetospeed()로도 설정 가능
     // CS8 : 8N1 (8bit, no parity, 1 stop bit)
     // CLOCAL : Local connection. 제어를 하지 않음
     // CREAD : 문자 수신 가능
     stNewState.c_cflag = SPEED | CRTSCTS | CS8 | CLOCAL | CREAD;
     // IGNPAR : Parity 에러가 있는 문자 바이트 무시
     // ICRNL : CR 문자를 NL 문자로 변환 처리
     stNewState.c_iflag = IGNPAR | ICRNL;
     stNewState.c_oflag = 0; // 수신된 데이터를 그대로 출력

     stNewState.c_lflag = ICANON; // Canonical 통신 기법 사용
     bzero(stNewState.c_cc, NCCS); // 제어 문자 초기화
     stNewState.c_cc[VMIN] = 1; // read시 리턴되기 위한 최소 문자 개수 지정
     tcflush(iDev, TCIFLUSH); // 시리얼 포트 수신 큐 초기화
     tcsetattr(iDev, TCSANOW, &stNewState); // 시리얼 포트에 새 속성 적용
     iRet = read(iDev, cBuff, 255); // 시리얼 포트로부터 데이터 수신
     cBuff[iRet-1] = 0;
     printf("[%s]:[%d]\n", cBuff, iRet);
     tcsetattr(iDev, TCSANOW, &stOldState); // 시리얼 포트의 원래 속성 복귀
     close(iDev); // 시리얼 포트 닫음
} // End main()

O_NOCTTY
ctrl+C 는 프로그램을 종료해야되는데 
ctrl+C 를 상대방에게 전송하는 불상사가 생기는것을 막기위한 플래그

stNewState.c_cc[VMIN] = 1;
최소 문자1개 수신지정했기 때문에 read에서 블로킹 걸린다.


stSigAct.sa_handler = Handle_Serial_Sig;
sigaction(SIGIO, &stSigAct, NULL);
시그널 액션 - 소프트웨어 인터럽트(비동기모드는 소프트웨어 인터럽트라고 보면 됨)
입출력이 일어나면 함수호출되도록 한다.

fcntl(iDev, F_SETOWN, getpid());
현재실행중인 프로그램의 번호를 알아내서 iDev와 합체.

리눅스 시리얼은 캐노니컬모드나 논캐노니컬모드 둘중에 하나를 무조건 사용해야되는데

Asynchronous는 캐노니컬을 쓴다.


728x90