Ismael Ripoll §@ªÌ²¤¶¡G ¤@¤E¤E¤»¦~©ó Valencia ºî¦X¬ì§Þ¤j¾Ç¨ú±o³Õ¤h¾Ç¦ì¡C ¥Ø«e¥ô¾©ó DISCA¡A ¬°§@·~¨t²Î±M®a¡C ¬ã¨s±MÃD¦³§Y®É¨t²Î±Æµ{ºÞ²z©M§@·~¨t²Îµ¥µ¥¡C ¤@¤E¤E¥|¦~¦¨¬° Linux ªº¤@¥÷¤l¡C ¶Ý¦n¦³¡G Ãkµn¬£·ç¥§´µ¤s¯ß (Pyrenees)¡B ·Æ³·¡B ¥H¤Î·í¤@¦Wºô¸ô¹C«L¡C »P§@ªÌÁpô ¤º®e¥Ø¿ý¡G »Å»Åªº Linux §Y®É¨t²Î (KURT) §Y®É¨t²Î¦³¤°»ò¦nªº¡S ¥i¸ü¤Jªº¼Ò²Õ §Y®É¨t²Îµ{¦¡ ¥ô°È³q°T µ²½× °Ñ¦Ò¸ê®Æ |
RT-Linux II¤º®eºKn¡G ³o¬O²Ä¤G½g±´°Q RT-Linux ªº¤å³¹¡A §Ú·|¸ÕµÛ¥H§ó¹ê°ÈªºÆ[ÂI¨Ó»¡©ú RT-Linux¡C ¤£¹L¡A ¦b²`¤J²Ó¸`¤§«e¡A §Ú¥´ºâ¥ý¥Î¤@¬q¤å¦r¸Ñ»¡¤@¤E¤E¤K¦~ªì¡A èµo®i¦¨¥\ªº§Y®É§@·~¨t²Îªº¯S¦â¡A ¦W¬° Linux KURT¡C »Å»Åªº Linux §Y®É¨t²Î (KURT)¤@¤E¤E¤K¦~ªì¡A ¦³¤@Ó¥H Linux ¬°°ò¦¤§·sªº§Y®É¨t²Î½Ï¥Í¤F¡C KURT ¬O³n¦¡ªº§Y®É§@·~¨t²Î (soft real-time system)¡A ¤ñ¦p»¡¡A ±Æµ{µ{¦¡·|¸ÕµÛ¥hº¡¨¬¥ô°È (task) °õ¦æ®É©Ò»Ý¨Dªº®É¶¡¡A §Y¨Ï¦³¥ô¦ó¥ô°È°õ¦æ§¹ªº®É¶¡¶W¹L©Ò¹w´Áªº¡A ¤]¤£·|³y¦¨¥ô¦óªº´d¼@¡C KURT ªº§Y®É©Ê¥ô°È¥i¥H¹B¥Î Linux ©Ò¦³ªº¤½¥Îµ{¦¡¡A ³o¤@ÂI«ê¦n¸ò RT-Linux ªº¥ô°È¬Û¤Ï¡C KURT §@·~¨t²Îªº®Ö¤ßµ{¦¡¦³¤@¨Ç§½³¡ªº×¥¿¡G
§Y®É¨t²Îªº¥ô°È³£¬O°ÊºA¸ü¤Jªº¼Ò²Õ¡C KURT ³Ì¨ã¯S¦âªº«K¬O±Æµ{µ¦²¤¡C ±Æµ{µ{¦¡¬O´`Àôªº¡A ³oºØ«¬¦¡ªº±Æµ{µ{¦¡¡A ¬O¹B¥Î¤@±i¦W¬°pµeªí (plan) ªºªí®æ¡A ¨ÓÀx¦s©Ò¦³¶i¤J±Æµ{ªº¥ô°Èªº°Ê§@¡G ±Ò°Êªº®É¨è¡B ¹w³Æ°õ¦æªº¥ô°È¡B ¥ô°Èªº©µ®Éµ¥µ¥¡C ³o±iªí®æ¶}¾÷®É´N·|«Ø¦n¡A µ¥¨ì¥ô°Èn°õ¦æ®É¡A ±Æµ{µ{¦¡ªº¤u§@¡A ´N¶È³Ñ¤U¨Ì§Ç¤@¶µ¶µÅª¨úªí¤¤ªº¸ê®Æ¤F¡C ·í±Æµ{µ{¦¡Åª¨ìªí¤¤ªº§ÀºÝ®É¡A ±Æµ{µ{¦¡·|¦^¨ìªí¤¤ªº³Ì¶}ÀY³B¡A Ä~Äò³B²z¥ô°Èªº°õ¦æ¤u§@ ¡X¡X ¤]´N¬O³o¼Ë¡A ¤~§â³oºØ±Æµ{µ{¦¡¡A ©R¦W¬°´`Àô±Æµ{µ{¦¡ (cyclic scheduler)¡C ´`Àô±Æµ{µ{¦¡¦³½Ñ¦hªºÀuÂI¡G
³Ì¥Dnªº§xÃøÂI¡A ´N¦b©ó«ç¼Ë¥h»s§@pµeªí¤F¡C ÁÙ¦³¡A ¨C¦¸¥un¦³¥ô¦ó¤@¶µ¥ô°Èªº°Ñ¼Æ°µ¤F×¥¿¡A ´N¥²¶·««Øpµeªí¡F ¦P®É¡A Àx¦spµeªí©Ò»Ýªº°O¾ÐÅé¤]¤jªºÅå¤H¡C §Y®É¨t²Î¦³¤°»ò¦nªº¡S¤]³\¦h¼Æ¤H³£¥H¬°¡A §Y®É¨t²Îªº§Þ³N¥u¯àÀ³¥Î¦b NASA¡A ©Î¬O¾É¼u¡B ¯èªÅ¾¹¤§Ãþªº»â°ì¸Ì¡C ÁöµM¡A ¦b¦h¦~¥H«e¡A ³oªº½T¬OÓ¤£§é¤£¦©ªº¨Æ¹ê¡A µM¦Ó¡A ¥@¨Æ쥻´N·É®áÃø®Æ¡A ªñ¦~¨Ó¥Ñ©ó¸ê°T¨t²Î©M¹q¤lªº¾ã¦XÀ³¥Î¡A ¥¿³v¨B¤j¶q¦a¤Þ¶i¤@¯ë¤Hªº¤é±`¥Í¬¡¤¤¡A±¡¶Õ¤w¸g¦³¤F§ïÅÜ¡C ©M§Ṳ́é±`¥Í¬¡®§®§¬ÛÃö³Ìª½±µªºÃÒ¾Ú¡A ´N¬O¹q¶Ç³q°T (telecommunications) ©M¦h´CÅ骺À³¥Î»â°ì¡A ¤ñ¦p»¡¡A ¦pªG§ÚÌ·QnÅý¹q¸£¡A ¥i¥H«Âм½©ñ¤@ÓÀx¦s©óµwºÐ¸Ìªºµ®ÄÀÉ¡A ³B²zµ®Äªºµ{¦¡´N±o¤£Â_¦a ¡]©ÎªÌ§ó¦nªº¡A ¬O©T©w©P´Áªº¡^ ¥hµwºÐ¸ÌŪ¨úÀɮ׸ê®Æ¡A ¸ÑÀ£ÁY¡A µM«á§â¼Æ¦ì¸ê®Æ°e¥X¥hµ¹µ®Ä¥d¡C °²¦p»¡¡A ¦P¤@®É¶¡¡A §ÚÌ¥¿¦b¾Þ§@¤@®MÀ³¥Î³nÅé¡A ¥i¯à¬O¤å®Ñ³B²zµ{¦¡¡A ©Î¬O¥¿¦b½sĶ Linux ªº®Ö¤ßµ{¦¡¡F ÅãµM¡A CPU ³B²z¾¹·|¥H©P´Á´`Àôªº¤ù¬q®É¶¡¡A ¨Ó³B²z¨ä¥Lªº¥ô°È¡C ¦pªG¤£©ñµ®Ä¡A §ï¦b¿Ã¹õ¤W«Âм½©ñ¼v¹³¡A ·L³B²z¾¹¤À¬q³B²zªºµ²ªG¡A ¼v¹³«K·|¦³¶¡·²©Êªº°±¹y¡C ³oºØ¨t²Î«K¬O©Ò¿×ªº¡u³n¦¡§Y®É¨t²Î¡v ¡]°õ¦æ´Á¶¡¦³¤¤Â_ªº²{¶H¨Ã¤£·|³y¦¨¤°»ò¥¨¤jªº¨a®`¡A ¤£¹L¡A ³o¼Ëªº¨t²Îªº½T·|°§CªA°Èªº«~½è¡^¡C RT-Linux ªºÀ³¥Îµ{¦¡¡A ©M¤@¯ë¥¿±`ªº§Y®ÉÀ³¥Îµ{¦¡¤j²§¨ä½ì¡C ¹ï RT-Linux ¦Ó¨¥¡A §ÚÌ¥i¥H¥þµM´x±± PC ªº¹B§@ ¡]§Ú·|»¡ PC ¦Ó¤£¬O¹q¸£¡A ¬O¦]¬°¨ì¥Ø«e¬°¤î¡A °£¤F·L¹q¸£¤§¥~¡A RT-Linux ÁÙ¨S¦³²¾´Ó¨ì¨ä¥LºØªº¾÷¾¹¬[ºc¤W¥h¡^¡A ¦p¦P¹L¥hªº MSDOS ¤@¯ë¡C ·í¤@Ó§Y®É¨t²Îªº¥ô°È¥æµ¹ CPU ¥h°õ¦æ®É¡A ³oÓ°õ¦æ¤¤ªº¥ô°È¬O¥i¥H¥h¦s¨ú PC ¤W©Ò¦³ªº¦ì§}ªúªº¡A ¨Ò¦p´Ó¤J¤¤Â_ªA°È±`¦¡¡A ¼È®ÉÃö³¬¤¤Â_ªA°È±`¦¡ªº¥\¯àµ¥µ¥¡C ´«¥y¸Ü»¡¡A §ÚÌ¥i¥H"ºR·´"³o®M¨t²Î¡A ¦p¦Pµøµ¡¨t²Î¨º»òªº¤£³ô¤@À»¡C ¦ý¬O¡A ¸Ü¤S»¡¦^¨Ó¡A ³oºØ¤è«K¤§ªù¡A ¹ï©ó«Ü³ßÅw¼g¨Çºë¥©ªº¤pµ{¦¡¡A µ¹¦Û¤v¹q¸£¥h¶]ªº¤H¦Ó¨¥¡A «K¨ã¦³¬Û·í¤jªº¾y¤O¤F¡C ¥i¸ü¤Jªº¼Ò²Õn·QÁA¸Ñ RT-Linux¡A ÁÙ¦³¨ã³Æ¯à¤O¥h¨Ï¥Î RT-Linux¡A ¦³Ãö Linux °ÊºA¸ü¤J¼Ò²ÕªºÆ[©À¡A ¬O¦³¥²nª¾¹Dªº¡C Matt Welsh ¤w¸g¼g¤F§¹¾ãªº¤å¥ó¡A ¨Ó¸Ñ»¡¼Ò²Õ©Ò¦³ªº²Ó¸`¡C ¼Ò²Õ¨ì©³¬O¤°»ò¡S¤j³¡¥÷ªº UNIX ¨t²Î¦s¨úµwÅé®É¡]¦ì§}ªú¡B°O¾ÐÅé¡B¤¤Â_µ¥µ¥¡^¡A ³£¬O¸g¥Ñ¯S§OªºÀɮרӳB²zªº¡A ³q±`¤]³£¬O°ß¤@ªº¤èªk¡C ¨t²Î¦w¸Ë®É¡A ·|¨Æ¥ý¦w¸Ë¦n¨C¤@ºØ¶gÃä³]³Æ©Ò»ÝªºÅX°Êµ{¦¡¡C ¤£¹L¡A ¦³«Ü¦h¤£¿ùªº®ÑÄy³£¦³±Ð§ÚÌ«ç»ò¥h¼g³]³ÆÅX°Êµ{¦¡¡A ³o±`±`¬O¬JµL²á¤S¤¾ªøªº¤u§@¡A ¦]¬°§Ú̱o¼g¥X¬°¼Æ¤£¤Öªº¨ç¼Æ¡A §âÅX°Êµ{¦¡©M¨t²Î³sµ²°_¨Ó¡C ¼Ò²Õ¥i¥H»¡¬O"§@·~¨t²Îªº¤ù¬qµ{¦¡½X"¡A ¥i¥H¦b°õ¦æ´Á¶¡ÀH®É¥[¤J©Î¬O©âÂ÷¥X¨Ó¡C °²³]¦³¤@¤äµ{¦¡ªºì©l½X¡A ¤À§OÀx¦s¦b¦UÓ¤£¦PªºÀɮ׸̡A n®³¨Ó½sĶ¡A º¥ý¡A ¨CÓ³æ¤@ªºÀÉ®×·|¥ý³Q°µ¦¨ ".o" ¤§¥ØªºÀÉ¡A µM«á¡A ©Ò¦³ªº¥ØªºÀɦA³sµ²¦¨³æ¤@ªº¥i°õ¦æÀÉ¡C °²³]¥ØªºÀɤ¤¡A ¦³¤@ÓÀɮקt¦³ main ³oÓ¨ç¼Æ¥i¥H°õ¦æ¡A ¨º»ò§@·~¨t²Î«K¥i¥H±N³oÓÀɮ׸ü¤J°O¾ÐÅ餤°õ¦æ¡A ¨Ã¥B¦b»Ýnªº®ÉÔ¡A §â¨ä¥Lªº¥ØªºÀɳsµ²¶i¨Ó¤@°_°õ¦æ¡C ·íµM¡A ®Ö¤ß¥»¨¦ÛµM¦³¯à¤O³B²z³o¼Ëªº°ÝÃD¡C ¨Æ¹ê¤W¡A ·í Linux ¶}¾÷¤§«á¡A ¤]¥u¦³°õ¦æÀÉ vmlinuz ¸ü¤J°O¾ÐÅé¸Ì¡A vmlinuz §t¦³ Linux ®Ö¤ß¤£¥i©Î¯Êªº¤¸¥ó¡A «Ý¨t²ÎÂର°õ¦æ´Á¶¡®É¡A ®Ö¤ß«K¥i¨Ì»Ý¨D¨Ó¸ü¤J©Ò»Ýªº¼Ò²Õ¡A ©Î¬OÄÀ©ñ¤£»Ýnªº¼Ò²Õ¡C ¹ï Linux ®Ö¤ß¦Ó¨¥¡A ¼Ò²Õ¬O¥i¦³¥iµLªº¯S¦â¡C ³o¶µ¯S¦â¥²±o¦b½sĶ®Ö¤ß®É¡A ¿ï¾Ü¾A·íªº¿ï¶µ¤~±o¥H³º¥þ¥\¡C ´N§Ú©Òª¾¹Dªº¡A ©Ò¦³µo¦æ¨t²Îªº®Ö¤ßµ{¦¡¡A ³£¬O¥H¼Ò²Õ¤Æ©w¬°¹w³]¿ï¶µªº¡C §Ú̬Ʀܩó¥i¥H´À¨t²Î³]p·sªº¼Ò²Õ¡A ¨Ã¥Ñ®Ö¤ß¸ü¤J°õ¦æ¡A ¦Ó¤£¥Î«·s½sĶ¨t²Î¡A ¤]¤£¥Î«·s±Ò°Ê¨t²Î¡C ·í¤@¼Ò²Õ¸ü¤J®Ö¤ß®É¡A «K¦¨¤F§@·~¨t²Îªº¤@³¡¥÷¡A ¦]¦¹¡G
¦p¦P§ÚÌ©Ò¨£ªº¡A °ÊºA¸ü¤J¼Ò²Õ¤w¸g¦³¤@¨Ç§Y®É¨t²Îµ{¦¡ªº¯SÂI¡G °ÊºA¸ü¤J¼Ò²Õ¡A ·|ÁקK¥Ñ¤À¶¿ù»~©Ò³y¦¨ªº®É¶¡©µ¿ð¡A ¦Ó¥B°ÊºA¸ü¤J¼Ò²Õ¡A ¥i¥H¦s¨ú©Ò¦³ªºµwÅé¸ê·½¡C «ç»ò«Ø¼Ò²Õ¡S «ç»ò¥Î¡S¼Ò²Õ¥i¥H "C »y¨¥" ¨Ó¼g¡C ³o¸Ì¦³Ó¤p¤p¼Ò²Õªº¨Ò¤l ¡]n°õ¦æ¤U±©Ò´£¨ìªº©R¥O¡A³Ì¦n¬O¥H su¡Broot ªº¨¥÷µn¿ý¨t²Î¡^¡G example1.c #define MODULE #include <linux/module.h> #include <linux/cons.h> static int output=1; int init_module(void) { printk("Output= %d\n",output); return 0; } void cleanup_module(void){ printk("Adiós, Bye, Chao, Ovuar, \n"); } ¥H¤U¤@¦æªº°Ñ¼Æ¨Ó½sĶ example1.c¡G # gcc -I /usr/src/linux/include/linux -O2 -Wall -D__KERNEL__ -c example1.c¿ï¶µ -c ¬On¨D gcc ¦b²£¥Í¥ØªºÀɤ§«á´N°±¤U¨Ó¡A ¤£n¦A°µ³sµ²ªº°Ê§@¡C ³Ì«áªºµ²ªG¬O¤@ӥتºÀÉ¡A example1.o¡C ®Ö¤ßµ{¦¡¯Ê¤Ö¼Ð·Ç¿é¥X¨ç¼Æ¡A ¦]¦¹§Ṳ́£¥i¥H¥Î printf() ³oÓ¨ç¼Æ¡A ¦Ón¥H®Ö¤ßµ{¦¡©Ò´£¨Ñªº printk() ¨ç¼Æ¨Ó¥N´À¡C printk() ©M printf() ´X¥G¨S¤°»ò¨â¼Ë¡A °ß¤@ªº®t§O¬O printk() ·|§â¿é¥Xªºµ²ªG¡A °e¨ì®Ö¤ßµ{¦¡ªºÀô½w½Ä°Ï (ring buffer) ¸Ì¡C ³oÓ½w½Ä°Ï¬O¨t²Î©Ò¦³°T®§¶°¤¤ªº¦a¤è¡A ´N¹³¶}¾÷®É©Ò¨£¨ìªº°T®§¡A ³£¥i¥H¦b³oÓÀô½w½Ä°Ï¸Ì§ä¨ì¡C ¥ô¦ó®ÉÔ¡A §Ú̳£¥i¥H¥Î dmseg ©R¥O¬d¬Ý½w½Ä°Ïªº¤º®e¡A ©Î¬Oª½±µÀËÅç /proc/kmsg ³oÓÀɮסC ª`·N¨ì³oӼҲո̨èS¦³ main() ¨ç¼Æ¡A ¤Ï¦Ó¦³Ó¤£±a¥ô¦ó°Ñ¼Æªº init_module() ¨ç¼Æ¡C cleanup_module() ¬O³Ì«á¤@ÓÄÀ©ñ¼Ò²Õ«e¡A ©Ò¥²¶·©I¥sªº¨ç¼Æ¡C insmod ¬O¥Î¨Ó¸ü¤J¼Ò²Õ¡A µM«á°õ¦æ¼Ò²Õªº¡C # insmod example1.o ²{¦b¡A §Ṳ́w¸g¦w¸Ë¦n example1 ¼Ò²Õ¤F¡A ¦Ó¥B¤]°õ¦æ¤F example1 ªº init_module() ¨ç¼Æ¡C n¬Ýµ²ªG¡A ½Ð¥´¤U¦Cªº©R¥O¡G # dmesg | tail -1 Output= 1 ©R¥O lsmod ·|¦C¥X·í«e©Ò¦³¸ü¤J®Ö¤ß¤¤ªº¼Ò²Õ¡G # lsmod Module Pages Used by: example1 1 0 sb 6 1 uart401 2 [sb] 1 sound 16 [sb uart401] 0 (autoclean) ³Ì«á©O¡A§Ú̥Πrmmod ¨ÓÄÀ©ñ¼Ò²Õ¡G # rmmod example1 # dmesg | tail -2 Output= 1 Adiós, Bye, Chao, Orvua, dmesg Åã¥Ü¤F¨ç¼Æ cleanup_module() ¤w¸g°õ¦æ¤F¡C ²{¦b¡A §ÚÌ¥u®tÁÙ¤£ª¾¹D«ç»ò§â°Ñ¼Æ¶Çµ¹¼Ò²Õ¤F¡C ³oÓ¤èªk¥X©_ªºÂ²³æ¡A ¥un«ü©w¼Æȵ¹¾ãÅéÅܼơA ¦AÂÇ¥Ñ insmod §â°Ñ¼Æ¶Ç»¼µ¹¼Ò²Õ´N¦æ¤F¡C ¨Ò¦p¡G # insmod ejemplo1.o output=4 # dmesg | tail -3 Output= 1 Adíos, Bye, Chao, Orvua, Output= 4 ²{¦b¡A ¼Ò²Õ¤j¤j¤p¤pªº¨Æ±¡¡A ¸Óª¾¹Dªº³£ª¾¹D¤F¡C ¦^ RT-Linux ¤F§a¡I §Aªº²Ä¤@Ó§Y®É¨t²Îµ{¦¡º¥ý¡A °O¦í¤@ÂI¡A n·Q¥Î RT-Linux¡A ´N±o¹w¥ý·Ç³Æ¦n Linux ªº®Ö¤ßµ{¦¡¡A ¥H¤ä´©§Y®É¨t²Î¼Ò²Õ¡C ³o¤@³¡¥÷ªº»¡©ú¡A ¸Ô¨£²Ä¤@½g¤å³¹¡C RT-Linux ¥i¥H¦³¨âºØ¾Þ§@¤èªk¡G
³o¤@¦¸§Ú·Q¥ý°Q½×¦b²Ä¤@ºØ±¡ªp¤U¡A «ç¼Ë§â RT-Linux ·í§@§Y®É¨t²Î¨Ó¨Ï¥Î¡C »Õ¤U§Y±Nn¬Ý¨ìªºµ{¦¡½d¨Ò¡A ¥»¨¨Ã¨S¦³¤°»ò"¥Î³~"¡A ¶È¶È¬O³]©w¤F¤@Ó§Y®É¨t²Îªº¥ô°È¦Ó¤w¡]¤@Ó²³æªº°j°éµ{¦¡¡^¡G example2.c#define MODULE #include <linux/module.h> #include <linux/kernel.h> #include <linux/version.h> #include <linux/rt_sched.h> RT_TASK task; void fun(int computo) { int loop,x,limit; limit = 10; while(1){ for (loop=0; loop<computo; loop++) for (x=1; x<limit; x++); rt_task_wait(); } } int init_module(void) { RTIME now = rt_get_time(); rt_task_init(&task,fun, 50 , 3000, 1); rt_task_make_periodic(&task, now+(RTIME)(RT_TICKS_PER_SEC*4000)/1000000, (RTIME)(RT_TICKS_PER_SEC * 100)/1000000); return 0; } void cleanup_module(void){ rt_task_delete(&task); } ¦P¼Ëªº¡A¥H¤U¦Cªº©R¥O¨Ó½sĶ example2.c¡G # gcc -I /usr/src/linux/include/linux -O2 -Wall -D__KERNEL__ -D__RT__ -c example2.c¬JµM¬O¼Ò²Õ¡Aµ{¦¡ªº°_ÂI¦ÛµM¬O¨ç¼Æ init_module()¤F¡C³oÓ¼Ò²ÕÀY¤@¥ó°µªº¨Æ´N¬O¥hŪ·í«eªº®É¶¡µM«á§â®É¶¡Àx¦s¦b¤@Ó§½³¡ÅܼƸ̡Crt_get_time()¨ç¼Æ·|¶Ç¦^±q¶}¾÷°_©Ò¸g¹Lªº®É¶¡È RT_TICKS_PER_SEC ¡]¥Ø«e¨ÓÁ¿¡A RT_TICKS_PER_SEC¬O1.193.180¡A¸ÑªR«×¬O0.838 micro-seconds¡^¡C °õ¦æ¨ìrt_task_init()®É¡A"task" structure·|¶i¦æªìȳ]©w¡A¦ýÁÙ¨S¶}¶]¡C ³oÓªº¥ô°Èªº¥Dµ{¦¡¬Ofun()¡A²Ä¤GӰѼơC¤U¤@ӰѼƬO·í·staskn¶}©l°õ¦æ®É¡An¶Ç»¼µ¹·staskªº¸ê®ÆÈ¡Cnª`·N¨ìfun()nªº¬Oint«¬ºAªº°Ñ¼Æ¡C¤U¤@ӰѼƬOtask°ïÅ|ªÅ¶¡ªº¤j¤p¡A³o¬O¦]¬°¨C¤@Ótask³£¦³¥L¦Û¤vªº°õ¦æºü¡]thread of execution¡^¡A¦]¦¹¨CÓtask³£»Ýn¦³¦Û¤vªº°ïÅ|ªÅ¶¡¡C³Ì«á¤@ӰѼƬOÀu¥ýÅv¡F´N³oÓµ{¦¡¨Ò¨ÓÁ¿¡A¥u¦³¤@¥ó¥ô°È¦b¨t²Î¤W°õ¦æ¡A§ÚÌ¥i¥H³]©w¥ô¦ó©Ònªº¼ÆÈ¡C rt_task_make_periodic()·|§â¥ô°ÈÂà´«¦¨´`Àô¦¡¥ô°È¡C³o»Ýn¨âӮɶ¡°Ñ¼Æ¡A²Ä¤@Ó¬O°O¿ý¥ô°È²Ä¤@¦¸³Q±Ò°Êªºµ´¹ï®É¶¡¡A¦Ó²Ä¤GÓ¬O³sÄò±Ò°Êªº¥ô°È¤§¶¡¡A±q²Ä¤@Ó¥ô°È°_ºâªº®É¶¡¶¡¹j¡C ³oÓ§Y®É¨t²Î¥ô°È¡]´N¬O¨ç¼Æfun()¡^¬O¤@ÓµL½aªº°j°é¡A¥u°µ¨â¥ó¨Æ±¡¡G¤@¬O®ö¶O®É¶¡ªº°j°é¡A¤G¬O©I¥s rt_task_wait()¡Crt_task_wait()¬O¥Î¨Ó¼È®É¤¤¤î¥ô°È°õ¦æªº¨ç¼Æ¡Aª½¨ì¤U¤@¦¸ªº±Ò°Ê®É¶¡¡]activation time¡^¨ì¤F¬°¤î¡C±µµÛ¥ô°È·|±qºò±µ¦brt_task_wait()«á±ªº±Ôz¶}©l°õ¦æ¡CŪªÌÀ³·í©úÁA¡A´`Àô¦¡ªº¥ô°È¨Ã«D¨C¦¸±Ò°Ê®É³£·|±qÀY¶}©l°õ¦æµ{¦¡¡A¦Ó¬O¦Û¦æ¼È°±°õ¦æ¡A¨Ãµ¥«Ý¤U¤@¦¸ªº±Ò°Ê®É¶¡¨ì¨Ó¡C³oºØ³]p¾÷¨î·|Åý¥ô°È¶È¦b²Ä¤@¦¸©I¥s®É°õ¦æ¤@¦¸ªìȳ]©wªº¤u§@¡A¦]¬°¥ô°È¤£·|±qÀY¶}©l°õ¦æ¡C °õ¦æ example2 ¤§«e¡A ¶·¥ý¦w¸Ë¦n rt_prio_sched ¼Ò²Õ¡A ³o¬O¦]¬° example2 »Ýn rt_task_make_periodic()¡B rt_task_delete() ©M rt_task_init() ³o¨Ç¨ç¼Æ¡C ¨ç¼Æ rt_get_time() ¨Ã¨S¦³¥]§t¦b³oӼҲո̱¡A ³oÓ¨ç¼Æ¦s©ñ¦b Linux ªº®Ö¤ßµ{¦¡¤¤¡A ¦]¦¹¨Ã¤£»Ýn¦h°µ¦w¸Ëªº°Ê§@¡C # modprobe rt_prio_sched # insmod ./example2.o ¤w¦³ªº rt_prio_sched¡A ¬O¨t²Î¥»¨ªº¼Ò²Õ¡C ³oÓ¼Ò²Õ·|¦b Linux ®Ö¤ß½sĶ´Á¶¡«Ø¥X¨Ó¡A µM«á«þ¨©¨ì /var/modules/2.0.33/ ³oӥؿý©³¤U¡C §Ų́ϥΠmodprobe ³oÓ©R¥O¡A ì¦]¬O³o¬OÓ¤ñ¸û²³æªº¤u¨ã¡A ´N¸ü¤J¼Ò²Õ¨ÓÁ¿¡]modprobe·|¦b¼Ò²Õªº¥Ø¿ý¤¤·j´M±ý¸ü¤Jªº¼Ò²Õ¡^¡C ¡]°Ñ¨£ modprobe(1)¡^¡C ÕY©Ò¦³ªº¨BÆJ³£«Ü¶¶§Q¡A ¥un¦A¥[ lsmod ©R¥O¡A ´N¥i¥H¬Ý¨ì¨âÓ¼Ò²Õ³£¥¿½T¦a¸ü¤J¤F¡C ¶â¡A ¨ì¤F³oÓ¶¥¬q¡A »Õ¤U¤w¸g¦³¤F¤@Ó§Y®É¨t²Îµ{¦¡¦b¨t²Î¤W¶]¤F¡C §A¦³¨S¦³µo²{¤°»ò¯S§Oªº¨Æ±¡µo¥Í¡S °²¦p³B²z¾¹¥»¨´N¶]±o¤ñ¸ûºC¡A §A·|µo²{ Linux ¶]±o¤ñ¥±`ÁÙnºC¡C §A¥i¥H¸ÕµÛ¥h¼W¥[ fun() ¨ç¼Æ¤¤¡A ¤º³¡°j°éªº¥æ´À¦¸¼Æ¡A ¥un§ïÅÜ rt_task_init() ¨ç¼Æªº²Ä¤TӰѼƫK¥i¥H¤F¡C §Ú«ØijŪªÌ¤£§«¶]¤@¤U ico¡A ¬d¬d¬Ý³B²z¾¹¯à³Ñ¾lªº®É¶¡¤Ö¤F¦h¤Ö¡C ¦]¬°§Y®É¨t²Îµ{¦¡©Ò¯Ó¥Îªº®É¶¡¡A ·|³y¦¨³B²z¾¹¹³¬O³t«×ÅܺC¤Fªº¡A Linux ·|¥H¬°©Ò¦³ªºµ{§Ç¡A ©Ò»Ý¨Dªº°õ¦æ®É¶¡¶W¹L쥻©Ò»Ýªº¡C ¦pªGpºâ¥X¨Óªº®É¶¡ ¡X¡X ´N¬O°õ¦æ©Ò¦³°j°é©Ò»Ýªº®É¶¡ ¡X¡X ¤j¹L 100 ²@¬í (microseconds)¡A Linux ´N·|"±¾"¦b¨ºÃä¤F¡C ¦]¬° Linux ¬OI´ºµ{¦¡¡A ¦Ó³oÓ§Y®É¨t²Î¥ô°È·|¯ÓºÉ©Ò¦³ªº®É¶¡¡C ¨Æ¹ê¤W¡A Linux ¨Ã¨S¦³±¾±¼¡A Linux ¥u¬O±o¤£¨ì³B²z¾¹ªº®É¶¡½}¤F¡C ¥ô°È³q°TRT-Linux ¥u¦³¤@ºØ¥ô°È³q°Tªº¤èªk¡G Real-Time FIFO¡C ³oÓ¤èªk«ÜÃþ¦ü UNIX ªº PIPEs¡A ¶È¥H¸ê®Æ¬y¨Ó³q°T¡A ¦Ó¨S¦³¥ô¦óªº¸ê®Æµ²ºc¡C FIFO ¬O¤@¶ô©T©w¤j¤pªº½w½Ä°Ï¡A ¥Î¨ÓŪ¼g¸ê®Æ¤§¥Î¡C ±Ä¥Î FIFOs ¥i¥HÅý§Y®É¨t²Î¡A ¥ô°È¶¡ªº¤º³¡³q°TÁÍ©óéw¡F ¹ï©ó¤@¯ë Linux ªº¥ô°È¦Ó¨¥¡A ¤]¦P¼Ë¾A¥Î¡C ±q¥¿±`µ{§Ç (process) ªº²´¥ú¨Ó¬Ý¡A FIFO ¬O¤@Ó¯S®í¦r¤¸ªºÀɮסC ¤@¯ë¦Ó¨¥¡A ·|¬O /dev/rtf0¡B /dev/rtf1 µ¥µ¥½Ñ¦p¦¹Ãþªº¡C ³o¨ÇÀɮר䣬O Linux 즳ªº¡A ©Ò¥H¥²¶·ÃB¥~¦A«Ø¡C ¤èªk¦p¤U¡G # for i in 0 1 2 3; do mknod /dev/rtf$i c 63 $i; done¦pªG FIFOs ªº»Ý¨D¶W¹L¤W¦C©ÒÁ|ªº¡A ¨ä¥Lªº FIFO ´N¥i¥H¨Ì¼Ëµe¸¬Äª¦a»s§@¥X¨Ó¡A ¦p rtf4¡B rtf5 µ¥µ¥¡C ³o¨Ç¯S®íÀɮתº§@¥Î¡A ´N¦n¹³handlerªº¤¶±¤@¼Ë¡A ¦ý¬O¦pªG handler ¤£¦s¦b¡A ³o¨Ç¯S®íÀÉ®×´N¤@ÂI»ùȤ]¨S¦³¤F¡C ¨Æ¹ê¤W¡A ¦pªG§@·~¨t²Î¨S¦³¬Û¹ïÀ³ªº handler¡A ¤@©w¨S¦³¿ìªk¦¨¥\¦a¶}±Ò³o¨Ç¯S®íÀɮסC ³B²z FIFOs ªºÀɮשM¥¿±`ªºÀɮרS¤°»ò¨â¼Ë (open¡B read/write¡B close)¡C ¦pªG Linux ¥¿±`ªºµ{§Ç (process) n¨Ï¥Î FIFOs¡A º¥ý¡A §Y®É¨t²Îµ{¦¡±o¥ý«Ø¥ß¬Û¹ïÀ³ªº FIFO¡C ±q§Y®É¨t²Î¥ô°Èªº²´¥ú¨Ó¬Ý¡A FIFOs ¬O¸g¥Ñ¯S©w¨ç¼Æ¨Ó¨Ï¥Îªº¡G
¤U¤@Ó¨Ò¤l¨Ó¬Ý¬Ý³o¨Ç¨ç¼Æªº¨Ï¥Î¤èªk¡C ³o¬O¤@Ó RT-Linux¡]µ®Ä¡^µo¦æ¨t²Î¤¤¡A °µ¹L¨Ç·Lק諸¨Ò¤l¡G example3.c#define MODULE #include <linux/module.h> #include <linux/rt_sched.h> #include <linux/rtf.h> #include <asm/io.h> RT_TASK task; static int filter(int x){ static int oldx; int ret; if (x & 0x80) { x = 382 - x; } ret = x > oldx; oldx = x; return ret; } void fun(int dummy) { char data; char temp; while (1) { if (rtf_get(0, &data, 1) > 0) { data = filter(data); temp = inb(0x61); temp &= 0xfd; temp |= (data & 1) << 1; outb(temp,0x61); } rt_task_wait(); } } int init_module(void){ rtf_create(0, 4000); /* enable counter 2 */ outb_p(inb_p(0x61)|3, 0x61); /* to ensure that the output of the counter is 1 */ outb_p(0xb0, 0x43); outb_p(3, 0x42); outb_p(00, 0x42); rt_task_init(&task, fun, 0 , 3000, 1); rt_task_make_periodic(&task, (RTIME)rt_get_time()+(RTIME)1000LL, (RTIME)(RT_TICKS_PER_SEC / 8192LL)); return 0; } void cleanup_module(void){ rt_task_delete(&task); rtf_destroy(0); } ¦p¦P²Ä¤GÓ½d¨Ò©Ò¥Ü¡A §ÚÌ»Ýn rt_prio_sched ¼Ò²ÕªºªA°È¡A ¦ý¬O¡A ³o¤@¦¸¬°¤F¨Ï¥Î FIFO¡A §ÚÌ¥²¶·¦P®É¸ü¤J rt_fifo_new ¼Ò²Õ¡C ÀW²v 8192Hz ªº´`Àô§Y®É¨t²Î¥ô°È¤w¸g«Ø¦n¤F¡C ¦pªG³o¥ô°Èµo²{¦³¥ô¦óªº¸ê®Æ¡A °e¨ì PC µoÁn¾¹ªº¦ì§}ªú¡A ´N·|±q FIFO 0 ¸ÌŪ¨ú¦ì¤¸²Õªº¸ê®Æ¡C ¦pªG§Ú̧â¤@Ó ".au" ®æ¦¡ªºµ®ÄÀɮ׫þ¨©µ¹ /dev/rtf0¡A ²{¦b´N¥i¥Hťť¬Ýµ®ÄÀɪºµ®Ä¦p¦ó¤F¡C ¦]¬° PC ªºµwÅé¡A ¶È¤¹³\¥H¤@¦ì¤¸¥h½Õ¸`«H¸¹¡A ©Ò¥H¤£¥²¥h¦b·Nµ®Äªº«~½è§C¦H¡C µo¦æ¨t²Îªº¥Ø¿ý testing/sound ¤¤¦³ linux.au ³oÓÀɮסA ¥i¥H¥Î¨Ó´ú¸Õ¡C ±µµÛ¬O½sĶµ{¦¡¡A µM«á°õ¦æ¡G # gcc -I /usr/src/linux/include/linux -O2 -Wall -D__KERNEL__ -D__RT__ -c example3.c# modprobe rt_fifo_new # modprobe rt_prio_sched # insmod example3.o # cat linux.au > /dev/rtf0 ª`·N¨ì cat ³oÓ¤u¨ãµ{¦¡¬O«ç»ò¥Î¨Ó°µÂмgÀɮתº¡A ¥]§t¤F¯S®íÀɮסC ©R¥O cp ¦³¦P¼Ëªº®ÄªG¡C n¤ñ¸û§Y®É¨t²Îªº¯S¦â·|«ç¼Ë¼v·Q½Æ»s«~ªº«~½è¡A §ÚÌ¥u¦n¥t¥~¦A¼gÓµ{¦¡¡A ¥Î Linux ¥¿±`ªºµ{§Ç¨Ó³B²z¬Û¦Pªº¤u§@¡G example4.c#include <unistd.h> #include <asm/io.h> #include <time.h> static int filter(int x){ static int oldx; int ret; if (x & 0x80) x = 382 - x; ret = x > oldx; oldx = x; return ret; } espera(int x){ int v; for (v=0; v<x; v++); } void fun() { char data; char temp; while (1) { if (read(0, &data, 1) > 0) { data = filter(data); temp = inb(0x61); temp &= 0xfd; temp |= (data & 1) << 1; outb(temp,0x61); } espera(3000); } } int main(void){ unsigned char dummy,x; ioperm(0x42, 0x3,1); ioperm(0x61, 0x1,1); dummy= inb(0x61);espera(10); outb(dummy|3, 0x61); outb(0xb0, 0x43);espera(10); outb(3, 0x42);espera(10); outb(00, 0x42); fun(); } ³o¤äµ{¦¡¥i¥H¹³¨ä¥L²³æªºµ{¦¡¨º¼Ë¨Ó½sĶ¡G # gcc -O2 example4.c -o example4 And to execute it: # cat linux.au | example4 n¸g¥Ñ Linux ªºµ{¦¡¨Ó¦s¨úµwÅ骺¦ì§}ªú¡A§Ú̱o¥ý½Ð¨D§@·~¨t²Îªºã³\¡C ³o¬OÁקKµ{¦¡ª½±µ¦s¨úµwÅé¸ê·½¡A ³Ì°ò¥»¥B¥²nªº«OÅ@±¹¬I¡C ¨Ò¦p¡A ©I¥s¨ç¼Æ ioperm() ·|§i¶D Linux¡A §Ú̧Ʊæ¥h¦s¨ú¬Y¤@©w½d³òªº I/O ¦ì§}ªú¡C ¥u¦³·íµ{¦¡¬O¥H root ªº¨¥÷¨Ó°õ¦æ®É¡A µ{¦¡¤~¦³¥i¯à±o¨ì³oºØÅv¤O¡C ¥t¤@Óȱoª`·Nªº¬O¡A 8192Hz ªºÀW²v¦p¦ó½Õ¸`µ®Ä¡A ¨Ï¨ä²£¥ÍÁnµ¡C ÁöµM¦³Ó¨t²Î©I¥s¨ç¼Æ nanodelay() ¥i¥Î¡A ¦ý³oÓ¨ç¼Æ¶È¦³©T©wªº¦Ê¸U¤À¤§¤@¬í (milliseconds) ªº¸ÑªR«×¡F ¦]¦¹¡A §ÚÌ¥²¶·¨Ï¥Î°j°é¨ÓµêÀÀµ¥«Ýªº®É¶¡¡A ¨Ï®ÉÄÁ·|¼È°±¤@¤U¤U¡C ³oÓµ¥«Ý°j°é¥²¶·½Õ¾ã¨ì®t¤£¦h¥i¥H¦b 100MHz ªº Pentium ¤W°õ¦æ¡C ²{¦b¡A §Ú«ØijŪªÌ¤£§«´ú¸Õ¤@¤U example4 ©M ico¡C ÁnµÅ¥°_¨Ó«ç»ò¼Ë¡S §ï´«¦¨§Y®É¨t²Îª©¥»ªº Linux ·Pı¦p¦ó¡S §Y®É¨t²Î¬O¤£¬O¦³»ùÈ¥i¨¥©O¡S µ²½×²Ä¤G½g¤å³¹§âµJÂI©ñ¦b³]p§Y®É¨t²Îµ{¦¡¡C ¤å³¹¤¤©Ò¦CÁ|ªºµ{¦¡½d¨Ò¡A ³£«D±`²³æ¥B¯Ê¥F¹ê»Ú¥Î³~¡A ±µ¤U¨Óªº¨t¦C¤å³¹¡A §Ú·|´£¥X§ó¦³¥ÎªºÀ³¥Î½d¨Ò¡C §Ú̱N¥i¥H¥Î Linux ¨Ó±±¨î¹qµø¡A ¬Æ¦Ü©ó¥i¥H±q»·ºÝ¡A ¨Ó¨M©w§A©M§Aªº Linux ¤§¶¡³q°Tªº¤èªk (Linux box)!!! |
¥Dºô¯¸¥Ñ Miguel A Sepulveda ºûÅ@ © Ismael Ripoll 1998 LinuxFocus 1998 |