The Linux Serial Programming HOWTO ¸®´ª½º ½Ã¸®¾ó ÇÁ·Î±×·¡¹Ö ÇÏ¿ìÅõ Peter H. Baumann, Peter.Baumann@dir.de v1.0, 22 January 1998 Àü¼º¹Î, schun@crypto.pe.kr 2000³â 2¿ù 24ÀÏ ÀÌ ¹®¼­´Â ¸®´ª½º ½Ã½ºÅÛ¿¡¼­ ½Ã¸®¾ó Åë½ÅÀ» ¾î¶»°Ô ÇÁ·Î±×·¡¹ÖÇϴ°¡¸¦ ¼³¸íÇÏ´Â ÇÏ¿ìÅõ ¹®¼­ÀÌ´Ù. ______________________________________________________________________ ¸ñÂ÷ 1. ¼Ò°³ 1.1 ÀúÀÛ±Ç 1.2 ÀÌ ¹®¼­ÀÇ ÃֽŠ¹öÀü 1.3 Feedback 2. ½ÃÀÛÇϱâ 2.1 µð¹ö±ë 2.2 Æ÷Æ® ¼¼Æà 2.3 ½Ã¸®¾ó ÀåÄ¡ÀÇ ÀÔ·Â ¹æ¹ý 2.3.1 Canonical ÀԷ ó¸®(Canonical Input Processing) 2.3.2 Non-Canonical ÀԷ ó¸®(Non-Canonical Input Processing) 2.3.3 ºñµ¿±â ÀÔ·Â 2.3.4 ÀÔ·ÂÀåÄ¡ ¸ÖƼÇ÷º½Ì 3. ÇÁ·Î±×·¥ ¿¹Á¦ 3.1 Canonical ÀԷ ó¸®(Canonical Input Processing) 3.2 Non-Canonical ÀԷ ó¸®(Non-Canonical Input Processing) 3.3 ºñµ¿±â ÀÔ·Â 3.4 ÀÔ·Â ÀåÄ¡ ¸ÖƼÇ÷º½Ì 4. ´Ù¸¥ À¯¿ëÇÑ Á¤º¸ 5. ±â¿©ÇÑ »ç¶÷µé ______________________________________________________________________ 1. ¼Ò°³ ÀÌ ¹®¼­´Â ¸®´ª½º ½Ã½ºÅÛ¿¡¼­ ½Ã¸®¾ó Åë½ÅÀ» ¾î¶»°Ô ÇÁ·Î±×·¡¹ÖÇϴ°¡¸¦ ¼³¸íÇÏ´Â ÇÏ¿ìÅõ ¹®¼­ÀÌ´Ù. ´Ù¾çÇÑ ½Ã¸®¾ó Åë½Å ÇÁ·Î±×·¥ ±â¹ýµé(Canonical I/O, ºñµ¿±â I/O, I/O ¸ÖƼÇ÷º½Ì)À» ¼³¸íÇÑ´Ù. ½Ã¸®¾ó Æ÷Æ®¸¦ ¼Â¾÷ÇÏ´Â ¹æ¹ý¿¡ ´ëÇؼ­´Â Greg HankinsÀÇ Serial-HOWTO ¹®¼­¸¦ Àо±â ¹Ù¶õ´Ù. ³ª´Â ÀÌ ºÐ¾ßÀÇ Àü¹®°¡°¡ ¾Æ´ÔÀ» ¸ÕÀú ¹àÇôµÐ´Ù. ±×·¯³ª ÇÁ·ÎÁ§Æ®¸¦ Çϸ鼭 ¸¹Àº ¹®Á¦µé¿¡ ºÎµúÇû´Ù. ÀÌ ¹®¼­¿¡ ¼Ò°³µÈ ÄÚµå ¿¹Á¦µéÀº LDP(Linux Document Project) ÇÁ·Î±×·¡¸Ó °¡À̵å(ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers- guide/lpg-0.4.tar.gz ¹× ¹Ì·¯ »çÀÌÆ®µé)¿¡¼­ ±¸ÇÒ ¼ö ÀÖ´Â miniterm code¿¡ ±Ù°ÅÇÏ¿© ¸¸µé¾ú´Ù. 1997³â 6¿ù¿¡ ÀÌ ¹®¼­¸¦ ÀÛ¼ºÇÑ µÚ¿¡ ³ª´Â °í°´ÀÇ ¿ä±¸¿¡ ÀÇÇØ Win NT ȯ°æÀ¸·Î ¿Å±â°Ô µÇ¾î¼­ ´õ ÀÌ»ó ±íÀº Áö½ÄÀ» ¾òÀ» ¼ö ¾ø¾ú´Ù. ´©±¸µçÁö Ä¿¸ÇÆ®°¡ ÀÖÀ¸¸é ÀÌ ¹®¼­¸¦ °ü¸®Çϴµ¥¿¡ ±â²¨ÀÌ È°¿ëÇÏ°Ú´Ù.(Feedback ºÎºÐÀ» º¼ °Í) ¶ÇÇÑ ÀÌ ¹®¼­ÀÇ À¯Áö ¹× °ü¸®¸¦ ¸Ã°í ½Í°Å³ª version UPÀ» ¿øÇÑ´Ù¸é e-mailÀ» Áֱ⠹ٶõ´Ù. ÀÌ ¹®¼­ÀÇ ¸ðµç ¿¹Á¦´Â i386 Linux Kernel 2.0.29¿¡¼­ Å×½ºÆ®¸¦ ÇÏ¿´´Ù. 1.1. ÀúÀÛ±Ç The Linux Serial-Programming-HOWTO is copyright (C) 1997 by Peter Baumann. Linux HOWTO documents may be reproduced and distributed in whole or in part, in any medium physical or electronic, as long as this copyright notice si retained on all copies. Commercial redistribution is allowed and encouraged; however, the author would like to be notified of any such distributions. All translations, derivative works, or aggregate works incorporating any Linux HOWTO documents must be covered under this copyright notice. That is, you may not produce a derivative work from a HOWTO and impose additional restrictions on its distribution. Exceptions to thes rules may be granted under certain conditions; please contact the Linux HOWTO coordinator at the address given below. In short, we wish to promote dissemination of this information through as many channels as possible. However, we do wish to retain copyright on the HOWTO documents, and would like to be notified of any plans to redistribute the HOWTOs. If you have questions, please contact Tim Bynum, the Linux HOWTO coordinator, at linux-howto@sunsite.unc.edu via email. 1.2. ÀÌ ¹®¼­ÀÇ ÃֽŠ¹öÀü ÀÌ ¹®¼­ÀÇ ÃֽŠ¹öÀüÀº ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/Serial-Programming-HOWTO ¿Í ¹Ì·¯ »çÀÌÆ®¿¡¼­ ãÀ» ¼ö ÀÖ´Ù. PostScript ¹× DVI ¹öÀüµµ ´Ù¸¥ Æ÷¸ËµéÀ» °®°í ÀÖ´Â µð·ºÅ丮¿¡ ÀÖ´Ù. http://sunsite.unc.edu/LDP/HOWTO/Serial- Programming-HOWTO.html ¿¡¼­µµ ±¸ÇÒ ¼ö ÀÖÀ¸¸ç, comp.os.linux.answers¿¡ ¸Å´Þ Æ÷½ºÆà µÉ °ÍÀÌ´Ù. 1.3. Feedback ¿À·ù, Áú¹®, Ä¿¸ÇÆ®, °ÇÀÇ»çÇ×À̳ª ±× ¿Ü Ãß°¡ÇÒ »çÇ×ÀÌ ÀÖ´Ù¸é ¾Ë·ÁÁֱ⠹ٶõ´Ù. ÀÌ HOWTO¸¦ °è¼ÓÀûÀ¸·Î ¾÷µ¥ÀÌÆ® Çϱ⸦ ¿øÇÑ´Ù. ´ç½ÅÀÌ Á¤È®È÷ ÀÌÇØÇÏÁö ¸øÇÏ´Â ºÎºÐÀÌ Àְųª ´õ ¸íÈ®ÇØ¾ß ÇÒ ºÎºÐÀÌ ÀÖ´Ù¸é ¾Ë·ÁÁà¶ó. ³» e-mail ÁÖ¼Ò´Â Peter.Baumann@dir.de ÀÌ´Ù. ÀÌ ¹®¼­¿¡ °üÇÑ e-mailÀ» º¸³¾ ¶§´Â ¹®¼­ÀÇ ¹öÀüµµ °°ÀÌ ¾Ë·ÁÁà¶ó. ÀÌ ¹®¼­ ¹öÀüÀº 1.0ÀÌ´Ù. 2. ½ÃÀÛÇϱâ 2.1. µð¹ö±ë Äڵ带 µð¹ö±ëÇÏ´Â °¡Àå ÁÁÀº ¹æ¹ýÀº ¶Ç ÇϳªÀÇ ¸®´ª½º ¹Ú½º¸¦ ¼Â¾÷ÇÏ°í µÎ ¸®´ª½º ¹Ú½º¸¦ null-modem ÄÉÀ̺í·Î ¿¬°áÇÏ´Â °ÍÀÌ´Ù. Miniterm ÇÁ·Î±×·¥À» ÀÌ¿ëÇÏ¿© ¹®ÀÚµéÀ» Àü¼ÛÇغ¸¶ó. MinitermÀº ÄÄÆÄÀÏÇϱ⵵ ½±°í, Å°º¸µå¿¡¼­ ÀԷµǴ ¹®ÀÚµé(Ư¼ö¹®ÀÚ Æ÷ÇÔ)À» ½Ã¸®¾ó Æ÷Æ®·Î Àü¼ÛÇÒ ¼ö ÀÖ´Ù. ÄÄÆÄÀÏÇÒ ¶§ üũÇØ¾ß ÇÒ °ÍÀº #define MODEMDEVICE "/dev/ttyS0" ¹®ÀåÀÌ Á¦´ë·Î ¼³Á¤µÇ¾î Àִ°¡ ÇÏ´Â °ÍÀÌ´Ù. COM1À¸·Î ¸ÂÃß·Á¸é /dev/ttyS0, COM2·Î ÇÏ·Á¸é /dev/ttyS1À¸·Î ¼öÁ¤ÇÑ´Ù. Å×½ºÆÃÀ» ÇÒ ¶§ °¡Àå Áß¿äÇÑ °ÍÀº ¹®ÀÚ°¡ ½Ã¸®¾ó Æ÷Æ®·Î Ãâ·ÂµÉ ¶§ µ¥ÀÌÅÍ°¡ Ãâ·Â µ¥ÀÌÅÍ Ã³¸®(output processing)À» ÇÏÁö ¾Ê°í ±×´ë·Î(raw) Àü¼ÛÀÌ µÇ´Â°¡¸¦ È®ÀÎÇÏ´Â °ÍÀÌ´Ù. Å×½ºÆ® °úÁ¤Àº ´ÙÀ½°ú °°´Ù. µÎ ´ëÀÇ ¸®´ª½º ¹Ú½º¿¡¼­ °¢°¢ miniterm ÇÁ·Î±×·¥À» ½ÇÇà½ÃÅ°°í Å°º¸µå¸¦ Ãĺ»´Ù. ÇÑ °÷¿¡¼­ ŸÀÌÇÎÇÑ ¹®ÀÚ°¡ ´Ù¸¥ °÷¿¡¼­ ±×´ë·Î ³ªÅ¸³ª´Â Áö È®ÀÎÇÑ´Ù. Null-modem ÄÉÀ̺íÀÇ TxD¿Í RxD°¡ ¼­·Î cross ¿¬°áÀÌ µÇ¾î¾ß ÇÑ´Ù. Àß ¸ð¸£°ÚÀ¸¸é Serial-HOWTO ¹®¼­ÀÇ 7ÀåÀ» º»´Ù. À§ÀÇ Å×½ºÆ®´Â ÇÑ ´ëÀÇ ÄÄÇ»Å͸¸ °®°íµµ °¡´ÉÇÏ´Ù. »ç¿ëÇÒ ¼ö ÀÖ´Â ½Ã¸®¾ó Æ÷Æ®°¡ µÎ °³ ÀÖ´Ù¸é ÄÉÀ̺íÀ» °¢°¢ÀÇ ½Ã¸®¾ó Æ÷Æ®¿¡ ¿¬°áÇÏ°í minitermÀ» µÎ °³ ½ÇÇàÇÏ¿© Å×½ºÆ®ÇÏ¸é µÈ´Ù. 2.2. Æ÷Æ® ¼¼Æà ÀåÄ¡ ÆÄÀÏÀÎ /dev/ttyS*´Â ¸®´ª½º¿¡¼­ Å͹̳ÎÀ» ¿¬°áÇϱâ À§ÇÑ ¸ñÀûÀ¸·Î »ç¿ëµÈ´Ù. ÀÌ »ç½ÇÀº ½Ã¸®¾ó Åë½Å ÇÁ·Î±×·¡¹ÖÀ» Çϴµ¥ ¹Ýµå½Ã ±â¾ïÇØ¾ß ÇÒ »çÇ×ÀÌ´Ù. ¿¹¸¦ µé¾î, ½Ã¸®¾ó Æ÷Æ®µµ ¹®ÀÚ ¿¡ÄÚ¸¦ Çϵµ·Ï ¼³Á¤µÇ¾î ÀÖ´Ù. ÀÌ ¼³Á¤Àº º¸Åë µ¥ÀÌÅÍ Àü¼Û½Ã¿¡ ¹Ù²ã¾ß ÇÒ »çÇ×ÀÌ´Ù. (¿ªÀÚ ÁÖ: ½Ã¸®¾ó ÀåÄ¡ ÆÄÀϵµ Å͹̳ΠÀåÄ¡·Î ºÐ·ùµÇ±â ¶§¹®¿¡ Ãʱ⠼³Á¤Àº ÀÏ¹Ý Å͹̳ο¡¼­ »ç¿ëµÇ´Â ¿¡ÄÚ°¡ µÇµµ·Ï ¼³Á¤µÇ¾î ÀÖ´Â °ÍÀÌ´Ù.) ¸ðµç ÆĶó¹ÌÅ͵éÀº ÇÁ·Î±×·¥ Äڵ忡¼­ ½±°Ô ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ÆĶó¹ÌÅ͵éÀº ¿¡ Á¤ÀǵǾî ÀÖ´Â struct termios ±¸Á¶Ã¼¿¡ ÀúÀåµÇ¾î ÀÖ´Ù. #define NCCS 19 struct termios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ tcflag_t c_cflag; /* control mode flags */ tcflag_t c_lflag; /* local mode flags */ cc_t c_line; /* line discipline */ cc_t c_cc[NCCS]; /* control characters */ }; ÀÌ ÆÄÀÏÀº ¸ðµç flagµéÀ» Á¤ÀÇÇÏ°í ÀÖ´Ù. c_iflag(ÀÔ·Â ¸ðµå flag)´Â ¸ðµç ÀԷ ó¸®(input processing)¸¦ Á¤ÀÇÇÑ´Ù. ÀԷ ó¸®¶õ read() ÇÔ¼ö¿¡ ÀÇÇØ ½Ã¸®¾ó Æ÷Æ®·Î µé¾î¿Â µ¥ÀÌÅ͸¦ read¿¡ ÀÇÇØ Àбâ Àü¿¡ µ¥ÀÌÅ͵éÀ» c_iflag¿¡ Á¤ÀÇÇÑ ´ë·Î ó¸®ÇÏ´Â °ÍÀ» ÀǸ¶ÇÑ´Ù. c_oflag(Ãâ·Â ¸ðµå flag)´Â Ãâ·Â ó¸®(output processing) ÇÏ´Â ¹æ¹ýÀ» Á¤ÀÇÇÑ´Ù. c_cflag(Á¦¾î ¸ðµå flag)´Â baudrate, data bits, stop bits µîÀÇ Æ÷Æ® ¼¼ÆÃÀ» Á¤ÀÇÇÑ´Ù. c_lflag(local ¸ðµå flag)´Â echo¸¦ ÇÒ °ÍÀÎÁö µîÀ» °áÁ¤ÇÑ´Ù. ¸¶Áö¸·À¸·Î c_cc(Á¦¾î ¹®ÀÚ) ¹è¿­Àº EOF(End of File), STOP µîÀÇ Á¦¾î µ¿ÀÛµéÀ» ¾î¶² ¹®ÀÚ·Î Á¤ÀÇÇÒ °ÍÀΰ¡¸¦ ¼³Á¤ÇÑ´Ù. Á¦¾î ¹®ÀÚÀÇ µðÆúÆ® ¹®ÀÚ´Â ¿¡ Á¤ÀǵǾî ÀÖ´Ù. À§ flagµé¿¡ °üÇÑ ¼³¸íÀº termios(3) man page¿¡ ³ª¿ÍÀÖ´Ù. termios ±¸Á¶Ã¼ÀÇ c_line Ç׸ñÀº POSIX ȣȯ ½Ã½ºÅÛ¿¡¼­ »ç¿ëµÇÁö ¾Ê´Â´Ù. 2.3. ½Ã¸®¾ó ÀåÄ¡ÀÇ ÀÔ·Â ¹æ¹ý ÀÌ ¼½¼Ç¿¡¼­´Â ¼¼ °¡ÁöÀÇ ÀÔ·Â ¹æ¹ýÀ» ±â¼úÇϱâ·Î ÇÑ´Ù. ÀÀ¿ë ºÐ¾ß¿¡ µû¶ó¼­ ¾Ë¸ÂÀº ¹æ¹ýÀ» »ç¿ëÇØ¾ß ÇÑ´Ù. ÇÑ ¹®ÀÚ¾¿ Àд ·çÇÁ¸¦ µ¹·Á¼­ Àüü ¹®ÀÚ¿­À» ¹Þ´Â ¹æ¹ýÀº °¡´ÉÇÏ´Ù¸é ÇÇÇØ¾ß ÇÑ´Ù. ³»°¡ ÀÌ·± ¹æ¹ýÀ¸·Î ÇßÀ» ¶§, ¹®ÀÚ¸¦ ÀÒ¾î¹ö¸®´Â °æ¿ì°¡ »ý±ä ¹Ý¸é, Àüü ¹®ÀÚ¿­À» Çѹø¿¡ ÀÐÀ» ¶§´Â ¿¡·¯°¡ ¹ß»ýÇÏÁö ¾Ê¾Ò´Ù. 2.3.1. Canonical ÀԷ ó¸®(Canonical Input Processing) Canonical ÀԷ ó¸®´Â Å͹̳ÎÀÇ ±âº» ó¸® ¹æ¹ýÀÌ´Ù. ÀÌ ¹æ¹ýÀº ÇÑ ÁÙ ´ÜÀ§·Î ó¸®ÇÏ´Â ´Ù¸¥ ÇÁ·Î±×·¥°ú Åë½ÅÇϴµ¥¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÇÑ ÁÙÀº µðÆúÆ®·Î NL(New Line, ASCII´Â LF) ¹®ÀÚ, EOF(End of File) ¹®ÀÚ, ȤÀº EOL(End of Line)¿¡ ÀÇÇØ Á¾·áµÇ´Â ¹®ÀÚ¿­À» ÀǹÌÇÑ´Ù. CR(Carriage Return, DOS/WindowsÀÇ µðÆúÆ® EOL ¹®ÀÚÀÓ) ¹®ÀÚ´Â µðÆúÆ® ¼¼Æÿ¡¼­ ÇÑ ÁÙÀÇ Á¾·á ¹®ÀÚ·Î ÀνĵÇÁö ¾Ê´Â´Ù. ¶ÇÇÑ Canonical ÀԷ ó¸® ¸ðµå¿¡¼­´Â ERASE, DELETE WORD, REPRINT CHARACTERS ¹®ÀÚµéÀ» ó¸®ÇÒ ¼ö ÀÖ°í, CR ¹®ÀÚ¸¦ NL ¹®ÀÚ·Î º¯È¯ 󸮸¦ ÇÒ ¼ö ÀÖ´Ù. 2.3.2. Non-Canonical ÀԷ ó¸®(Non-Canonical Input Processing) Non-Canonical ÀԷ ó¸® ¸ðµå¿¡¼­´Â ÇÑ ¹ø ÀÐÀ» ¶§¸¶´Ù Á¤ÇØÁø Å©±âÀÇ ¹®ÀÚ¸¸À» Àо ¼ö ÀÖ´Ù. ¶ÇÇÑ Å¸À̸Ӹ¦ µÎ¾î¼­ ÀÏÁ¤ ½Ã°£±îÁö read()°¡ ¸®ÅÏÇÏÁö ¾Ê´Â °æ¿ì °­Á¦ ¸®ÅÏÀ» ÇÒ ¼ö ÀÖ´Ù. ÀÌ ¸ðµå´Â Ç×»ó Á¤ÇØÁø Å©±âÀÇ ¹®Àڵ鸸À» Àо°Å³ª ´ë·®ÀÇ ¹®ÀÚµéÀ» Àü¼ÛÇÏ°íÀÚ ÇÒ ¶§ »ç¿ëÇÑ´Ù. 2.3.3. ºñµ¿±â ÀÔ·Â À§¿¡¼­ ¼³¸íÇÑ µÎ °¡Áö ¸ðµå´Â µ¿±â ¹æ½ÄÀ̳ª ºñµ¿±â ¹æ½ÄÀ¸·Î »ç¿ëµÉ ¼ö ÀÖ´Ù. µ¿±â ¹æ½ÄÀº readÀÇ Á¶°ÇÀÌ ¸¸Á·µÉ ¶§±îÁö blockµÇ´Â ¹æ½ÄÀ¸·Î¼­ µðÆúÆ®·Î ¼³Á¤µÇ¾î ÀÖ´Ù. ºñµ¿±â ¹æ½Ä¿¡¼­´Â read() ÇÔ¼ö°¡ ¹Ù·Î ¸®ÅϵǸç, È£ÃâÇÑ ÇÁ·Î±×·¥¿¡°Ô signalÀ» º¸³½´Ù. ÀÌ signalÀº signal handler(½Ã±×³Î ó¸® ÇÔ¼ö)·Î º¸³»Áø´Ù. 2.3.4. ÀÔ·ÂÀåÄ¡ ¸ÖƼÇ÷º½Ì À§¿¡¼­ ¼³¸íÇÑ ÀÔ·Â ¸ðµå¿¡ ÇØ´çÇÏÁø ¾ÊÁö¸¸ ¿©·¯ °³ÀÇ ÀåÄ¡µéÀ» ´Ù·ç°íÀÚ ÇÒ ¶§ À¯¿ëÇÏ´Ù. ¿¹¸¦ µé¾î ³» ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼­ TCP/IP ¼ÒÄÏ°ú ½Ã¸®¾ó Åë½Å¿¡¼­ µ¿½Ã¿¡ ÀÔ·ÂÀ» ¹Þ¾Æ¾ß Çß´Ù. ¾Æ·¡ 3.4ÀÇ ¿¹Á¦´Â µÎ °³ÀÇ ¼­·Î ´Ù¸¥ ÀåÄ¡·ÎºÎÅÍ µ¿½Ã¿¡ ÀÔ·ÂÀ» ±â´Ù¸®´Â ÄÚµåÀÌ´Ù. µÑ Áß ÇÑ °³ÀÇ ÀåÄ¡¿¡¼­ ÀÔ·ÂÀÌ µé¾î¿À¸é 󸮸¦ ÇÏ°í ¶Ç ´Ù½Ã »õ·Î¿î ÀÔ·ÂÀÌ ¿Ã ¶§±îÁö ±â´Ù¸°´Ù. ¾Æ·¡ 3.4ÀÇ ¿¹Á¦´Â º¹ÀâÇØ º¸ÀÏ ¼ö ÀÖÁö¸¸, ¸®´ª½º°¡ multi-processing OSÀÓÀ» ¾Ë°í Àֱ⿡ ¸Å¿ì Áß¿äÇÏ´Ù. select() ½Ã½ºÅÛ È£Ãâ ÇÔ¼ö´Â ÀÔ·ÂÀ» ±â´Ù¸®´Â µ¿¾È CPU¿¡ ºÎÇϸ¦ ÁÖÁö ¾Ê´Â´Ù. ¹Ý¸é ÀÔ·ÂÀÌ µé¾î¿Ô´ÂÁö ·çÇÁ¸¦ µ¹¸é¼­ üũÇÏ´Â polling ¹æ½ÄÀº ½Ã½ºÅÛ¿¡ ºÎÇϸ¦ ÁÖ°Ô µÇ¾î ´Ù¸¥ ÇÁ·Î¼¼½ºÀÇ ¼öÇà ¼Óµµ¸¦ ÀúÇϽÃÅ°°Ô µÈ´Ù. 3. ÇÁ·Î±×·¥ ¿¹Á¦ ¿©±âÀÇ ¸ðµç ¿¹Á¦´Â miniterm.c¿¡¼­ µû¿Ô´Ù. Canonical ÀԷ ó¸®¿¡¼­ ó¸®ÇÒ ¼ö ÀÖ´Â ÃÖ´ë ±æÀÌÀÇ ¹®ÀÚ´Â 255°³( ȤÀº ¿¡ Á¤ÀǵÊ) ·Î¼­ ¹öÆÛÀÇ ÃÖ´ë ±æÀÌ´Â 255·Î Á¦ÇѵȴÙ. ¿©·¯ ÀԷ ó¸® ¸ðµåÀÇ »ç¿ë¹ý¿¡ ´ëÇÑ ¼³¸íÀ» ¿øÇϸé ÄÚµå ³»ÀÇ comment¸¦ ÂüÁ¶Ç϶ó. Äڵ尡 ÀÌÇØÇϱ⠽±±â¸¦ ¹Ù¶õ´Ù. Canonical ÀԷ ó¸® ¸ðµåÀÇ ¿¹Á¦´Â comment¸¦ °¡Àå Àß Çسõ¾Ò´Ù. ´Ù¸¥ ¿¹Á¦´Â canonical ¸ðµå ¿¹Á¦¿Í ´Ù¸¥ ºÎºÐ¿¡¸¸ comment¸¦ ´Þ¾Ò´Ù. ¼³¸íÀÌ ¿Ïº®ÇÏÁø ¾ÊÁö¸¸, ÀÌ ¿¹Á¦·Î Á÷Á¢ Å×½ºÆ®¸¦ Çغ¸¸é ´ç½ÅÀÇ ÇÁ·Î±×·¥¿¡ Àû¿ëÇÒ ¶§ ÃÖÀûÀÇ ¹æ¹ýÀ» ãÀ» ¼ö ÀÖÀ» °ÍÀÌ´Ù. ½Ã¸®¾ó Æ÷Æ® ÀåÄ¡ ÆÄÀÏÀÇ ¼±ÅÃÀ» Á¦´ë·Î Çߴ°¡¸¦ ´Ù½Ã ÇÑ ¹ø È®ÀÎÇÏ°í, ÆÄÀÏ Á¢±Ù Çã°¡´Â Á¦´ë·Î µÇ¾î ÀÖ´ÂÁö º¸±â¸¦ ¹Ù¶õ´Ù. (¿¹: chmod a+rw /dev/ttyS1) 3.1. Canonical ÀԷ ó¸®(Canonical Input Processing) #include #include #include #include #include /* Baudrate ¼³Á¤Àº ¿¡ Á¤ÀǵǾî ÀÖ´Ù. /* ´Â ¿¡¼­ 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) µ¥ÀÌÅÍ Àü¼Û ½Ã¿¡ -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; /* ¸ðµç Á¦¾î ¹®ÀÚµéÀ» ÃʱâÈ­ÇÑ´Ù. µðÆúÆ® °ªÀº Çì¾î ÆÄÀÏ¿¡¼­ ãÀ» ¼ö ÀÖ´Ù. ¿©±â 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); } 3.2. Non-Canonical ÀԷ ó¸®(Non-Canonical Input Processing) Non-Canonical ÀԷ ó¸® ¸ðµå¿¡¼­´Â ÀÔ·ÂÀÌ ÇÑ ÁÙ ´ÜÀ§·Î 󸮵ÇÁö ¾Ê´Â´Ù. erase, kill, delete µîÀÇ ÀԷ ó¸®µµ ¼öÇàµÇÁö ¾Ê´Â´Ù. ÀÌ ¸ðµå¿¡¼­ ¼³Á¤ÇÏ´Â ÆĶó¹ÌÅÍ´Â c_cc[VTIME]°ú c_cc[VMIN] µÎ °¡ÁöÀÌ´Ù. c_cc[VTIME]Àº ŸÀ̸ÓÀÇ ½Ã°£À» ¼³Á¤ÇÏ°í, c_cc[VMIN]Àº readÇÒ ¶§ ¸®ÅϵDZâ À§ÇÑ ÃÖ¼ÒÀÇ ¹®ÀÚ °³¼ö¸¦ ÁöÁ¤ÇÑ´Ù. MIN > 0, TIME = 0 MINÀº read°¡ ¸®ÅϵDZâ À§ÇÑ ÃÖ¼ÒÇÑÀÇ ¹®ÀÚ °³¼ö. TIMEÀÌ 0À̸é ŸÀ̸Ӵ »ç¿ëµÇÁö ¾Ê´Â´Ù.(¹«ÇÑ´ë·Î ±â´Ù¸°´Ù.) MIN = 0, TIME > 0 TIMEÀº time-out °ªÀ¸·Î »ç¿ëµÈ´Ù. Time-out °ªÀº TIME * 0.1 ÃÊÀÌ´Ù. Time-outÀÌ ÀϾ±â Àü¿¡ ÇÑ ¹®ÀÚ¶óµµ µé¾î¿À¸é read´Â ¸®ÅϵȴÙ. MIN > 0, TIME > 0 TIMEÀº time-outÀÌ ¾Æ´Ñ inter-character ŸÀ̸ӷΠµ¿ÀÛÇÑ´Ù. ÃÖ¼Ò MIN °³ÀÇ ¹®ÀÚ°¡ µé¾î¿À°Å³ª µÎ ¹®ÀÚ »çÀÌÀÇ ½Ã°£ÀÌ TIME °ªÀ» ³ÑÀ¸¸é ¸®ÅϵȴÙ. ¹®ÀÚ°¡ óÀ½ µé¾î¿Ã ¶§ ŸÀ̸Ӵ µ¿ÀÛÀ» ½ÃÀÛÇÏ°í ÀÌÈÄ ¹®ÀÚ°¡ µé¾î¿Ã ¶§¸¶´Ù Àç½ÃÀ۵ȴÙ. MIN = 0, TIME = 0 read´Â Áï½Ã ¸®ÅϵȴÙ. ÇöÀç ÀÐÀ» ¼ö ÀÖ´Â ¹®ÀÚÀÇ °³¼ö³ª ¿äûÇÑ ¹®ÀÚ °³¼ö°¡ ¹ÝȯµÈ´Ù. Antonino¾¾¿¡ ÀÇÇϸé readÇϱâ Àü¿¡ fcntl(fd, F_SETFL, FNDELAY); ¸¦ È£ÃâÇÏ¸é ¶È°°Àº °á°ú¸¦ ¾òÀ» ¼ö ÀÖ´Ù. newtio.c_cc[VTIME]°ú newtio.c_cc[VMIN]À» ¼öÁ¤ÇÏ¿© À§ ³× °¡Áö ¹æ½ÄÀ» Å×½ºÆ® ÇÒ ¼ö ÀÖ´Ù. #include #include #include #include #include #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); } 3.3. ºñµ¿±â ÀÔ·Â #include #include #include #include #include #include #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; } 3.4. ÀÔ·Â ÀåÄ¡ ¸ÖƼÇ÷º½Ì ÀÌ ¼½¼ÇÀº °£·«ÇÑ ¼³¸í¸¸À» ÇÏ°Ú´Ù. ¾î¶»°Ô ÇÏ´Â Áö¿¡ ´ëÇÑ °£´ÜÇÑ ÈùÆ®¸¸À» ÁÖ±â À§ÇÑ °ÍÀ̹ǷΠªÀº ¿¹Á¦ Äڵ常À» ´ã¾Ò´Ù. ÀÌ ¹æ¹ýÀº ½Ã¸®¾ó Æ÷Æ®¿¡¸¸ Àû¿ëµÇ´Â °ÍÀÌ ¾Æ´Ï¶ó 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 #include #include 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()¸¦ È£ÃâÇÑ´Ù¸é Time­ out.tv_usec°ú Timeout.tv_sec °ªÀ» ´Ù½Ã ¼³Á¤ÇØ¾ß ÇÑ´Ù. Timeout °ªÀÌ 0ÀÌ µÇ¸é time-outÀÌ ¹ß»ýÇÏ°í select()´Â Áï½Ã ¸®ÅϵȴÙ. 4. ´Ù¸¥ À¯¿ëÇÑ Á¤º¸ o Serial-HOWTO ¹®¼­´Â ½Ã¸®¾ó Æ÷Æ®¸¦ ¾î¶»°Ô ¼Â¾÷ÇÏ´ÂÁö¸¦ ¼³¸íÇÏ°í Çϵå¿þ¾î Á¤º¸¸¦ Á¦°øÇÑ´Ù. o Michael SweetÀÇ Serial Programming Guide for POSIX Compliant Operating Systems . ÀÌ ¸µÅ©´Â ¿¾³¯ °ÍÀÌ°í ÃֽŠÀ§Ä¡¸¦ ãÀ» ¼ö°¡ ¾ø´Ù. À̰Šã¾ÆÁÙ ºÐ ´©±¸ ¾ø¼ö? ÀÌ ¹®¼­´Â ¸Å¿ì Àß Á¤¸®µÈ °ÍÀÌ´Ù. (¿ªÀÚ ÁÖ: ´Ù½Ã ÀÌ À§Ä¡°¡ ºÎÈ°Çß´Ù. ¿¹Àü¿¡ Àá½Ã Æó¼âµÈ ÀûÀÌ ÀÖ¾ú´Ù.) o termios(3) man page´Â termios ±¸Á¶Ã¼ÀÇ ¸ðµç flag¿¡ ´ëÇØ Á¤ÀǵǾî ÀÖ´Ù. 5. ±â¿©ÇÑ »ç¶÷µé 1ÀåÀÇ ¼Ò°³ ºÎºÐ¿¡¼­ ¾ð±ÞÇßµíÀÌ, ³ª´Â ÀÌ ºÐ¾ßÀÇ Àü¹®°¡°¡ ¾Æ´Ï´Ù. ±×·¯³ª ¿©·¯ ¹®Á¦¿¡ ºÎµúÇû¾ú°í, ´Ù¸¥ À̵éÀÇ µµ¿òÀ» ¹Þ¾Æ¼­ ¹®Á¦µéÀ» ÇØ°áÇß´Ù. Strudthoff ¾¾, Michael Carter(mcarter@rocke.electro.swri.edu)¾¾ ¹× Peter Walternberg(p.waltenberg@karaka.chch.cri.nz) ¾¾ÀÇ µµ¿ò¿¡ °¨»çÇÑ´Ù. Antonino Ianella(antonino@usa.net)¾¾´Â ³»°¡ ÀÌ ¹®¼­¸¦ ÀÛ¼ºÇÒ ¶§ Serial-Port-Programming Mini HOWTO¸¦ ½è´Ù. Greg Hankins¾¾´Â AntoninoÀÇ Mini-HOWTO¸¦ ÀÌ ¹®¼­¿¡ ³ÖÀ¸¶ó°í ±ÇÇß´Ù. ÀÌ ¹®¼­ÀÇ ±¸Á¶¿Í SGML Æ÷¸ËÀº Greg Hankins¾¾ÀÇ Serial-HOWTO¿¡¼­ µû¿Ô´Ù. ÀÌ ±Û¿¡¼­ ¿À·ù¸¦ ¼öÁ¤ÇÒ ¼ö ÀÖµµ·Ï µµ¿ÍÁֽŠ¸¹Àº ºÐµéÀÌ ÀÖ´Ù. Dave Pfaltzgraff(Dave_Pfaltzgraff@patapsco.com), Sean Lincolne(slincol@tpgi.com.au), Michael Wiedmann(mw@miwie.in- berlin.de), Adrey Bonar(andy@tipas.lt) ¾¾¿¡°Ô °¨»çÇÑ´Ù.