본문 바로가기

기타[etc]

[C언어] Serial 통신 프로그램

SMALL

Linux 환경에서 시리얼 통신을 하는 방법을 알아본다.

먼저 개발을 하기위해서 보드나 uart와 같은 장비?가 필요한데, 가상으로 시리얼 포트를 구성할 수 있다.

그래서 먼저 가상 시리얼 포트를 만드는 방법과 그리고 간단한 시리얼 통신 예제 프로그램을 알아본다.


1. 가상 시리얼 포트 [http://stackoverflow.com/questions/52187/virtual-serial-port-for-linux]

socat이라는 프로그램을 사용해서 가상 시리얼 포트를 만든다. 

총 3개의 터미널을 이용하고 [Terminal 2]처럼 /pts/3에 입력 값을 넣으면 pts2에서 결과 값이 나온다.

$socat -d -d pty,raw,echo=0 pty,raw,echo=0    [Terminal 0]

$cat < /dev/pts/2                                         [Terminal 1]

$echo "Test" > /dev/pts/3                             [Terminal 2]





* TTY/PTS 차이

[https://unix.stackexchange.com/questions/21280/difference-between-pts-and-tty]

tty is a native terminal device, the backend is either hardware or kernel emulated.

pty (pseudo terminal device) is a terminal device which is emulated by an other program (example: xtermscreen, or ssh are such programs). A pts is the slave part of a pty.

(More info can be found in man pty.)

Short summary:

pty is created by a process through posix_openpt() (which usually opens the special device /dev/ptmx), and is constituted by a pair of bidirectional character devices:

  1. The master part, which is the file descriptor obtained by this process through this call, is used to emulate a terminal. After some initialization, the second part can be unlocked with unlockpt(), and the master is used to receive or send characters to this second part (slave).

  2. The slave part, which is anchored in the filesystem as /dev/pts/x (the real name can be obtained by the master through ptsname() ) behaves like a native terminal device (/dev/ttyx). In most cases, a shell is started that uses it as a controlling terminal


간단하게 요약하면 실제 장치가 연결되어 있는 부분들은 TTY로 표시되어 진다. 실제 UART 포트를 연결하였거나 모니터를 연결한 디바이스는

TTY에 표시되어진다.

하지만 pts는 가상적으로 만들어진 터미널 장치를 표현할 때 표시 되어진다.

ptmx, ptm, pts 와 같은 용어들도 있는데...

ptm은 Master의 개념이고 pts는 slave의 개념이다.    --> 우리가 아는 Server client 모델을 생각하면 된다.


ptmx는 socket을 연다고 생각하면 된다.

그러면 해당 socekt에는 포트 번호와 함께, 관련 구조체도 설정되어 있을 것이고 해당 socket을 이용해서 통신한다.

ex)

ptmx 9999 하면 9999라는 식별자 실제로는 fd가 생성된다고 가정

그러면 이를 기초로 하여 ptm  <---9999----> pts   와 같이 통신을 하는 것이다.



2. 시리얼 통신 프로그램

터미널 통신을 하기 위해서는 #include <termios.h> 라는 헤더가 필요하고, terminos 구조체가 필요하다.

termios 헤더에는!

포트를 통한 비동기 통신을 하기 위한 인터페이스를 설정을 위한 함수와 구조체가 설정되어 있다.

먼저 해당 termios구조체의 멤버들을 알아본다.

통신을  할 때 상황에 맞는 환경을 설정할 수 있는 멤버들이 있다.

struct termios
tcflag_t c_iflag; /* input modes */
tcflag_t c_oflag; /* output modes */
tcflag_t c_cflag; /* control modes */
tcflag_t c_lflag; /* local modes */
cc_t c_cc[NCCS]; /* special characters */



각 flag에 대한 자세한 내용은 메뉴얼 man termios 내용을 참고

int main(void)
{
int fd;
fd=open("/dev/pts/14", O_RDWR );
struct termios newtio;
// newtio <-- serial port setting.
memset(&newtio, 0, sizeof(struct termios));
newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
//B9600 : 시리얼 통신 baurate 설정
//CS8 : 데이터 BIT설정 CS5, CS6, CS7, CS8 중 선택
//CREAD : 데이터를 전송 뿐만 아니라 읽기도 가능하게
//CLOCAL: 내부 통신 포트를 사용
newtio.c_iflag = IGNPAR;
//Parity bit를 사용하지 않음
newtio.c_oflag = 0;
newtio.c_lflag = 0;
tcflush(fd, TCIFLUSH);
/*tcflush() discards data written to the object referred to by fd but not
transmitted*/
tcsetattr(fd, TCSANOW, &newtio);
/*tcsetattr() sets the parameters associated with the terminal*/
const char *str = "Hello world";
write(fd, str, strlen(str)+1);
close(fd);
return 0;
}









위와 같이 포트에 적용될 환경을 맞추고 사용하면 된다.



LIST

'기타[etc]' 카테고리의 다른 글

[PYTHON] bruteforce  (0) 2017.07.09
[Forensic] 17.7.5 교육 내용 정리  (0) 2017.07.05
so[dll] Makefile Template  (0) 2017.05.19
C언어 정규식  (0) 2017.05.11
python idle 컬러 수정  (0) 2017.03.30