The Linux Serial Programming HOWTO by Peter H. Baumann, [1]Peter.Baumann@dlr.de ĶªÌ: ´¿¤¸¦ö [2]yytseng@ms16.hinet.net v1.0, 22 ¤@¤ë 1998 _________________________________________________________________ ¥»¤å¥ó±N±Ôz¦p¦ó¦b Linux Àô¹Ò¤U¼¶¼g§Ç¦C°ðªº³q°Tµ{¦¡. _________________________________________________________________ 1. ²¤¶ * 1.1 ª©Åv * 1.2 ¥»¤å³Ì·sªºª©¥» * 1.3 ¦^õX 2. ¶}©l * 2.1 °»¿ù * 2.2 ³s±µ°ð³]©w * 2.3 §Ç¦C¸Ë¸mªº¿é¤JÆ[©À 3. µ{¦¡½d¨Ò * 3.1 ¼Ð·Ç¿é¤Jµ{§Ç * 3.2 «D¼Ð·Ç¿é¤Jµ{§Ç * 3.3 «D¦P¨B¦¡¿é¤J * 3.4 µ¥«Ý¨Ó¦Û¦hÓ°T¸¹¨Ó·½ªº¿é¤J 4. ¨ä¥¦¸ê·½ 5. °^Äm _________________________________________________________________ 1. ²¤¶ ¥»¤å¬O Linux §Ç¦C°ðµ{¦¡¼¶¼gªº HOWTO. ¥þ½g³£¦b°Q½×¦p¦ó¦b Linux Àô¹Ò¤U, ¥H§Ç¦C°ð»P¨ä¥L ¸Ë¸m/¹q¸£ ³q°Tªºµ{¦¡¼gªk. ©Ò¸ÑÄÀªº§Þ³N¥]§t: ¼Ð·Çªº I/O (¥u¨ã³Æ ¶Ç°e/±µ¦¬ ½uªº), «D¦P¨B I/O, ¤Î µ¥«Ý¨Ó¦Û¦h«H¸¹·½ªº¿é¤J°T¸¹ ªº¼g ªk. ¥»¤å¤£·|±Ôz¦p¦ó³]©w§Ç¦C°ð, ¦]¬°³o¦b Greg Hankins ªº Serial-HOWTO ¤w¸g ¦³»¡©ú¤F. §Ú¥²»Ý±j½Õ§Ú¨Ã«D¦¹»â°ì¤¤ªº±M®a, ¦Ó¬O¦b±M®×¤¤´¿¹J¨ì¹L³oÃþªº³q°T°ÝÃD. ¦b ³o©Ò´£¨ìªº½d¨Òµ{¦¡¬Ol¥Í¦Û miniterm ªºµ{¦¡½X. ¥i¦b LDP µ{¦¡³]p®v«ü«n¨ú ±o (ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers-guide/lpg-0.4.ta r.gz ¤Î¨ä¥L¬M®g¯¸) ¦b½d¨Ò¨ºÓ¥Ø¿ý¤U. §Ú¶}©l¼g³o¥÷¤å¥ó¬O¦b 1997 ¦~ ¤»¤ë, ²{¦b§Ú¤w¸g²¾Âà¨ì WinNT ¥Hº¡¨¬«È¤áªº »Ý¨D, ¥HP©ó§Ú¨S¯à¾Ç±o§ó²`¤Jªºª¾ÃÑ. ¦pªG¥ô¦ó¤H¦³¤°»ò·N¨£, §Ú«Ü¼Ö·N§â¥¦ Â\¶i³o¥÷¤å¥ó¤¤ (°Ñ¦Ò ¦^õX ¨º¤@¸`). ¦pªG¦³¤H¯à±µ¤â³o¥÷¤u§@¨Ã¥[¥H§ï¶i, ½Ð e-mail µ¹§Ú. ©Ò¦³ªº½d¨Ò³£¦b i386 Linux Kernel 2.0.29 ¤U´ú¸Õ¹L. 1.1 ª©Åv Linux Serial-Programming-HOWTO ªºª©Åv(C) 1997 ¬O Peter Baumann ©Ò¦³. Linux HOWTO ¤å¥ó¥i¥H§¹¾ã©Î³¡¥÷¥H¹ê»Ú©Î¹q¤l«¬¦¡«»s©Î´²§G, ¥unª©Åv«Å§i ¯à«O¯d¦b©Ò¦³´²§Gªº°Æ¥»¤¤. °Ó·~©Êªº«»s´²§G¬O³\¥i¨Ã³Q¹ªÀyªº; ¤£¹L, ¦pªG ¥H¦¹«¬¦¡ªº´²§G À³¸Ó §iª¾§@ªÌ. ©Ò¦³¦³ÃöªºÂ½Ä¶, l¥Íªº¤u§@, ©Î¾ã¦X¦X¨Ö¥ô¦ó Linux HOWTO ¤å¥ó¬Ò¥²¶·¦b¦¹ª© Åv«Å§i³W½d¤§¤U. ¤]´N¬O, §A¤£¥i¥H¦Û HOWTO ©Òl¥Íªº¤u§@¤¤, ´²§Gªº¤å¥ó¤Wªþ ¥[ÃB¥~ªº¨î±ø´Ú. °£¤F³o¨Ç³W«h¤§¥~¬Ò¥i¦b¬YºØ±ø¥óªº±Â»P; ½ÐÁpµ¸ Linux HOWTO ¨ó½Õû: ¦p¥H¤U©Òµ¹ªº¦ì§}. ²¦Ó¨¥¤§, §Ú̧Ʊ澨¥i¯à±o³z¹L¦UºØºÞ¹D«P¶i³o¥÷¸ê°Tªº¬y³q, ¤£¹L, §Ú±j¯P ªº§Æ±æ±Nª©Åv«Å§i¸m©ó HOWTO ªº¤å¥ó¤W, ¥ô¦ó ·Q «·s´²§G HOWTO ªº¤H, §¡§Æ ±æ±z¯àª¾·|§Ṳ́@¤U. ¦pªG§A¦³°ÝÃD, ½Ð¸g¥Ñ email »P Tim Bynum, Linux HOWTO ¨ó½Õû³sµ¸, [3]linux-howto@sunsite.unc.edu. 1.2 ¥»¤å³Ì·sªºª©¥» Serial-Programming-HOWTO ³Ì·sªºª©¥»±N©ñ¦b [4]ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO/Serial-Programming-HOWT O ¤Î¨ä¥L¬M³]¯¸¥x. ¦³³\¦hªº®æ¦¡, ¦p PostScript ¤Î DVI ªºª©¥»©ñ¦b other-formats ¥Ø¿ý¤U. Serial-Programming-HOWTO ¤]©ñ¦b [5]http://sunsite.unc.edu/LDP/HOWTO/Serial-Programming-HOWTO.html ¨Ã·| ¨CÓ¤ëÂ\¤@¥÷¨ì [6]comp.os.linux.answers. 1.3 ¦^õX ½Ð§â¥ô¦ó×¥¿, °ÝÃD, ·N¨£, «Øij, ©Î¨ä¥¦ªþ¥[ªºÃD§÷¶Ç°eµ¹§Ú. ¥HÅý§Ú§ï¶i³o ¥÷ HOWTO! ¨Ã¸Ô²Ó§i¶D§ÚþÓ³¡¥÷¬O±z¤£¯à¤F¸Ñ, ©Î¤£°÷²M·¡ªº. §A¥i¥H¥Î email ³sµ¸§Ú [7]Peter.Baumann@dlr.de. ½Ð§â Serial-Programming-HOWTO ªº ª©¥»¸¹½Xªþ¤W, ¥»¤åª©¥»¸¹½X¬O 0.3. 2. ¶}©l 2.1 °»¿ù ³Ì¦nªº°»¿ù§Aµ{¦¡½Xªº¤èªk¬O«Øºc¥t¤@¥x Linux box, ¨Ã§â¨â¥x¹q¸£¥Î null-modem Æl½u³s±µ. ¥Î miniterm (¥i¦b LDP µ{¦¡³]p®v«ü«n¨ú±o (ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers-guide/lpg-0.4.ta r.gz ¦b½d¨Ò¨ºÓ¥Ø¿ý¤U) ¥H¶Ç°e¦r¤¸¨ì§Aªº Linux box. Miniterm «Ü®e©ö½sĶ ¦Ó¥¦·|§â©Ò¦³¿é¤J¨ìÁä½Lªº¦r¤¸³z¹L§Ç¦C°ð¶Ç°e. ¥u¦³³oӫŧi©w¸q·|³QÀˬd #define MODEMDEVICE "/dev/ttyS0". ¦pªG¬O COM1 ³]©w¬° ttyS0, ¦pªG¬O COM2 ³]©w¬° ttyS1 µ¥µ¥.. ¥ý«eªº´ú¸Õ¬O¥²nªº, ©Ò¦³ªº ¦r¤¸³£±N¥H raw ¤è¦¡ (¤£¸g¥ô¦ó³B²z) ª½±µ¶Ç°e. ´ú¸Õ¬O§_³s±µ¥¿½T, ¦b¨â¥x¹q¸£¤W³£±Ò°Ê miniterm µM«áÀH«K¦bÁä½L¤W¶Ã«ö. ¦b¨ä¤¤¤@¥x¤W¿é¤Jªº¦r¤¸À³¸Ó·|Åã¥Ü¦b¥t¤@¥x¹q¸£¤W¤Ï ¤§¥ç¦P. ¦ý¿é¤Jªº¦r¤¸¤£·|¦^À³¨ì»P¤§¬Û³sªº¿Ã¹õ¤W. n¦Û»s null-modem ªº¹qÆl, §A¥²»Ýn§â TxD (¶Ç°e) ¤Î RxD (±µ¦¬) ¨â½u¹ï ½Õ. ¸Ô²Óªº»¡©ú¦b Serial-HOWTO ªº²Ä 7 ¬q. ·íµM¤]¥i¥H¥u¥Î¤@¥x¹q¸£¨Ó§@¬Û¦Pªº´ú¸Õ, ¥un¹q¸£¤W¦³¨âÓ¥¼¨Ï¥Îªº§Ç¦C°ð. ·íµM§A¤]´Nn°õ¦æ¨âÓ miniterm ¨Ó·íµêÀÀ±±¨î¥x. ¦pªG§A¬OÂǥѩޥh·Æ¹«¨Ó¨ú ±o¥t¤@ӧǦC°ð, °O±on§â /dev/mouse ¸Ë¸m«·s¾É¦V, ¦pªG¥¦¦s¦bªº¸Ü. ¦pªG §A¨Ï¥Î¦h°ðªº§Ç¦C°ð±±¨î¥d, ½Ð½T©w¥¦¤w³]©w¥¿½T. ·í§Ú¦b§Úªº¹q¸£¤W´ú¸Õ®É¤] ´¿¸g¦]¬°³]©w¿ù»~¦Ó¥X¹Lºl. ·í§Ú³s¨ì¥t¤@¥x¹q¸£, ³q°T°ð¶}©l¶Ç°e¦r¤¸. ´N¦] ¬°è¦n³o¤£¬O§¹¾ãªº«D¦P¨B¦¡¶Ç¿é, ©Ò¥H¥i¦b¦P¤@¥x¹q¸£¤W°õ¦æ¨âÓµ{¦¡. 2.2 ³s±µ°ð³]©w /dev/ttyS* ¸Ë¸m·|³Q·í¦¨³s±µ¨ì§Aªº Linux box ªº²×ºÝ¾÷, ¨Ã¥B¦b±Ò°Ê«á´N³] ©w¦n¤F. ³oÓÆ[©À¦b§A¼g raw ¸Ë¸mªº³q°Tµ{¦¡®É¥²»Ý°O¦í. ¤]´N¬O»¡³oÓ³s±µ°ð ³Q³]©w¬°¦^À³©Ò¦³¦Û³oӸ˸m°e¥Xªº¦r¤¸, ¦Ó¥Î¦b¸ê®Æ¶Ç¿é®É³q±`³oºØn§ïÅܳo ºØ¤u§@¼Ò¦¡. ©Ò¦³ªº°Ñ¼Æ¥i¥H¥Ñ¤@Ó¤pµ{¦¡Â²³æªº§¹¦¨. ³]©w°Ñ¼Æ³Q©ñ¦b¤@Óµ²ºcÅ餺 struct termios, ¥Lªº©w¸qÀɦb <asm/termbits.h>: #define NCCS 19 struct termios { tcflag_t c_iflag; /* ¿é¤J¼Ò¦¡ºX¼Ð */ tcflag_t c_oflag; /* ¿é¥X¼Ò¦¡ºX¼Ð */ tcflag_t c_cflag; /* ±±¨î¼Ò¦¡ºX¼Ð */ tcflag_t c_lflag; /* °Ï°ì¼Ò¦¡ºX¼Ð */ cc_t c_line; /* ¦æ±±¨î (line discipline) */ cc_t c_cc[NCCS]; /* ±±¨î¯S©Ê */ }; ³oÓÀɮפ]¥]§t©Ò¦³ªººX¼Ð©w¸q. ¿é¤J¼Ò¦¡ºX¼Ð¦b c_iflag ´xºÞ©Ò¦³ªº¿é¤J³B ²z, ³o´N·N¿×µÛ¥Ñ¸Ë¸m¤W¶Ç¨Óªº¦r¤¸¦bÁÙ¨S¥Î read ¥\¯àŪ¨ú«e¥i¥H¥ý³B²z¹L. ¦P²z c_oflag ´xºÞ©Ò¦³ªº¿é¥X³B²z. c_cflag ¥]§t³s±µ°ðªº³]©w, ¦p Àj²v, ¨C ¦r¤¸¦h¤Ö¦ì¤¸, °±¤î¦ì¤¸, µ¥µ¥.. °Ï°ì¼Ò¦¡ºX¼Ð©ñ¦b c_lflag ¥Î¨Ó°»´ú¦r¤¸¬O §_¦^À³, ¦Ó°T¸¹·|°e¨ì§Aªºµ{¦¡, µ¥µ¥.. ³Ì«á c_cc °}¦C©w¸q¤FÀɮײפFªº±±¨î ¦r¤¸, °±¤î, µ¥µ¥.. ¹w³]ªº±±¨î¦r¤¸È©ñ¦b <asm/termios.h>. ¦³ÃöºX¼Ðªº²Ó¸` Â\¦b¨Ï¥Î¤â¥U termios(3). termios µ²ºcÅ餺ªº c_line ¦æ±±¨î (line discipline) ¤¸¯À, ¤£¯à¦b POSIX ¬Û®eªº¨t²Î¤U¨Ï¥Î ĶªÌµù:³o¸Ì©Ò»¡ªº line discipline ÁöµM§Ú½¦¨ ¦æ±±¨î ¦ýÁÙ¬O«ÜÃø»¡¥X¨º¬OªÙ. ¦pªG·Qª¾¹D½Ð¬Ý¬Ý kernel :( . 2.3 §Ç¦C¸Ë¸mªº¿é¤JÆ[©À ¦³¤TÓ¿é¤JªºÆ[©Àn»¡©ú. «ö·Ó©Òn¼gªºÀ³¥Îµ{¦¡¿ï¥Î¾A¦XªºÆ[©À. ¾¨¶qÁקK¨Ï ¥Î°j°é¨ÓŪ¨ú³æ¤@ªº¦r¤¸¦A²Õ¦¨¦r¦ê. §Ú´¿³o¼Ë°µ¹L, ·|±¼¦r¤¸, ¥B¹ï read ¦Ó ¨¥¤£·|Åã¥Ü¥ô¦ó¿ù»~. ¼Ð·Ç¿é¤Jµ{§Ç ³o¬O²×ºÝ¾÷ªº¼Ð·Ç³B²zµ{§Ç, ¦ý¥Î¨Ó»P¨ä¥L dl «¬¦¡ªº¥H¦æ¬°³æ¦ìªº¿é¤J³q°T¤] «Ü¦³¥Î, ¤]´N¬O read ·|¶Ç¦^¤@¾ã¦æ§¹¾ãªº¿é¤J¸ê®Æ. ¦æ¹w³]ªº²×¤î¦r¤¸¬O NL (ASCII LF), ÀÉ®×µ²§ô²Å, ©Î¦æ²×¤î¦r¤¸. ¹w³]Àô¹Ò¤U, CR (¬O DOS/Windows ¹w ³]ªº¦æ²×¤î²Å) ¤£·|²×¤î¤@¦æªº±Ôz. ¼Ð·Çªº¿é¤J³B²zµ{§ÇÁÙ¥i¥H³B²z ²M°£, §R°£¦r, «¦L¦r¤¸, ¤ÎÂà´« CR ¬° NL µ¥ µ¥¥\¯à.. «D¼Ð·Ç¿é¤Jµ{§Ç «D¼Ð·Ç¿é¤Jµ{§Ç¥i¥H¥Î¦b»Ýn¨C¦¸Åª¨ú©T©w¼Æ¶q¦r¤¸ªº±¡ªp, ¨Ã¤¹³\¨Ï¥Î¦r¤¸¿é ¤J®É¶¡ªºp®É¾¹. ³oºØ¼Ò¦¡¥i¥H¥Î¦bŪ¨ú©T©w¦r¤¸¼Æ¶qªºÀ³¥Îµ{¦¡, ©ÎªÌ©Ò³s±µ ªº¸Ë¸m·|¬ðµM°e¥X¤j¶q¦r¤¸ªºª¬ªp. «D¦P¨B¦¡¿é¤J ¥H¤W©Ò±Ôzªº¨âºØ¼Ò¦¡³£¥i¥H¥Î¦b«D¦P¨B»P¦P¨Bªº¶Ç¿é¼Ò¦¡. ¹w³]¬O¦b¦P¨Bªº¼Ò ¦¡¤U¤u§@, ¤]´N¬O¦b©|¥¼Åª¨ú§¹¤§«e, read ªºª¬ºA·|³QªýÂ_. ¦Ó«D¦P¨B¼Ò¦¡¤U read ªºª¬ºA·|ª½±µªð¦^¨Ã°e¥X°T¸¹¨ì©Ò¥s¥Îªºµ{¦¡ª½¨ì§¹¦¨¤u§@. ³oÓ°T¸¹¥i¥H ¥Ñ°T¸¹ªº³B²zµ{¦¡ handler...¨Ó±µ¦¬. µ¥«Ý¨Ó¦Û¦hÓ°T¸¹¨Ó·½ªº¿é¤J ³o¨Ã¤£¬O¤@Ó¤£¤@¼Ëªº¿é¤J¼Ò¦¡. ¦pªG§An³z¹L§Ç¦C°ð³s±µ¨Ã³B²z¦hӸ˸mªº ¸Ü, ¥¦¬Oº¡¦³¥Îªº. ¦b§ÚªºÀ³¥Îµ{¦¡¤¤§Ú¥²»Ý¦b´X¥G¦P¤@®É¶¡¤º, ³z¹L TCP/IP socket ¤Î§Ç¦C°ð³B²z¨Ó¦Û¨ä¥L¹q¸£ªº¿é¤J°T¸¹. ¤U±³oÓ½d¨Òµ{¦¡±Nµ¥«Ý¨Ó¦Û¨â Ó¤£¦P¿é¤J·½ªº°T¸¹. ¦pªG¨ä¤¤¤@Ó«H¸¹·½¥X²{, ¥L´N·|³Q³B²z, ¦Óµ{¦¡·|Ä~Äò µ¥«Ý·sªº¿é¤J°T¸¹. ¥H¤U³oÓ¤èªk¬Ý°_¨Ó¬Û·íÂÐÂø, ¦ý½Ð°O¦í Linux ¬O¤@Ó¦h¤uªº§@·~¨t²Î. select ³oÓ¨t²Î©I¥s¨Ã¤£·|¦bµ¥«Ý¿é¤J°T¸¹®É§â CPU t¸ü¥[«, ¦Ó¦pªG§A¥Î°j °é¤è¦¡¨Óµ¥«Ý¿é¤J°T¸¹±N¨Ï±o¨ä¥¦¦P®É°õ¦æªº¦æµ{³Q©ìºC. 3. µ{¦¡½d¨Ò ©Ò¦³ªº½d¨Ò¨Ó·½¦Û miniterm.c. The type ahead ¼È¦s¾¹³Q¨î¦b 255 Ó¦r¤¸, ´N¸ò¼Ð·Ç¿é¤Jµ{§Çªº³Ì¤j¦r¦êªø«×¬Û¦P (<linux/limits.h> ©Î <posix1_lim.h>). °Ñ¦Òµ{¦¡½X¤¤ªºµù¸Ñ¥¦·|¸ÑÄÀ¤£¦P¿é¤J¼Ò¦¡ªº¨Ï¥Î. §Ú§Æ±æ³o¨Çµ{¦¡½X³£¯à³Q¤F ¸Ñ. ¼Ð·Ç¿é¤Jµ{§Çªºµ{¦¡½d¨Òªºµù¸Ñ¼g±o³Ì¦n, ¨ä¥¦ªº½d¨Ò³£¥u¦b¤£¦P©ó¨ä¥¦½d ¨Òªº¦a¤è°µµù¸Ñ. ±Ôz¤£¬O«Ü§¹¾ã, ¦ý¥i¥H¿EÀy§A¹ï³o½d¨Ò°µ¹êÅç, ¥H©µ¥Í¥X¦X©ó§A©Ò»ÝÀ³¥Îµ{¦¡ ªº³Ì¨Î¸Ñ. §O§Ñ°On§â§Ç¦C°ðªºÅv³]©w¥¿½T (¤]´N¬O: chmod a+rw /dev/ttyS1)! 3.1 ¼Ð·Ç¿é¤Jµ{§Ç #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <stdio.h> /* Àj²v³]©w³Q©w¸q¦b <asm/termbits.h>, ³o¦b <termios.h> ³Q¤Þ¤J */ #define BAUDRATE B38400 /* ©w¸q¥¿½Tªº§Ç¦C°ð */ #define MODEMDEVICE "/dev/ttyS1" #define _POSIX_SOURCE 1 /* POSIX ¨t²Î¬Û®e */ #define FALSE 0 #define TRUE 1 volatile int STOP=FALSE; main() { int fd,c, res; struct termios oldtio,newtio; char buf[255]; /* ¶}±Ò¼Æ¾Ú¾÷¸Ë¸m¥HŪ¨ú¨Ã¼g¤J¦Ó¤£¥H±±¨î tty ªº¼Ò¦¡ ¦]¬°§Ṳ́£·Qµ{¦¡¦b°e¥X CTRL-C «á´N³Q±þ±¼. */ fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY ); if (fd <0) {perror(MODEMDEVICE); exit(-1); } tcgetattr(fd,&oldtio); /* Àx¦s¥Ø«eªº§Ç¦C°ð³]©w */ bzero(&newtio, sizeof(newtio)); /* ²M°£µ²ºcÅé¥H©ñ¤J·sªº§Ç¦C°ð³]©wÈ */ /* BAUDRATE: ³]©w bps ªº³t«×. §A¤]¥i¥H¥Î cfsetispeed ¤Î cfsetospeed ¨Ó³]©w. CRTSCTS : ¿é¥X¸ê®ÆªºµwÅé¬y¶q±±¨î (¥u¯à¦b¨ã§¹¾ã½u¸ôªºÆl½u¤U¤u§@ °Ñ¦Ò Serial-HOWTO ²Ä¤C¸`) CS8 : 8n1 (8 ¦ì¤¸, ¤£°µ¦P¦ì¤¸Àˬd,1 Ӳפî¦ì¤¸) CLOCAL : ¥»¦a³s½u, ¤£¨ã¼Æ¾Ú¾÷±±¨î¥\¯à CREAD : P¯à±µ¦¬¦r¤¸ */ newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; /* IGNPAR : ©¿²¤¸g¦P¦ì¤¸Àˬd«á, ¿ù»~ªº¦ì¤¸²Õ ICRNL : ¤ñ CR ¹ïÀ³¦¨ NL (§_«h·í¿é¤J°T¸¹¦³ CR ®É¤£·|²×¤î¿é¤J) ¦b¤£µM§â¸Ë¸m³]©w¦¨ raw ¼Ò¦¡(¨S¦³¨ä¥¦ªº¿é¤J³B²z) */ newtio.c_iflag = IGNPAR | ICRNL; /* Raw ¼Ò¦¡¿é¥X. */ newtio.c_oflag = 0; /* ICANON : P¯à¼Ð·Ç¿é¤J, ¨Ï©Ò¦³¦^À³¾÷¯à°±¥Î, ¨Ã¤£°e¥X«H¸¹¥H¥s¥Îµ{¦¡ */ newtio.c_lflag = ICANON; /* ªì©l¤Æ©Ò¦³ªº±±¨î¯S©Ê ¹w³]È¥i¥H¦b /usr/include/termios.h §ä¨ì, ¦bµù¸Ñ¤¤¤]¦³, ¦ý§Ú̦b³o¤£»Ýn¬Ý¥¦Ì */ 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; /* ¤£¨Ï¥Î¤À³Î¦r¤¸²Õªºp®É¾¹ */ newtio.c_cc[VMIN] = 1; /* ¦bŪ¨ú¨ì 1 Ó¦r¤¸«e¥ý°±¤î */ 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' */ /* ²{¦b²M°£¼Æ¾Ú¾÷½u¨Ã±Ò°Ê§Ç¦C°ðªº³]©w */ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); /* ²×ºÝ¾÷³]©w§¹¦¨, ²{¦b³B²z¿é¤J°T¸¹ ¦b³oÓ½d¨Ò, ¦b¤@¦æªº¶}©l³B¿é¤J 'z' ·|°h¥X¦¹µ{¦¡. */ while (STOP==FALSE) { /* °j°é·|¦b§Ú̵o¥X²×¤îªº°T¸¹«á¸õ¥X */ /* §Y¨Ï¿é¤J¶W¹L 255 Ó¦r¤¸, Ū¨úªºµ{¦¡¬qÁÙ¬O·|¤@ª½µ¥¨ì¦æ²×µ²²Å¥X²{¤~°±¤î. ¦pªGŪ¨ìªº¦r¤¸²Õ§C©ó¥¿½T¦s¦bªº¦r¤¸²Õ, «h©Ò³Ñªº¦r¤¸·|¦b¤U¤@¦¸Åª¨ú®É¨ú±o. res ¥Î¨Ó¦s©ñ¯u¥¿Åª¨ìªº¦r¤¸²ÕÓ¼Æ */ res = read(fd,buf,255); buf[res]=0; /* ³]©w¦r¦ê²×¤î¦r¤¸, ©Ò¥H§Ú̯à¥Î printf */ printf(":%s:%d\n", buf, res); if (buf[0]=='z') STOP=TRUE; } /* ¦^¦sªº§Ç¦C°ð³]©wÈ */ tcsetattr(fd,TCSANOW,&oldtio); } 3.2 «D¼Ð·Ç¿é¤Jµ{§Ç ¦b«D¼Ð·Çªº¿é¤Jµ{§Ç¼Ò¦¡¤U, ¿é¤Jªº¸ê®Æ¤£·|³Q²Õ¦X¦¨¤@¦æ¦Ó¿é¤J«áªº³B²z¥\¯à (²M°£, ±þ±¼, §R°£, µ¥µ¥.) ³£¤£¯à¨Ï¥Î. ³oÓ¼Ò¦¡¦³¨âÓ¥\¯à±±¨î°Ñ¼Æ: c_cc[VTIME] ³]©w¦r¤¸¿é¤J®É¶¡p®É¾¹, ¤Î c_cc[VMIN] ³]©wº¡¨¬Åª¨ú¥\¯àªº³Ì §C¦r¤¸±µ¦¬Ó¼Æ. ¦pªG MIN > 0 ¥B TIME = 0, MIN ³]©w¬°º¡¨¬Åª¨ú¥\¯àªº³Ì§C¦r¤¸±µ¦¬Ó¼Æ. ¥Ñ ©ó TIME ¬O ¹s, ©Ò¥Hp®É¾¹±N¤£³Q¨Ï¥Î. ¦pªG MIN = 0 ¥B TIME > 0, TIME ±N³Q·í°µ¹O®É³]©wÈ. º¡¨¬Åª¨ú¥\¯àªº±¡ªp¬° Ū¨ú¨ì³æ¤@¦r¤¸, ©ÎªÌ¶W¹L TIME ©Ò©w¸qªº®É¶¡ (t = TIME *0.1 s). ¦pªG¶W¹L TIME ©Ò©w¸qªº®É¶¡, «h¤£·|¶Ç¦^¥ô¦ó¦r¤¸. ¦pªG MIN > 0 ¥B TIME > 0, TIME ±N³Q·í°µ¤@Ó¤À³Î¦r¤¸²Õªºp®É¾¹. º¡¨¬Åª¨ú ¥\¯àªº±ø¥ó¬° ±µ¦¬¨ì MIN Ӽƪº¦r¤¸, ©Î¨âÓ¦r¤¸ªº¶¡¹j®É¶¡¶W¹L TIME ©Ò©w ¸qªºÈ. p®É¾¹·|¦b¨CŪ¨ì¤@Ó¦r¤¸«á«·sp®É, ¥B¥u·|¦b²Ä¤@Ó¦r¤¸¦¬¨ì«á¤~ ·|±Ò°Ê. ¦pªG MIN = 0 ¥B TIME = 0, Ū¨ú¥\¯à´N°¨¤W³Qº¡¨¬. ¥Ø«e©Ò¦s¦bªº¦r¤¸²ÕÓ ¼Æ, ©ÎªÌ ±N¦^¶Çªº¦r¤¸²ÕÓ¼Æ. ®Ú¾Ú Antonino (°Ñ¦Ò °^Äm) ©Ò»¡, §A¥i¥H¥Î fcntl(fd, F_SETFL, FNDELAY); ¦bŪ¨ú«e±o¨ì¬Û¦Pªºµ²ªG. ÂÇ¥Ñקï newtio.c_cc[VTIME] ¤Î newtio.c_cc[VMIN] ¤Wzªº¼Ò¦¡´N¥i¥H´ú¸Õ ¤F. #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 ¨t²Î¬Û®e */ #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); /* Àx¦s¥Ø«eªº§Ç¦C°ð³]©w */ bzero(&newtio, sizeof(newtio)); newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; /* ³]©w¿é¤J¼Ò¦¡ («D¼Ð·Ç«¬, ¤£¦^À³,...) */ newtio.c_lflag = 0; newtio.c_cc[VTIME] = 0; /* ¤£¨Ï¥Î¤À³Î¦r¤¸²Õp®É¾¹ */ newtio.c_cc[VMIN] = 5; /* ¦bŪ¨ú¨ì 5 Ó¦r¤¸«e¥ý°±¤î */ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); while (STOP==FALSE) { /* ¿é¤J°j°é */ res = read(fd,buf,255); /* ¦b¿é¤J 5 Ó¦r¤¸«á§Yªð°j */ buf[res]=0; /* ©Ò¥H§Ú̯à¥Î printf... */ printf(":%s:%d\n", buf, res); if (buf[0]=='z') STOP=TRUE; } tcsetattr(fd,TCSANOW,&oldtio); } 3.3 «D¦P¨B¦¡¿é¤J #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 ¨t²Î¬Û®e */ #define FALSE 0 #define TRUE 1 volatile int STOP=FALSE; void signal_handler_IO (int status); /* ©w¸q°T¸¹³B²zµ{§Ç */ int wait_flag=TRUE; /* ¨S¦¬¨ì°T¸¹ªº¸Ü´N·|¬O TRUE */ main() { int fd,c, res; struct termios oldtio,newtio; struct sigaction saio; /* definition of signal action */ char buf[255]; /* ¶}±Ò¸Ë¸m¬° non-blocking (Ū¨ú¥\¯à·|°¨¤Wµ²§ôªð¦^) */ fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd <0) {perror(MODEMDEVICE); exit(-1); } /* ¦b¨Ï¸Ë¸m«D¦P¨B¤Æ«e, ¦w¸Ë°T¸¹³B²zµ{§Ç */ saio.sa_handler = signal_handler_IO; saio.sa_mask = 0; saio.sa_flags = 0; saio.sa_restorer = NULL; sigaction(SIGIO,&saio,NULL); /* ¤¹³\¦æµ{¥h±µ¦¬ SIGIO °T¸¹*/ fcntl(fd, F_SETOWN, getpid()); /* ¨ÏÀÉ®×ake the file descriptor «D¦P¨B (¨Ï¥Î¤â¥U¤W»¡¥u¦³ O_APPEND ¤Î O_NONBLOCK, ¦Ó F_SETFL ¤]¥i¥H¥Î...) */ fcntl(fd, F_SETFL, FASYNC); tcgetattr(fd,&oldtio); /* Àx¦s¥Ø«eªº§Ç¦C°ð³]©wÈ */ /* ³]©w·sªº§Ç¦C°ð¬°¼Ð·Ç¿é¤Jµ{§Ç */ 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); /* µ¥«Ý¿é¤J°T¸¹ªº°j°é. «Ü¦h¦³¥Îªº¨Æ§Ú̱N¦b³o°µ */ while (STOP==FALSE) { printf(".\n");usleep(100000); /* ¦b¦¬¨ì SIGIO «á, wait_flag = FALSE, ¿é¤J°T¸¹¦s¦b«h¥i¥H³QŪ¨ú */ if (wait_flag==FALSE) { res = read(fd,buf,255); buf[res]=0; printf(":%s:%d\n", buf, res); if (res==1) STOP=TRUE; /* ¦pªG¥u¿é¤J CR «h°±¤î°j°é */ wait_flag = TRUE; /* µ¥«Ý·sªº¿é¤J°T¸¹ */ } } /* ¦^¦sªº§Ç¦C°ð³]©wÈ */ tcsetattr(fd,TCSANOW,&oldtio); } /*************************************************************************** * °T¸¹³B²zµ{§Ç. ³]©w wait_flag ¬° FALSE, ¥H¨Ï¤Wzªº°j°é¯à±µ¦¬¦r¤¸ * ***************************************************************************/ void signal_handler_IO (int status) { printf("received SIGIO signal.\n"); wait_flag = FALSE; } 3.4 µ¥«Ý¨Ó¦Û¦hÓ°T¸¹¨Ó·½ªº¿é¤J ³o¤@¬q«Üµu. ¥¦¥u¯à³Q®³¨Ó·í¦¨¼gµ{¦¡®Éªº´£¥Ü, ¬G½d¨Òµ{¦¡¤]«Ü²µu. ¦ý³oÓ ½d¨Ò¤£¥u¯à¥Î¦b§Ç¦C°ð¤W, ÁÙ¥i¥H¥Î¦b³Q·í¦¨ÀɮרӨϥΪº¸Ë¸m¤W. select ©I¥s¤Î¦ñÀH¥¦©Ò¤Þµoªº¥¨¶°¦@¥Î fd_set. fd_set «h¬O¤@Ó ¦ì¤¸°}¦C, ¦Ó¨ä¤¤¨C¤@Ӧ줸¥Nªí¤@Ó¦³®ÄªºÀÉ®×±Ôzµ²ºc. select ©I¥s±µ¨ü¤@Ó¦³®ÄªºÀÉ ®×±Ôzµ²ºc¨Ã¶Ç¦^ fd_set ¦ì¤¸°}¦C, ¦Ó¸Ó¦ì¤¸°}¦C¤¤Y¦³¬Y¤@Ӧ줸¬° 1, ´N ªí¥Ü¬Û¹ï¬MªºÀÉ®×±Ôzµ²ºcªºÀÉ®×µo¥Í¤F¿é¤J, ¿é¥X©Î¦³¨Ò¥~¨Æ¥ó. ¦Ó³o¨Ç¥¨¶° ´£¨Ñ¤F©Ò¦³³B²z fd_set ªº¥\¯à. ¥ç¥i°Ñ¦Ò¤â¥U select(2). #include <sys/time.h> #include <sys/types.h> #include <unistd.h> main() { int fd1, fd2; /* ¿é¤J·½ 1 ¤Î 2 */ fd_set readfs; /* ÀÉ®×±Ôzµ²ºc³]©w */ int maxfd; /* ³Ì¤j¥i¥ÎªºÀÉ®×±Ôzµ²ºc */ int loop=1; /* °j°é¦b TRUE ®É¦¨¥ß */ /* open_input_source ¶}±Ò¤@Ӹ˸m, ¥¿½Tªº³]©w¦n§Ç¦C°ð, ¨Ã¦^¶Ç¦^¦¹ÀÉ®×±Ôzµ²ºcÅé */ 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; /* ´ú¸Õ³Ì¤j¦ì¤¸¿é¤J (fd) */ /* ¿é¤J°j°é */ while (loop) { FD_SET(fd1, &readfs); /* ´ú¸Õ¿é¤J·½ 1 */ FD_SET(fd2, &readfs); /* ´ú¸Õ¿é¤J·½ 2 */ /* block until input becomes available */ select(maxfd, &readfs, NULL, NULL, NULL); if (FD_ISSET(fd1)) /* ¦pªG¿é¤J·½ 1 ¦³°T¸¹ */ handle_input_from_source1(); if (FD_ISSET(fd2)) /* ¦pªG¿é¤J·½ 2 ¦³°T¸¹ */ handle_input_from_source2(); } } ³oÓ½d¨Òµ{¦¡¦bµ¥«Ý¿é¤J°T¸¹¥X²{«e, ¤£¯à½T©w¥¦·|°±¹y¤U¨Ó. ¦pªG§A»Ýn¦b¿é ¤J®É¥[¤J¹O®É¥\¯à, ¥u»Ý§â select ©I¥s´«¦¨: int res; struct timeval Timeout; /* ³]©w¿é¤J°j°éªº¹O®ÉÈ */ Timeout.tv_usec = 0; /* ²@¬í */ Timeout.tv_sec = 1; /* ¬í */ res = select(maxfd, &readfs, NULL, NULL, &Timeout); if (res==0) /* ÀÉ®×±Ôzµ²ºc¼Æ¦b input = 0 ®É, ·|µo¥Í¿é¤J¹O®É. */ ³oÓµ{¦¡·|¦b 1 ¬íÄÁ«á¹O®É. ¦pªG¶W¹L®É¶¡, select ·|¶Ç¦^ 0, ¦ý¬OÀ³¸Ó¯d·N Timeout ªº®É¶¡»¼´î¬O¥Ñ select ©Òµ¥«Ý¿é¤J°T¸¹ªº®É¶¡¬°°ò·Ç. ¦pªG¹O®ÉªºÈ ¬O 0, select ·|°¨¤Wµ²§ôªð¦^. 4. ¨ä¥¦¸ê·½ * Linux Serial-HOWTO ±Ôz¦p¦ó³]©w§Ç¦C°ð¤Î©Ò¦³¬ÛÃöªºµwÅé¸ê°T. * ¥Ñ Michael Sweet ©Ò¼gªº [8]Serial Programming Guide for POSIX Compliant Operating Systems. ³oÓ³sµ²¤w¸g¯î¼o¤F¦ý§Ú§ä¤£¨ì¥¦ªº·s¦ì §}. ¦³¤Hª¾¹D¯à¦bþ§ä¨ì¥¦¶Ü? ¥¦¬O«Ü´Îªº¤å¥ó! * termios(3) ªº¨Ï¥Î¤â¥U. ±Ôz©Ò¦³¦³Ãö termios µ²ºcÅ骺ºX¼Ð. 5. °^Äm ´N¸ò²¤¶©Ò»¡ªº¤@¼Ë, §Ú¨Ã«D¦b³o»â°ì¦³©Ò±Mºë, ¦ý§Ú¦Û¤v¹J¨ì°ÝÃD, ¨Ã³z¹L¥L ¤HªºÀ°§U§ä¨ìµª®×. ·PÁÂ¨Ó¦Û European Transonic Windtunnel ªº Strudthoff ¥ý¥Í, Cologne, Michael Carter (mcarter@rocke.electro.swri.edu), ¤Î Peter Waltenberg (p.waltenberg@karaka.chch.cri.nz) »P§Ú¦P®É·Ç³Æ³o¥÷¤å¥óªº Antonino Ianella (antonino@usa.net ©Ò½f¼gªº Serial-Port-Programming Mini HOWTO. Greg Hankins n¨D§Ú§â Antonino's Mini-HOWTO ¤@¨Ö©ñ¤J³o¥÷¤å¥ó. ³o¥÷¤å¥óªºµ²ºc¤Î SGML ªº®æ¦¡¬O·½¦Û Greg Hankins ªº Serial-HOWTO. ·PÁ Dave Pfaltzgraff (Dave_Pfaltzgraff@patapsco.com), Sean Lincolne (slincol@tpgi.com.au), Michael Wiedmann (mw@miwie.in-berlin.de), ¤Î Adrey Bonar (andy@tipas.lt) ¦U¤è±ªº¨ó§U. References 1. mailto:Peter.Baumann@dlr.de 2. mailto:yytseng@ms16.hinet.net 3. mailto:linux-howto@sunsite.unc.edu 4. ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/Serial-Programming-HOWTO 5. http://sunsite.unc.edu/LDP/HOWTO/Serial-Programming-HOWTO.html 6. news:comp.os.linux.answers 7. mailto:Peter.Baumann@dlr.de 8. http://www.easysw.com/~mike/serial