¿©±âÀÇ ¸ðµç ¿¹Á¦´Â 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()´Â Áï½Ã ¸®ÅϵȴÙ.