¿©±âÀÇ ¸ðµç ¿¹Á¦´Â miniterm.c
¿¡¼ µû¿Ô´Ù. Canonical ÀԷ ó¸®¿¡¼
ó¸®ÇÒ ¼ö ÀÖ´Â ÃÖ´ë ±æÀÌÀÇ ¹®ÀÚ´Â 255°³(<linux/limits.h>
ȤÀº <posix1_lim.h>
¿¡ Á¤ÀǵÊ) ·Î¼ ¹öÆÛÀÇ ÃÖ´ë ±æÀÌ´Â
255·Î Á¦ÇѵȴÙ.
¿©·¯ ÀԷ ó¸® ¸ðµåÀÇ »ç¿ë¹ý¿¡ ´ëÇÑ ¼³¸íÀ» ¿øÇϸé ÄÚµå ³»ÀÇ comment¸¦ ÂüÁ¶Ç϶ó. Äڵ尡 ÀÌÇØÇϱ⠽±±â¸¦ ¹Ù¶õ´Ù. Canonical ÀԷ ó¸® ¸ðµåÀÇ ¿¹Á¦´Â comment¸¦ °¡Àå Àß Çسõ¾Ò´Ù. ´Ù¸¥ ¿¹Á¦´Â canonical ¸ðµå ¿¹Á¦¿Í ´Ù¸¥ ºÎºÐ¿¡¸¸ comment¸¦ ´Þ¾Ò´Ù.
¼³¸íÀÌ ¿Ïº®ÇÏÁø ¾ÊÁö¸¸, ÀÌ ¿¹Á¦·Î Á÷Á¢ Å×½ºÆ®¸¦ Çغ¸¸é ´ç½ÅÀÇ ÇÁ·Î±×·¥¿¡ Àû¿ëÇÒ ¶§ ÃÖÀûÀÇ ¹æ¹ýÀ» ãÀ» ¼ö ÀÖÀ» °ÍÀÌ´Ù.
½Ã¸®¾ó Æ÷Æ® ÀåÄ¡ ÆÄÀÏÀÇ ¼±ÅÃÀ» Á¦´ë·Î Çߴ°¡¸¦ ´Ù½Ã ÇÑ ¹ø È®ÀÎÇÏ°í, ÆÄÀÏ Á¢±Ù
Çã°¡´Â Á¦´ë·Î µÇ¾î ÀÖ´ÂÁö º¸±â¸¦ ¹Ù¶õ´Ù.
(¿¹: chmod a+rw /dev/ttyS1
)
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <stdio.h> /* Baudrate ¼³Á¤Àº <asm/termbits.h>¿¡ Á¤ÀǵǾî ÀÖ´Ù. /* <asm/termbits.h>´Â <termios.h>¿¡¼ includeµÈ´Ù. */ #define BAUDRATE B38400 /* ¿©±âÀÇ Æ÷Æ® ÀåÄ¡ ÆÄÀÏÀ» ¹Ù²Û´Ù. COM1="/dev/ttyS1, COM2="/dev/ttyS2 */ #define MODEMDEVICE "/dev/ttyS1" #define _POSIX_SOURCE 1 /* POSIX ȣȯ ¼Ò½º */ #define FALSE 0 #define TRUE 1 volatile int STOP=FALSE; main() { int fd,c, res; struct termios oldtio,newtio; char buf[255]; /* Àбâ/¾²±â ¸ðµå·Î ¸ðµ© ÀåÄ¡¸¦ ¿¬´Ù.(O_RDWR) µ¥ÀÌÅÍ Àü¼Û ½Ã¿¡ <CTRL>-C ¹®ÀÚ°¡ ¿À¸é ÇÁ·Î±×·¥ÀÌ Á¾·áµÇÁö ¾Êµµ·Ï Çϱâ À§ÇØ controlling tty°¡ ¾ÈµÇµµ·Ï ÇÑ´Ù.(O_NOCTTY) */ fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY ); if (fd <0) {perror(MODEMDEVICE); exit(-1); } tcgetattr(fd,&oldtio); /* save current serial port settings */ bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */ /* BAUDRATE: Àü¼Û ¼Óµµ. cfsetispeed() ¹× cfsetospeed() ÇÔ¼ö·Îµµ ¼¼Æà °¡´É CRTSCTS : Çϵå¿þ¾î È帧 Á¦¾î. (½Ã¸®¾ó ÄÉÀ̺íÀÌ ¸ðµç ÇÉ¿¡ ¿¬°áµÇ¾î ÀÖ´Â °æ¿ì¸¸ »ç¿ëÇϵµ·Ï ÇÑ´Ù. Serial-HOWTOÀÇ 7ÀåÀ» ÂüÁ¶ÇÒ °Í.) CS8 : 8N1 (8bit, no parity, 1 stopbit) CLOCAL : Local connection. ¸ðµ© Á¦¾î¸¦ ÇÏÁö ¾Ê´Â´Ù. CREAD : ¹®ÀÚ ¼ö½ÅÀ» °¡´ÉÇÏ°Ô ÇÑ´Ù. */ newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; /* IGNPAR : Parity ¿¡·¯°¡ ÀÖ´Â ¹®ÀÚ ¹ÙÀÌÆ®¸¦ ¹«½ÃÇÑ´Ù. ICRNL : CR ¹®ÀÚ¸¦ NL ¹®ÀÚ·Î º¯È¯ ó¸®ÇÑ´Ù. (ÀÌ ¼³Á¤À» ¾ÈÇÏ¸é ´Ù¸¥ ÄÄÇ»ÅÍ´Â CR ¹®ÀÚ¸¦ ÇÑ ÁÙÀÇ Á¾·á¹®ÀÚ·Î ÀνÄÇÏÁö ¾ÊÀ» ¼ö ÀÖ´Ù.) otherwise make device raw (no other input processing) */ newtio.c_iflag = IGNPAR | ICRNL; /* Raw output. */ newtio.c_oflag = 0; ICANON : canonical ÀÔ·ÂÀ» °¡´ÉÇÏ°Ô ÇÑ´Ù. disable all echo functionality, and don't send signals to calling program */ newtio.c_lflag = ICANON; /* ¸ðµç Á¦¾î ¹®ÀÚµéÀ» ÃʱâÈÇÑ´Ù. µðÆúÆ® °ªÀº <termios.h> Çì¾î ÆÄÀÏ¿¡¼ ãÀ» ¼ö ÀÖ´Ù. ¿©±â comment¿¡µµ Ãß°¡·Î ´Þ¾Æ³õ¾Ò´Ù. */ newtio.c_cc[VINTR] = 0; /* Ctrl-c */ newtio.c_cc[VQUIT] = 0; /* Ctrl-\ */ newtio.c_cc[VERASE] = 0; /* del */ newtio.c_cc[VKILL] = 0; /* @ */ newtio.c_cc[VEOF] = 4; /* Ctrl-d */ newtio.c_cc[VTIME] = 0; /* inter-character timer unused */ newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */ newtio.c_cc[VSWTC] = 0; /* '\0' */ newtio.c_cc[VSTART] = 0; /* Ctrl-q */ newtio.c_cc[VSTOP] = 0; /* Ctrl-s */ newtio.c_cc[VSUSP] = 0; /* Ctrl-z */ newtio.c_cc[VEOL] = 0; /* '\0' */ newtio.c_cc[VREPRINT] = 0; /* Ctrl-r */ newtio.c_cc[VDISCARD] = 0; /* Ctrl-u */ newtio.c_cc[VWERASE] = 0; /* Ctrl-w */ newtio.c_cc[VLNEXT] = 0; /* Ctrl-v */ newtio.c_cc[VEOL2] = 0; /* '\0' */ /* ÀÌÁ¦ modem ¶óÀÎÀ» ÃʱâÈÇÏ°í Æ÷Æ® ¼¼ÆÃÀ» ¸¶Ä£´Ù. */ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); /* Å͹̳Π¼¼ÆÃÀÌ ³¡³µ°í, ÀÌÁ¦´Â ÀÔ·ÂÀ» ó¸®ÇÑ´Ù. ÀÌ ¿¹Á¦¿¡¼´Â ÇÑ ÁÙÀÇ ¸Ç ù ¹®ÀÚ¸¦ 'z'·Î ÇßÀ» ¶§ ÇÁ·Î±×·¥À» Á¾·áÇÑ´Ù. */ while (STOP==FALSE) { /* Á¾·á Á¶°Ç(STOP==TRUE)°¡ µÉ ¶§±îÁö ·çÇÁ */ /* read()´Â ¶óÀÎ Á¾·á ¹®ÀÚ°¡ ³ª¿Ã ¶§±îÁö 255 ¹®ÀÚ¸¦ ³Ñ¾î°¡´õ¶óµµ block µÈ´Ù. read ÇÏ°íÀÚ ÇÏ´Â ¹®ÀÚ °³¼ö°¡ ÀÔ·Â °¡´ÉÇÑ ¹®ÀÚ °³¼öº¸´Ù ÀûÀº °æ¿ì¿¡´Â ¶Ç ÇѹøÀÇ read¸¦ ÇÏ¿© ³ª¸ÓÁö¸¦ Àо ¼ö ÀÖ´Ù. res´Â read¿¡ ÀÇÇؼ ½ÇÁ¦·Î ÀÐÇôÁø ¹®ÀÚÀÇ °³¼ö¸¦ °®°Ô µÈ´Ù. */ res = read(fd,buf,255); buf[res]=0; /* set end of string, so we can printf */ printf(":%s:%d\n", buf, res); if (buf[0]=='z') STOP=TRUE; } /* restore the old port settings */ tcsetattr(fd,TCSANOW,&oldtio); }
Non-Canonical ÀԷ ó¸® ¸ðµå¿¡¼´Â ÀÔ·ÂÀÌ ÇÑ ÁÙ ´ÜÀ§·Î 󸮵ÇÁö ¾Ê´Â´Ù.
erase, kill, delete µîÀÇ ÀԷ ó¸®µµ ¼öÇàµÇÁö ¾Ê´Â´Ù. ÀÌ ¸ðµå¿¡¼ ¼³Á¤ÇÏ´Â
ÆĶó¹ÌÅÍ´Â c_cc[VTIME]
°ú c_cc[VMIN]
µÎ °¡ÁöÀÌ´Ù.
c_cc[VTIME]
Àº ŸÀ̸ÓÀÇ ½Ã°£À» ¼³Á¤ÇÏ°í, c_cc[VMIN]
˼
read
ÇÒ ¶§ ¸®ÅϵDZâ À§ÇÑ ÃÖ¼ÒÀÇ ¹®ÀÚ °³¼ö¸¦ ÁöÁ¤ÇÑ´Ù.
MIN˼ read
°¡ ¸®ÅϵDZâ À§ÇÑ ÃÖ¼ÒÇÑÀÇ ¹®ÀÚ °³¼ö.
TIMEÀÌ 0À̸é ŸÀ̸Ӵ »ç¿ëµÇÁö ¾Ê´Â´Ù.(¹«ÇÑ´ë·Î
±â´Ù¸°´Ù.)
TIMEÀº time-out °ªÀ¸·Î »ç¿ëµÈ´Ù. Time-out °ªÀº
TIME * 0.1 ÃÊÀÌ´Ù. Time-outÀÌ ÀϾ±â Àü¿¡
ÇÑ ¹®ÀÚ¶óµµ µé¾î¿À¸é read
´Â ¸®ÅϵȴÙ.
TIMEÀº time-outÀÌ ¾Æ´Ñ inter-character ŸÀ̸ӷΠµ¿ÀÛÇÑ´Ù. ÃÖ¼Ò MIN °³ÀÇ ¹®ÀÚ°¡ µé¾î¿À°Å³ª µÎ ¹®ÀÚ »çÀÌÀÇ ½Ã°£ÀÌ TIME °ªÀ» ³ÑÀ¸¸é ¸®ÅϵȴÙ. ¹®ÀÚ°¡ óÀ½ µé¾î¿Ã ¶§ ŸÀ̸Ӵ µ¿ÀÛÀ» ½ÃÀÛÇÏ°í ÀÌÈÄ ¹®ÀÚ°¡ µé¾î¿Ã ¶§¸¶´Ù Àç½ÃÀ۵ȴÙ.
read
´Â Áï½Ã ¸®ÅϵȴÙ. ÇöÀç ÀÐÀ» ¼ö ÀÖ´Â ¹®ÀÚÀÇ °³¼ö³ª
¿äûÇÑ ¹®ÀÚ °³¼ö°¡ ¹ÝȯµÈ´Ù. Antonino¾¾¿¡ ÀÇÇϸé
read
Çϱâ Àü¿¡ fcntl(fd, F_SETFL, FNDELAY);
¸¦
È£ÃâÇÏ¸é ¶È°°Àº °á°ú¸¦ ¾òÀ» ¼ö ÀÖ´Ù.
newtio.c_cc[VTIME]
°ú newtio.c_cc[VMIN]
À»
¼öÁ¤ÇÏ¿© À§ ³× °¡Áö ¹æ½ÄÀ» Å×½ºÆ® ÇÒ ¼ö ÀÖ´Ù.
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <stdio.h> #define BAUDRATE B38400 #define MODEMDEVICE "/dev/ttyS1" #define _POSIX_SOURCE 1 /* POSIX compliant source */ #define FALSE 0 #define TRUE 1 volatile int STOP=FALSE; main() { int fd,c, res; struct termios oldtio,newtio; char buf[255]; fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY ); if (fd <0) {perror(MODEMDEVICE); exit(-1); } tcgetattr(fd,&oldtio); /* ÇöÀç ¼³Á¤À» oldtio¿¡ ÀúÀå */ bzero(&newtio, sizeof(newtio)); newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; /* set input mode (non-canonical, no echo,...) */ newtio.c_lflag = 0; newtio.c_cc[VTIME] = 0; /* ¹®ÀÚ »çÀÌÀÇ timer¸¦ disable */ newtio.c_cc[VMIN] = 5; /* ÃÖ¼Ò 5 ¹®ÀÚ ¹ÞÀ» ¶§±îÁø blocking */ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); while (STOP==FALSE) { /* loop for input */ res = read(fd,buf,255); /* ÃÖ¼Ò 5 ¹®ÀÚ¸¦ ¹ÞÀ¸¸é ¸®ÅÏ */ buf[res]=0; /* '\0' Á¾·á ¹®ÀÚ¿(printf¸¦ Çϱâ À§ÇØ) */ printf(":%s:%d\n", buf, res); if (buf[0]=='z') STOP=TRUE; } tcsetattr(fd,TCSANOW,&oldtio); }
#include <termios.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/signal.h> #include <sys/types.h> #define BAUDRATE B38400 #define MODEMDEVICE "/dev/ttyS1" #define _POSIX_SOURCE 1 /* POSIX compliant source */ #define FALSE 0 #define TRUE 1 volatile int STOP=FALSE; void signal_handler_IO (int status); /* signal handler ÇÔ¼ö Á¤ÀÇ */ int wait_flag=TRUE; /* signalÀ» ¹ÞÁö ¾ÊÀº µ¿¾ÈÀº TRUE */ main() { int fd,c, res; struct termios oldtio,newtio; struct sigaction saio; /* signal actionÀÇ Á¤ÀÇ */ char buf[255]; /* Non-blocking ¸ðµå·Î ½Ã¸®¾ó ÀåÄ¡¸¦ ¿¬´Ù(read ÇÔ¼ö È£Ãâ ÈÄ Áï°¢ ¸®ÅÏ) */ fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd <0) {perror(MODEMDEVICE); exit(-1); } /* install the signal handler before making the device asynchronous */ /* ÀåÄ¡¸¦ ºñµ¿±â ¸ðµå·Î ¸¸µé±â Àü¿¡ signal handler */ saio.sa_handler = signal_handler_IO; saio.sa_mask = 0; saio.sa_flags = 0; saio.sa_restorer = NULL; sigaction(SIGIO,&saio,NULL); /* SIGIO signalÀ» ¹ÞÀ» ¼ö ÀÖµµ·Ï ÇÑ´Ù. */ fcntl(fd, F_SETOWN, getpid()); /* file descriptor¸¦ ºñµ¿±â·Î ¸¸µç´Ù. (manual page¸¦ º¸¸é O_APPEND ¿Í O_NONBLOCK¸¸ÀÌ F_SETFL¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Ù°í µÇ¾î ÀÖ´Ù.) */ fcntl(fd, F_SETFL, FASYNC); tcgetattr(fd,&oldtio); /* save current port settings */ /* canonical ÀÔ·Â󸮸¦ À§ÇÑ Æ÷Æ® ¼¼Æà */ newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR | ICRNL; newtio.c_oflag = 0; newtio.c_lflag = ICANON; newtio.c_cc[VMIN]=1; newtio.c_cc[VTIME]=0; tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); /* loop while waiting for input. normally we would do something useful here */ while (STOP==FALSE) { printf(".\n");usleep(100000); /* after receiving SIGIO, wait_flag = FALSE, input is available and can be read */ if (wait_flag==FALSE) { res = read(fd,buf,255); buf[res]=0; printf(":%s:%d\n", buf, res); if (res==1) STOP=TRUE; /* stop loop if only a CR was input */ wait_flag = TRUE; /* wait for new input */ } } /* restore old port settings */ tcsetattr(fd,TCSANOW,&oldtio); } /*************************************************************************** * signal handler. sets wait_flag to FALSE, to indicate above loop that * * characters have been received. * ***************************************************************************/ void signal_handler_IO (int status) { printf("received SIGIO signal.\n"); wait_flag = FALSE; }
ÀÌ ¼½¼ÇÀº °£·«ÇÑ ¼³¸í¸¸À» ÇÏ°Ú´Ù. ¾î¶»°Ô ÇÏ´Â Áö¿¡ ´ëÇÑ °£´ÜÇÑ ÈùÆ®¸¸À» ÁÖ±â À§ÇÑ °ÍÀ̹ǷΠªÀº ¿¹Á¦ Äڵ常À» ´ã¾Ò´Ù. ÀÌ ¹æ¹ýÀº ½Ã¸®¾ó Æ÷Æ®¿¡¸¸ Àû¿ëµÇ´Â °ÍÀÌ ¾Æ´Ï¶ó file descriptor¸¦ »ç¿ëÇÏ´Â ¸ðµç ÀÔÃâ·Â¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
select()
½Ã½ºÅÛ È£Ãâ ÇÔ¼ö¿Í ÇØ´çÇÏ´Â ¸ÅÅ©·Î ÇÔ¼öµéÀº
fd_set
À» »ç¿ëÇÑ´Ù. fd_set
´Â bit array·Î¼
file descriptorÀÇ bit entry·Î ÀÛ¿ëÇÑ´Ù.
select()
´Â ÇØ´çÇÏ´Â file descriptorÀÇ bitµéÀ» ¼¼ÆÃÇÑ
fd_set
À» ÀÔ·Â ÆĶó¹ÌÅÍ·Î ¹Þ¾Æ¼ ÀÔ·Â, Ãâ·Â ȤÀº
¿¹¿Ü ¹ß»ýÀÌ ÀÏ¾î³ °æ¿ì ¸®ÅÏÇÑ´Ù. fd_set
˼
FD_
·Î ½ÃÀÛÇÏ´Â ¸ÅÅ©·Î ÇÔ¼öµéÀ» ÅëÇؼ °ü¸®ÇÑ´Ù.
select(2)
ÀÇ man page¸¦ ÂüÁ¶Ç϶ó.
#include <sys/time.h> #include <sys/types.h> #include <unistd.h> main() { int fd1, fd2; /* input sources 1 and 2 */ fd_set readfs; /* file descriptor set */ int maxfd; /* maximum file desciptor used */ int loop=1; /* loop while TRUE */ /* open_input_source opens a device, sets the port correctly, and returns a file descriptor */ fd1 = open_input_source("/dev/ttyS1"); /* COM2 */ if (fd1<0) exit(0); fd2 = open_input_source("/dev/ttyS2"); /* COM3 */ if (fd2<0) exit(0); maxfd = MAX (fd1, fd2)+1; /* maximum bit entry (fd) to test */ /* loop for input */ while (loop) { FD_SET(fd1, &readfs); /* set testing for source 1 */ FD_SET(fd2, &readfs); /* set testing for source 2 */ /* block until input becomes available */ select(maxfd, &readfs, NULL, NULL, NULL); if (FD_ISSET(fd1, &readfs)) /* input from source 1 available */ handle_input_from_source1(); if (FD_ISSET(fd2, &readfs)) /* input from source 2 available */ handle_input_from_source2(); } }
À§ÀÇ ¿¹Á¦ ÄÚµå´Â ÀÔ·ÂÀÌ µé¾î¿Ã ¶§±îÁö °è¼Ó block µÇ´Â µ¿ÀÛÀ» º¸¿©ÁØ´Ù. Time-outÀÌ ÇÊ¿äÇÏ´Ù¸é, ´ÙÀ½°ú °°ÀÌ ¹Ù²Û´Ù.
int res; struct timeval Timeout; /* set timeout value within input loop */ Timeout.tv_usec = 0; /* milliseconds */ Timeout.tv_sec = 1; /* seconds */ res = select(maxfd, &readfs, NULL, NULL, &Timeout); if (res==0) /* number of file descriptors with input = 0, timeout occurred. */ÀÌ ¿¹Á¦´Â 1ÃÊ ÈÄ¿¡ time-outÀÌ µÇ´Â °ÍÀ» º¸¿©ÁØ´Ù. Time-outÀÌ ÀϾ¸é
select()
´Â 0À» ¹ÝȯÇÑ´Ù. ¿©±â¼ ÁÖÀÇÇÒ Á¡Àº,
¼³Á¤ÇÑ Timeout
°ªÀº select()
¿¡ ÀÇÇؼ °¨¼ÒÇϱ⠶§¹®¿¡
´Ù½Ã select()
¸¦ È£ÃâÇÑ´Ù¸é Timeout.tv_usec
°ú
Timeout.tv_sec
°ªÀ» ´Ù½Ã ¼³Á¤ÇØ¾ß ÇÑ´Ù.
Timeout
°ªÀÌ 0ÀÌ µÇ¸é time-outÀÌ ¹ß»ýÇÏ°í
select()
´Â Áï½Ã ¸®ÅϵȴÙ.