The Linux Serial Programming HOWTO by Peter H. Baumann, Peter.Baumann@dlr.de v1.0, 22 January 1998 ¡´PÃ, fujiwara@linux.or.jp 26 February 1998 ±Ì¶ÅÍCLinux }VÌVA|[gðgÁ½ÊMvOÌ« ûðྵܷD ______________________________________________________________________ Ú 1. ͶßÉ 1.1 ì É墀 1.2 {¶ÌÅVÅÌüèû@ 1.3 tB[hobN 2. ͶßÄÝÜµå¤ 2.1 fobOÌû@ 2.2 |[gÌÝè 2.3 VAfoCXɨ¯éüÍÌTO 2.3.1 JmjJüÍ 2.3.2 ñJmjJüÍ 2.3.3 ñ¯úüÍ 2.3.4 ¡üÍ©çÌüÍÒ¿ 3. vOá 3.1 JmjJüÍ 3.2 ñJmjJüÍ 3.3 ñ¯úüÍ 3.4 ¡ÌüÍ©çÌüÍÒ¿ 4. ¼Ìîñ¹ 5. Rgr [V ______________________________________________________________________ 1. ͶßÉ {¶Í Linux Serial Programming HOWTO Å·DLinux ÌVA|[gð gÁÄC¼ÌfoCX/Rs [^ÆÊM·évOÌ«ûððൠܷDJmjJ I/O(sPÊÅÌóM)Cñ¯ú I/OC¡\[X©çÌü ÍÒ¿ÌCÙÈé^CvÌè@ððàµÜ·D {¶ÅÍCVA|[gÌÝèû@ÍྵܹñD±¿çÉ¢ÄÍC Greg Hankins Ì©ê½ Serial-HOWTO ð²¾³¢D ÍVAÊM̪ìÌêåÆÅÍ èܹñªCVAÊMÉÖíév WFNgÅâèððµÄ«Üµ½D{¶ÅÐî·éTvR[hÍC LDP vO}[YKCh (ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers- guide/lpg-0.4.tar.gz yÑ~[TCg)Ì 'examples' fBNg©çü è·é±ÆªÅ«é miniterm ÉR·éàÌÅ·D 1997NÌ6ɱ̶ð¢Ä©çCÍÚqÌsÉæè WindowsNT ðg ¤æ¤ÉÈèCÖAm¯ð[ßé±ÆªÅ«Ü¹ñŵ½D{¶É½f³¹ Ü·ÌÅCRgª êÎ¥ñÁľ³¢(tB[hobNÌÍðQ Æ)Ddðø«p¢Åæèæ¢àÌɵľ³éûª¢êÎC[Åm ç¹Ä¾³¢D SÄÌáèÌeXgÍCi386 x[XÌ Linux 2.0.29 Ås¢Üµ½D 1.1. ì É墀 Linux Serial-Programming-HOWTOÍPeter Baumann Ìì¨Å·(copyright (C) 1997)DLinux HOWTO ¶ÍC±Ìì \¦ðüϵȢÀèC¶Ì ê é¢ÍSÌðCCÓÌdqIE¨IfBAÖ¡»yÑzz·é±Æ ªÅ«Ü·D¤ÆIzzÍFßçêĨèCܽ½}µÄ¢Ü·Dµ©µC± Ìæ¤ÈzzÌêÉÍCÒÖÌAª é±Æðó]µÜ·D |óCh¶¨CLinux HOWTO ¶ðÜÞÒW¨Í±Ìì \¦É]íȯê ÎÈèܹñDÂÜèCHOWTO ©çh¶µ½¬Ê¨ðìèC±êɧÀðÇÁ µÄzz·é±ÆÍūܹñD½¾µCêèÌð̺űÌK¥ÉáOð Fßé±ÆªÅ«éêª èÜ·DȺÉAhX𦷠Linux HOWTO Ì ¢bðÉkµÄ¾³¢D ÈPɾ¦ÎCäXͱÌîñðū龯½ÌoHÅLß½¢ÆvÁÄ¢ Ü·Dµ©µCHOWTO ¶Ìì ÍÛ³êé±ÆÆCHOWTO ðÄzz·é SÄÌû@ðÅ«êÎmç¹Äàç¦é±Æðó]µÄ¢Ü·D ^â_ª êÎCLinux HOWTO Ì¢bðÅ é gregh@sunsite.unc.edu É dq[ÅkµÄ¾³¢D 1.2. {¶ÌÅVÅÌüèû@ Serial-Programming-HOWTO ÌÅVÅÍ ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO/Serial-Programming-HOWTO yÑC»Ì~[TCgÅüèÅ«Ü·DPostScript â DVI Ì`®Ì¶ Íother-formatsfBNgÉ èÜ·DܽC http://sunsite.unc.edu/LDP/HOWTO/Serial-Programming-HOWTO.html Éà èÜ·µCÉêxcomp.os.linux.answersj [XO[vÉàe³êÜ ·D 1.3. tB[hobN ù³C¿âCRgCñÄCÇÁÈǪ êÎC¥ñMÒɨmç¹ ¾³¢D±Ì¶ðæèÇ¢àÌɵ½¢ÆvÁĢܷD檩ç颮 ±ëâCàÁƪ©èâ·Å«éªðmç¹Ä¾³¢DMÒÉA·é ÉÍPeter.Baumann@dlr.deÖdq[ðoµÄ¾³¢Ddq[ð ÛÉÍCÇñ¾ Serial-Programming-HOWTO Ìo[W(±Ì¶Ío[ W1.0Å·)à¢Ä¾³¢D ó: ú{êóÌÅVÅÍJF vWFNgz[y[W ÅüèÅ«Ü·DÜ ½Cëóª êÎóÒÌûÖ[ðoµÄ¾³¢D 2. ͶßÄÝÜµå¤ 2.1. fobOÌû@ Ƚª¢½R[hðfobO·é½ßÌÅàÇ¢û@ÍCLinux }Vð à¤êäpÓµCñäÌRs [^ðkfP[uÅÚ±·é±ÆÅ ·Dminiterm(LDP vO}[YKCh (ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers- guide/lpg-0.4.tar.gz Ì'examples'fBNgÉ èÜ·)ðgÁÄC È ½Ì Linux }VÖ¶ðÁÄÝܵå¤Dminiterm ÍñíÉÈPÉR pCÅ«CL[{[hüÍðVA|[goRÅ»ÌÜÜ(raw)èÜ ·D½¾Cdefine ¶ #define MODEMDEVICE "/dev/ttyS0"̪¾¯Í`Fb NµÈÄÍÈèܹñD±ÌªÍCP[uÅÚ±·é̪ COM1 Å ê Î ttyS0CCOM2Å êÎttyS1Ìæ¤ÉÝèµÜ·D±ÌeXgÅåÈ_ ÍCSÄ̶ͻÌÜÜ(raw, oͳµÉ)M³êé±ÆÅ·DÚ± eXgð·éÆ«ÍC¼ûÌ}VÅ miniterm ðÀsµCL[{[hð@ ¾¯Å·DÐûÌ}VÅüͳ꽶ÍCà¤êûÌ}VÅoͳêÜ ·D»Ìt௶ŷDü͵½¶ÍCü͵½ûÌ}VÌæÊÉÍGR [³êܹñD kfP[uð©ì·éÉÍCTxD(M)ÆRxD(óM)ÌüðNX³ ¹Ü·DP[uÉ¢ÄÌÚµ¢ðàÍCSerial-HOWTO Ìæ7ÍÉ èÜ ·D ¢gpÌVA|[gª2 éÌÈçÎCêäÌRs [^űÌeX gðÀs·é±ÆàÅ«Ü·D±ÌêÍC2Â̼zR\[Å»ê¼ê miniterm ðÀsµÜ·DVA}EXðOµÄVA|[gðó¯éê ÉÍC/dev/mouseð·¦é±ÆðYêÈ¢æ¤ÉµÜµå¤D}`|[ gVAJ[hðgÁÄ¢éêÉÍCÝ誳µ¢±ÆðmFµÜµå ¤DMÒÍ©ªÌ}VÅÔáÁ½ÝèðµÄ¢½½ßÉC©ªÌ}VÅe Xgµ½¾¯¤Ü®ì·éÆ¢¤ÔÉÈÁ½±Æª èÜ·D±ÌÝè żÌRs [^ÉÚ±µ½ÉÍC¶ªÁ¦ÄµÜ¢Üµ½D 2ÂÌv Oð1ÂÌRs [^Å®©·±ÆÍC®SÉñ¯úÆ;¦Ü¹ ñD n 2.2. |[gÌÝè /dev/ttyS*Æ¢¤foCXÍ[ð Linux }VÉq®½ßÌàÌÅCÊM ðnß½ãÍ[Éí¹½ÝèªsíêÜ·D±Ì_Í raw foCXð gÁÄÊM·évOðs¤êÉÍCӵĨ©È¯êÎÈèÜñD á¦ÎCÁ½LN^ðGR[obN³¹éæ¤ÉVA|[gðÝè ³êĢܷªCÊíf[^M̽ßÉͱÌÝèÍÏXµÈ¯ê΢¯Ü ¹ñD SÄÌp[^ÍvOàÅÈPÉÝèÅ«Ü·DÝèÍwb_t@C <asm/termbits.h>Åè`³êÄ¢é termios \¢ÌÉÛ¶³êÜ·D #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 */ }; ±Ì<asm/termbits.h> t@CÉÍCtOÌè`àSÄLq³êÄ¢Ü ·Dc_iflag tOÉÍüÍ[hÌtOª¢Â©ÜÜêĨèCSÄÌ üÍðwèµÜ·DüÍÆÍCfoCX©ççê½LN^ ÍCreadÅÇÝo³êéOÉ·é±ÆªÅ«éÆ¢¤±ÆÅ·D¯l ÉCc_oflagÍoÍðµ¢Ü·D c_cflagÍC{[[gâ¶Ìrb gCXgbvrbgÈÇÌ|[gÝèðL^µÄ¢Ü·Dc_lflag àÌ[ J[htOÍC¶ªGR[³êé©Ç¤©CvOÉVOiª çêé©Ç¤©ðwèµÜ·DÅãÉCzñ c_cc ÅÍCt@CI [Cstop ̧ä¶ðè`µÜ·D§ä¶ÌftHglÍ <asm/termios.h> Åè`³êĢܷDetOÉ¢ÄÍCIC} j AÌ termios(3) Éྪ èÜ·D\¢Ì termiosÍ POSIX Ì VXeÅÍp¢çêÈ¢C c_linevfðÜñŢܷD 2.3. VAfoCXɨ¯éüÍÌTO ±±ÅÍC3ÂÌÙÈéíÞÌüÍÌTOðྵܷDpÚIÉ]ÁÄC KØÈàÌðIðµÄ¾³¢D¶ñSÌðæ¾·éÌÉC1¶ÇÝÝ Ì[vðg¤±ÆÍÅ«éÀèð¯é׫ŷDͱêðâÁ½Æ«CÇ ÝÝÉ read ªSG[ðo͵ȩÁ½ÌÉà©©íç¸C¶ª ¯ÄµÜÁ½±Æª èܵ½D 2.3.1. JmjJüÍ ±êÍ[ÉεÄÌÊíÌ[hÅ·ªC¼ÌfoCXÆÌÊMÌÉ àÖÅ·DSÄÌüÍÍsPÊųêÜ·DÂÜèCread ÍüÍÌ1s SÌÌÝðԵīܷDftHgÅÍCsÍNL(ASCII ÌLF)Ct@CI [CsI[¶Ì¢¸ê©ÅIèÜ·DWÌÝèÅÍCCR (DOS/Windows Ì ftHgÌsI[¶)ÍsÌI[ÆÍÈèܹñD JmjJüÍÅÍCÁ(erase)CPêÌí(delete word)C¶ÌÄ oÍ(reprint characters)CCRÌNLÖÌÏ·ÈÇ𵤱ƪūܷD 2.3.2. ñJmjJüÍ ñJmjJüÍÍCread ÉÜÁ½Ì¶ðµ¤û@ÅCL N^^C}ðp·é±ÆàÅ«Ü·D±Ì[hÍAvP[Vª ÜÁ½¶ÌLN^ðÇÝÞâCÚ±µ½foCXªåÊ̶ð ÁÄéêÉgpµÜ·D 2.3.3. ñ¯úüÍ ãL2ÂÌ[hÍC¯úyÑñ¯ú[hÅg¤±ÆªÅ«Ü·DftH gÍCüͪ¤Ü¢ÜÅ read ¶ªubN³êé¯ú[hÅ·Dñ¯ ú[hÅÍCread ¶Í¦ÀÉI¹µCãÅÇÝݪ®¹µ½ÉvO ÉVOiªçêÜ·D±ÌVOiÍCVOinhðgÁÄó ¯æèÜ·D 2.3.4. ¡üÍ©çÌüÍÒ¿ ±êÍÊÌüÍ[hÆ¢¤í¯ÅÍ èܹñªC¡ÌfoCX𵤠ÉÖÅ·DMÒÌAvP[VÅÍCTCP/IP \PbgoRÌüÍƼ ÌRs [^©çÌVAÚ±oRÌüÍð[IɯɵÁÄ¢Ü ·DȺɦ·vOáÅÍCÙÈé2ÂÌüÍ\[X©çÌüÍÒ¿ð s¢Ü·DÐûÌ\[X©çÌüͪÂ\ÉÈéÆC»Ìüͪ³êCv OÍÌüÍðÒ¿Ü·D Ⱥɦ·Av[`Í¿åÁÆ¡GÉ©¦Ü·ªCLinux Í}`vZb VO OS Å é±ÆðYêÄÍ¢¯Ü¹ñDselectVXeR[ÍüÍÒ ¿ÌÔÍ CPU É×ð^¦Ü¹ñªC[vðgÁ½üÍÒ¿ðs¤ÆC¯ ÉÀs³êÄ¢é¼ÌvZXªxÈÁĵܢܷD 3. vOá SÄÌáÍ miniterm.c ©çæèoµ½àÌÅ·DæsüÍÌobt@Í 255 ¶É§À³êĢܷD±êÍCJmjJüÍÌÅ嶷Ư¶Å · (<linux/limits.h> é¢Í <posix1_lim.h>ðQÆ)D »ê¼êÌüÍ[hÌg¢ûÉ¢ÄÍvOÌRgð©Ä¾ ³¢DvOÍ\ªÇݱȹéÆv¢Ü·DJmjJüÍ[hÌá ÉÍêÔÚµ¢Rgðt¯Ä¢Ü·Dá¢ð²·é½ßÉC¼ÌáÉ ¢ÄÍJmjJüÍ[hÆÌá_¾¯ð¢Ä¢Ü·D à¾Í®SÅÍ èܹñªCECðoµÄáèÅÀ±µC ȽÌÚIÉÅ àKµ½ðð©Â¯¾µÄ¾³¢D gp·éVA|[gÉÍCKØÈp[~bVð^¦éÌðYêȢŠ¾³¢(á: chmod a+rw /dev/ttyS1)D 3.1. JmjJüÍ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <stdio.h> /* <asm/termbits.h> Åè`³êÄ¢é{[[gÌÝèD±êÍ <termios.h>©çCN[h³êéD */ #define BAUDRATE B38400 /* KØÈVA|[gðw·æ¤ÉC±Ìè`ðÏX·éD*/ #define MODEMDEVICE "/dev/ttyS1" #define _POSIX_SOURCE 1 /* POSIX Ì\[X */ #define FALSE 0 #define TRUE 1 volatile int STOP=FALSE; main() { int fd,c, res; struct termios oldtio,newtio; char buf[255]; /* Çݫ̽ßÉffoCXðI[v·éDmCYÉæÁÄ CTRL-C ª½Ü½Ü¶µÄàÚ±ªØêÈ¢æ¤ÉCtty §ä͵ȢD */ fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY ); if (fd <0) {perror(MODEMDEVICE); exit(-1); } tcgetattr(fd,&oldtio); /* »ÝÌVA|[gÌÝèðÒð³¹é*/ bzero(&newtio, sizeof(newtio)); /* Vµ¢|[gÌÝèÌ\¢ÌðNA·é */ /* BAUDRATE: {[[gÌÝèDcfsetispeed Æ cfsetospeed àgpÅ«éD CRTSCTS : oÍÌn[hEFAt[§ä (KvÈüªSijêÄ¢éP[ uðg¤êÌÝDSerial-HOWTO Ì7ÍðQÆ̱Æ) CS8 : 8n1 (8 rbgCmpeBCXgbvrbg 1) CLOCAL : [JÚ±Cf§äȵ CREAD : óM¶(receiving characters)ðLøÉ·éD */ newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; /* IGNPAR : peBG[Ìf[^ͳ·é ICRNL : CR ð NL Éγ¹é(±êðsíÈ¢ÆC¼ÌRs [^Å CR ðü͵ÄàCüͪIèÉÈçÈ¢) »êÈOÌÝèÅÍCfoCXÍ raw [hÅ é(¼ÌüÍÍsíÈ¢) */ newtio.c_iflag = IGNPAR | ICRNL; /* Raw [hÅÌoÍ */ newtio.c_oflag = 0; /* ICANON : JmjJüÍðLøÉ·é SÄÌGR[ð³øɵCvOÉεÄVOiÍç¹È¢ */ newtio.c_lflag = ICANON; /* SÄ̧ä¶ðú»·é ftHglÍ /usr/include/termios.h ð©êΪ©éªCRgÉ ¢Ä éÌÅC±±ÅÍ©éKvÍÈ¢D */ 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; /* LN^Ô^C}ðgíÈ¢ */ newtio.c_cc[VMIN] = 1; /* 1¶éÜÅCÇÝÝðubN·é */ 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' */ /* fCðNAµC|[gÌÝèðLøÉ·é */ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); /* [ÌÝèI¹DüÍð·éÅ«éæ¤ÉÈÁ½D áÅÍCsÌæªÉ 'z' ðüÍ·é±ÆÅvOðI¹³¹é */ while (STOP==FALSE) { /* I¹ðª½³êéÜÅ[v */ /* 255¶Èãüͳê½êÅàCsI[¶ªüͳêéÜÅÍCv OÌÀsÍ read ÅubN³êéDÇÝñ¾¶ªCÀÛÉü ͳêÄ¢é¶æèÈ¢êÉÍCñÌ read Åcè̶ªÇ ÝÜêéDÏ res ÉÍÀÛÉÇÝÜ꽶ªZbg³êéD */ res = read(fd,buf,255); buf[res]=0; /* printf Åg¤½ßC¶ñÌI[ðZbg·é */ printf(":%s:%d\n", buf, res); if (buf[0]=='z') STOP=TRUE; } /* |[gÌÝèðvOJnÌàÌÉß· */ tcsetattr(fd,TCSANOW,&oldtio); } 3.2. ñJmjJüÍ ñJmjJüÍ[hÅÍCüÍðsƵÄÜÆßé±ÆÍsíê¸C üÍ(erase, kill, delete )àsíêܹñD±Ì[ḩäÍ2 Ìp[^Ås¢Ü·D c_cc[VTIME]ÅLN^^C}ÌÝèðs¢C c_cc[VMIN]ÅÍÇÝÝð«·éOÉó¯æéŬ̶ðÝèµÜ·D MIN > 0 Å TIME = 0 ÌêCMIN ÅÇÝݪ«·éOÉó¯æé¶ ðÝèµÜ·DTIME Í[ÈÌÅC^C}ÍgíêܹñD MIN = 0 Å TIME > 0 ÌêÉÍCTIME Í^CAEglÉÈèÜ·DÇÝ ÝÍ1¶ÇÝÜê½ê©CÔ TIME (Ò¿Ô = TIME * 0.1 b) ð ߬½êÉ«³êÜ·DÔðz¦½êÉÍC¶ÍÔ³êܹñD MIN > 0 Å TIME > 0 ÌêÉÍCTIME ÍLN^Ô^C}ÌÝèÉÈè Ü·DÇÝÝÍ MIN ¶ó¯æÁ½ê©C2Â̶ðó¯æéÔÌÔ ª TIME ðz¦½êÉ«³êÜ·D^C}Í1¶ó¯æé²ÆÉú» ³êÜ·DܽCÅÌ1¶ðó¯æéÜÅÍ^C}ÍLøÉÍÈèܹ ñD MIN = 0 ©Â TIME = 0 ÌêÉÍCÇÝÝͦÀÉ«³êÜ·D»ÝÇ ÝÝÂ\ȶ©Cvµ½¶ªß³êÜ·DAntonio ³ñÉæêÎ (contributions QÆ)CÇÝÝÌOÉ fcntl(fd, F_SETFL,FNDELAY); ðÀ s·é±ÆÅC¯¶Êð¾é±ÆªÅ«Ü·D newtio.c_cc[VTIME] Æ newtio.c_cc[VMIN] ðÏX·é±ÆÅCÈãÌ[h ðSÄ·±ÆªÅ«Ü·D #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 Ì\[X */ #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); /* »ÝÌ|[gÝèðÒð */ 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; /* LN^Ô^C}Í¢gp */ newtio.c_cc[VMIN] = 5; /* 5¶ó¯æéÜÅubN·é */ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); while (STOP==FALSE) { /* üÍ[v */ res = read(fd,buf,255); /* 5 ¶üͳê½çßé */ buf[res]=0; /* printf ðg¤½ßɶñI[ðZbg */ 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 Ì\[X */ #define FALSE 0 #define TRUE 1 volatile int STOP=FALSE; void signal_handler_IO (int status); /* VOinhÌé¾ */ int wait_flag=TRUE; /* VOiðó¯æÁĢȯêÎ TRUE */ main() { int fd,c, res; struct termios oldtio,newtio; struct sigaction saio; /* VOiðó¯½Ì®ìðè` */ char buf[255]; /* foCXðñubLO[hÅI[v·é (read ͦÀÉßÁÄéæ¤ÉÈé) */ fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd <0) {perror(MODEMDEVICE); exit(-1); } /* foCXðñ¯ú[hÉ·éOÉCVOinhðÝè·é */ saio.sa_handler = signal_handler_IO; saio.sa_mask = 0; saio.sa_flags = 0; saio.sa_restorer = NULL; sigaction(SIGIO,&saio,NULL); /* vZXª SIGIO ðó¯æêéæ¤É·é */ fcntl(fd, F_SETOWN, getpid()); /* t@CfXNv^ðñ¯ú[hÉ·é (IC}j AÉ æêÎCO_APPEND Æ O_NONBLOCK ¾¯ª F_SETFL Å®ì·éÆ̱Æc */ fcntl(fd, F_SETFL, FASYNC); tcgetattr(fd,&oldtio); /* save current port settings */ /* Vµ¢|[gÌÝèðJmjJüÍÉÝè·é */ 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); /* üÍÒ¿ÌÔ[vµÜ·DÊíͱ±Å½ç©ÌìÆð·é */ while (STOP==FALSE) { printf(".\n");usleep(100000); /* SIGIO ðó¯æèCwait_flag = FALSE ÉÈÁÄ¢êÎüͪp \ÈÌÅÇÝÝðs¤±ÆªÅ«é */ if (wait_flag==FALSE) { res = read(fd,buf,255); buf[res]=0; printf(":%s:%d\n", buf, res); if (res==1) STOP=TRUE; /* CR ¾¯ªüͳê½êÉ[vI¹ */ wait_flag = TRUE; /* ÌüÍðÒ */ } } /* vOJnÌ|[gÝèð³·é */ tcsetattr(fd,TCSANOW,&oldtio); } /********************************************************************** * VOinhDãLÌ[vŶðó¯æÁ½±Æ𦷽ßÉC * * wait_flag É FALSE ðZbg·éD * ***********************************************************************/ void signal_handler_IO (int status) { printf("received SIGIO signal.\n"); wait_flag = FALSE; } 3.4. ¡ÌüÍ©çÌüÍÒ¿ ±ÌÍÍÈPÉÏܹܷDqg𦷱ƪÚIÈÌÅCTvÌv OàZ¢àÌɵĢܷD±ÌdgÍVA|[g¾¯ÅÈCSÄ Ìt@CfXNv^ÌWÉεÄg¤±ÆªÅ«Ü·D select VXeR[Ʊêɺ¤}NÅÍCfd_set ðg¢Ü·D±ê ÍCSÄÌLøÈt@CfXNv^ÌGg[ªÜÜêérbgñÅ ·Dselect Ít@CfXNv^ÉηérbgW fd_setðøÆ µCfd_setÉüoͪÂ\Èt@CfXNv^C é¢ÍáOª¶µ½ t@CfXNv^ÌWðZbgµÜ·Dfd_set ÌìÍpÓ³êÄ¢ é}NÅs¢Ü·DÚµÍIC}j AÌ select(2) ðQƵ ľ³¢D #include <sys/time.h> #include <sys/types.h> #include <unistd.h> main() { int fd1, fd2; /* üÍ\[X 1, 2 */ fd_set readfs; /* t@CfXNv^ÌW */ int maxfd; /* gíêÄ¢ét@CfXNv^ÌÅål */ int loop=1; /* [vµÄ¢éÔÍ TRUE */ /* open_input_source ÅÍfoCXÌI[vC³µ¢|[gÌÝèªsí êCt@CfXNv^ªßµlÉÈÁÄ¢éàÌÆ·éD */ 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; /* ²×érbg·ÌÅål */ /* üÍ̽ßÌ[v */ while (loop) { FD_SET(fd1, &readfs); /* \[X 1 ð²×é±Æðwè */ FD_SET(fd2, &readfs); /* \[X 2 ð²×é±Æðwè */ /* block until input becomes available */ select(maxfd, &readfs, NULL, NULL, NULL); if (FD_ISSET(fd1)) /* \[X 1 ©çÌüͪÂ\ */ handle_input_from_source1(); if (FD_ISSET(fd2)) /* \[X 2 ©çÌüͪÂ\ */ handle_input_from_source2(); } } ±ÌáÅÍCÇ¿ç©Ì\[X©çüͪsíêéÜÅCvOª¢ÂÜ ÅàubN³êĵܢܷDüÍÌ^CAEgðwèµ½¢êÉÍC select VXeR[̪ðÌæ¤É«·¦Ü·D int res; struct timeval Timeout; /* üÍ[vÅÌ^CAEglðÝè */ Timeout.tv_usec = 0; /* ~b */ Timeout.tv_sec = 1; /* b */ res = select(maxfd, &readfs, NULL, NULL, &Timeout); if (res==0) /* üͪ Á½t@CfXNv^̪ 0 ÈçÎC^CAEg¶ */ ±ÌáÅÍ 1 bãÉ^CAEgÉÈèÜ·D^CAEgÆÈÁ½êÉ ÍCselect Í 0 ðԵܷªCTimeout Í selectªÀÛÉüÍðÒÁ½ Ô̪¾¯¸ç³êé±ÆÉӵľ³¢D^CAEglª[Ìê ÉÍCselect ͦÀÉAÁÄ«Ü·D 4. ¼Ìîñ¹ o Linux Serial-HOWTO ÉÍVA|[gÌÝèû@ÆCn[hEFAÌî ñª©êĢܷD o Serial Programming Guide for POSIX Compliant Operating Systems <http://www.easysw.com/~mike/serial>DMichael Sweet ³ñÌy[WÅ ·D±ÌNͽÇêÈÈÁĵÜÁ½ÌÅ·ªCVµ¢ URL ªí© èܹñDÇȽ©³¦Ä¾³¢DÇÅ«½¶¾Á½ÌÉI o IC}j AÌtermios(3)ÉÍCtermios \¢ÌÌSÄÌtO Ìྪ èÜ·D 5. Rgr [V ÅÉq×½æ¤ÉCMÒͱ̪ìÌGLXp[gÅÍ èܹñDµ© µC©ª©gÅâèɼʵC¼Ìl̯ðØèȪçâèððµÜµ ½D European Transonic Windtunnel, Cologne Ì Strudthoff C Michael Carter (mcarter@rocke.electro.swri.eduCPeter Waltenberg (p.waltenberg@karaka.chch.cri.nz)ÌFlɴӵܷD Antonino Ianella (antonino@usa.netÍCMÒª±Ì¶ðõµÄ¢éÌ ÆÙÚ¯É Serial-Port-Programming Mini HOWTO ð쬵ܵ½DGreg Hankins ÌñÄÉæèCAntonino Ì Mini-HOWTO ð{¶ÆµÜµ ½D ±Ì¶Ì\¢Æ SGML Éæé®`ÍCGreg Hankins Ì Serial-HOWTO ð îɵĢܷD{¶ÉC³ðüêÄê½ Dave Pfaltzgraff (Dave_Pfaltzgraff@patapsco.com)C Sean Lincolne (slincol@tpgi.com.au)C Michael Wiedmann (mw@miwie.in- berlin.de)C Adrey Bonar (andy@tipas.lt) ÌF³ñɴӵܷD