Serial-Programming-HOWTO
The Linux Serial Programming HOWTO
¸®´ª½º ½Ã¸®¾ó ÇÁ·Î±×·¡¹Ö ÇÏ¿ìÅõ
Peter H. Baumann, Peter.Baumann@dir.de
v1.0, 22 January 1998
Àü¼º¹Î, schun@crypto.pe.kr
v1.0.1, 2 July 2007
À̿켺, Á¦°¡ º¸±â ÁÁ°Ô À§Å°¹®¹ýÀ¸·Î ¹Ù²ãº¸¾Ò½À´Ï´Ù. ±Ùµ¥ ¿Ö Àß ¾È ³ª¿À´ÂÁö ¸ð¸£°Ú½À´Ï´Ù...:(
ÀÌ ¹®¼´Â ¸®´ª½º ½Ã½ºÅÛ¿¡¼ ½Ã¸®¾ó Åë½ÅÀ» ¾î¶»°Ô ÇÁ·Î±×·¡¹ÖÇϴ°¡¸¦
¼³¸íÇÏ´Â ÇÏ¿ìÅõ ¹®¼ÀÌ´Ù.
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
¿¡¼µµ ±¸ÇÒ ¼ö ÀÖÀ¸¸ç,
news:comp.os.linux.answers
¿¡ ¸Å´Þ Æ÷½ºÆà µÉ °ÍÀÌ´Ù.
1.3. Feedback ¶¿À·ù, Áú¹®, Ä¿¸ÇÆ®, °ÇÀÇ»çÇ×À̳ª ±× ¿Ü Ãß°¡ÇÒ »çÇ×ÀÌ ÀÖ´Ù¸é ¾Ë·ÁÁÖ±â
¹Ù¶õ´Ù. ÀÌ HOWTO¸¦ °è¼ÓÀûÀ¸·Î ¾÷µ¥ÀÌÆ® Çϱ⸦ ¿øÇÑ´Ù. ´ç½ÅÀÌ Á¤È®È÷
ÀÌÇØÇÏÁö ¸øÇÏ´Â ºÎºÐÀÌ Àְųª ´õ ¸íÈ®ÇØ¾ß ÇÒ ºÎºÐÀÌ ÀÖ´Ù¸é ¾Ë·ÁÁà¶ó.
³» e-mail ÁÖ¼Ò´Â Peter.Baumann@dir.de ÀÌ´Ù. ÀÌ ¹®¼¿¡ °üÇÑ e-mailÀ»
º¸³¾ ¶§´Â ¹®¼ÀÇ ¹öÀüµµ °°ÀÌ ¾Ë·ÁÁà¶ó. ÀÌ ¹®¼ ¹öÀüÀº 1.0ÀÌ´Ù.
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*´Â ¸®´ª½º¿¡¼ Å͹̳ÎÀ» ¿¬°áÇϱâ À§ÇÑ
¸ñÀûÀ¸·Î »ç¿ëµÈ´Ù. ÀÌ »ç½ÇÀº ½Ã¸®¾ó Åë½Å ÇÁ·Î±×·¡¹ÖÀ» Çϴµ¥
¹Ýµå½Ã ±â¾ïÇØ¾ß ÇÒ »çÇ×ÀÌ´Ù. ¿¹¸¦ µé¾î, ½Ã¸®¾ó Æ÷Æ®µµ ¹®ÀÚ ¿¡ÄÚ¸¦
Çϵµ·Ï ¼³Á¤µÇ¾î ÀÖ´Ù. ÀÌ ¼³Á¤Àº º¸Åë µ¥ÀÌÅÍ Àü¼Û½Ã¿¡ ¹Ù²ã¾ß ÇÒ »çÇ×ÀÌ´Ù.
(¿ªÀÚ ÁÖ: ½Ã¸®¾ó ÀåÄ¡ ÆÄÀϵµ Å͹̳ΠÀåÄ¡·Î ºÐ·ùµÇ±â ¶§¹®¿¡ Ãʱ⠼³Á¤Àº
ÀÏ¹Ý Å͹̳ο¡¼ »ç¿ëµÇ´Â ¿¡ÄÚ°¡ µÇµµ·Ï ¼³Á¤µÇ¾î ÀÖ´Â °ÍÀÌ´Ù.)
¸ðµç ÆĶó¹ÌÅ͵éÀº ÇÁ·Î±×·¥ Äڵ忡¼ ½±°Ô ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. ÆĶó¹ÌÅ͵éÀº
<asm/termbits.h>¿¡ Á¤ÀǵǾî ÀÖ´Â 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 µîÀÇ Á¦¾î µ¿ÀÛµéÀ»
¾î¶² ¹®ÀÚ·Î Á¤ÀÇÇÒ °ÍÀΰ¡¸¦ ¼³Á¤ÇÑ´Ù. Á¦¾î ¹®ÀÚÀÇ µðÆúÆ® ¹®ÀÚ´Â
<asm/termios.h>¿¡ Á¤ÀǵǾî ÀÖ´Ù. À§ 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°³(<linux/limits.h>
ȤÀº <posix1_lim.h>¿¡ Á¤ÀǵÊ) ·Î¼ ¹öÆÛÀÇ ÃÖ´ë ±æÀÌ´Â
255·Î Á¦ÇѵȴÙ.
¿©·¯ ÀԷ ó¸® ¸ðµåÀÇ »ç¿ë¹ý¿¡ ´ëÇÑ ¼³¸íÀ» ¿øÇϸé ÄÚµå ³»ÀÇ comment¸¦ ÂüÁ¶Ç϶ó.
Äڵ尡 ÀÌÇØÇϱ⠽±±â¸¦ ¹Ù¶õ´Ù. Canonical ÀԷ ó¸® ¸ðµåÀÇ ¿¹Á¦´Â comment¸¦
°¡Àå Àß Çسõ¾Ò´Ù. ´Ù¸¥ ¿¹Á¦´Â canonical ¸ðµå ¿¹Á¦¿Í ´Ù¸¥ ºÎºÐ¿¡¸¸ comment¸¦
´Þ¾Ò´Ù.
¼³¸íÀÌ ¿Ïº®ÇÏÁø ¾ÊÁö¸¸, ÀÌ ¿¹Á¦·Î Á÷Á¢ Å×½ºÆ®¸¦ Çغ¸¸é ´ç½ÅÀÇ ÇÁ·Î±×·¥¿¡
Àû¿ëÇÒ ¶§ ÃÖÀûÀÇ ¹æ¹ýÀ» ãÀ» ¼ö ÀÖÀ» °ÍÀÌ´Ù.
½Ã¸®¾ó Æ÷Æ® ÀåÄ¡ ÆÄÀÏÀÇ ¼±ÅÃÀ» Á¦´ë·Î Çߴ°¡¸¦ ´Ù½Ã ÇÑ ¹ø È®ÀÎÇÏ°í, ÆÄÀÏ Á¢±Ù
Çã°¡´Â Á¦´ë·Î µÇ¾î ÀÖ´ÂÁö º¸±â¸¦ ¹Ù¶õ´Ù.
(¿¹: chmod a+rw /dev/ttyS1)
3.1. Canonical ÀԷ ó¸®(Canonical Input Processing) ¶#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); } 3.2. Non-Canonical ÀԷ ó¸®(Non-Canonical Input Processing) ¶Non-Canonical ÀԷ ó¸® ¸ðµå¿¡¼´Â ÀÔ·ÂÀÌ ÇÑ ÁÙ ´ÜÀ§·Î 󸮵ÇÁö ¾Ê´Â´Ù.
erase, kill, delete µîÀÇ ÀԷ ó¸®µµ ¼öÇàµÇÁö ¾Ê´Â´Ù. ÀÌ ¸ðµå¿¡¼ ¼³Á¤ÇÏ´Â
ÆĶó¹ÌÅÍ´Â c_ccVTIME°ú c_ccVMIN µÎ °¡ÁöÀÌ´Ù.
c_ccVTIMEÀº ŸÀ̸ÓÀÇ ½Ã°£À» ¼³Á¤ÇÏ°í, c_ccVMINÀº
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); ¸¦
È£ÃâÇÏ¸é ¶È°°Àº °á°ú¸¦ ¾òÀ» ¼ö ÀÖ´Ù.
#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); } 3.3. ºñµ¿±â ÀÔ·Â ¶#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; } 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 <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()´Â Áï½Ã ¸®ÅϵȴÙ.
4. ´Ù¸¥ À¯¿ëÇÑ Á¤º¸ ¶Serial-HOWTO ¹®¼´Â ½Ã¸®¾ó Æ÷Æ®¸¦ ¾î¶»°Ô ¼Â¾÷ÇÏ´ÂÁö¸¦
¼³¸íÇÏ°í Çϵå¿þ¾î Á¤º¸¸¦ Á¦°øÇÑ´Ù.
Michael SweetÀÇ Serial Programming Guide for POSIX Compliant Operating Systems
ÀÌ ¸µÅ©´Â ¿¾³¯ °ÍÀÌ°í ÃֽŠÀ§Ä¡¸¦ ãÀ» ¼ö°¡ ¾ø´Ù.
À̰Šã¾ÆÁÙ ºÐ ´©±¸ ¾ø¼ö? ÀÌ ¹®¼´Â ¸Å¿ì Àß Á¤¸®µÈ °ÍÀÌ´Ù.
(¿ªÀÚ ÁÖ: ´Ù½Ã ÀÌ À§Ä¡°¡ ºÎÈ°Çß´Ù. ¿¹Àü¿¡ Àá½Ã Æó¼âµÈ ÀûÀÌ ÀÖ¾ú´Ù.)
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) ¾¾¿¡°Ô °¨»çÇÑ´Ù.
|
He who has imagination without learning has wings but no feet. |