  RTLinux HOWTO
  Dinil Divakaran <mailto:dinildivakaran@rediffmail.com>
  1.1, 2002-08-29
  {: yomoyomo <ymgrtq@ma.neweb.ne.jp>
  v1.1j 2003 N 01  18 

  RTLinux ̓ Linux ŃA^CȃvOƂɂ
  ______________________________________________________________________

  ڎ

  1. ͂߂
     1.1 ړI
     1.2  HOWTO ǂނׂl
     1.3 ӎ
     1.4 tB[hobN
     1.5 zz̕j

  2. RTLINUX ̃CXg[
  3. Ȃ RTLinux Ȃ̂
  4. RTLinux ̃vO
     4.1 W[̏
     4.2 RTLinux ɂXbh̍쐬
     4.3 vO

  5. RpCƎs
  6. vZXԒʐM
     6.1 A^C FIFO
     6.2 FIFO 𗘗pAvP[V

  7. ɍs
  8. {ɂ

  ______________________________________________________________________

  1.  ͂߂

  1.1.  ړI

  ́̕AS҂̃[UAł邾ȒP RTLinux ғł
  悤ɂ邱ƂړIƂ܂B

  1.2.   HOWTO ǂނׂl

  ́̕AA^CJ[l̓m肽ƎvĂlBׂ
  ΏۂɂĂ܂BɃW[vO~OɐʂĂlB́A
  ̕̂Ƃ͊Ȃł傤BłȂlBɂĂASz
  Kv͂܂BW[vO~O̊{TOKv
  񂵁AɂĂ͕KvȂƂŎۂɋc_܂̂ŁB

  1.3.  ӎ

  ܂A܂ĂꂽȂkł Pramode C. E 
  ӂƎv܂B܂AVictor Yodaiken ɂS̊ӂqׂ
  Ă炢܂B́̕AVictor Yodaiken eX̘_
  ꂽȂɂ͐Ȃł傤B܂A"A Linux-based Real-
  Time Operating System" Ƃ_ Michael Barabanov ɂӂ
  ܂B

  1.4.  tB[hobN

  ̕Ɋւ^ӌ͂ǂȂ̂łɊ}܂BȂ
  <mailto:dinildivakaran@rediffmail.com> [ĂB̕
  ɉԈႢAłŏCł悤Ɏɒm点ĂB
  ͊ӂ܂B

  1.5.  zz̕j

  Copyright (C)2002 Dinil Divakaran.

  ̓̕t[łBFree Software Foundation ɂ蔭sĂ
  GNU General Public License o[W2A(Cӂ) ȍ~
  o[W̏ɏ]Ă̕ĔzzCł܂B

  ͖̕ɗƂ҂ĔzẑłAȂۏ؂s
  ܂Biprւ̓KɂĂ̈Öق̕ۏ؂炠܂
  Bڂ́AGNU General Public License B

  2.  RTLINUX ̃CXg[

  RTLinux J[l̃RpC̑iḰA\߃pb`̂J[l
  2.2.18
  <http://ftp.kernel.org/pub/linux/kernel/v2.2/linux-2.2.18.tar.gz> (x86
  only)  2.4. 0-test1
  <http://ftp.kernel.org/pub/linux/kernel/v2.4/linux-2.4.0-test1.tar.gz>
  (x86, PowerPC, Alpha) _E[h /usr/src/ œWJ邱Ƃ
  B܂ www.rtlinux.org <http://www.rtlinux.org>  RTLinux J[l
  (o[W3.0)VɃRs[ /usr/src/rtlinux/ ɒuĂ
  B(̕ł́Avvg\̂ $ g܂)

  1. ł Linux J[lݒ肵Ă:

                     $ cd /usr/src/linux
                     $ make config
                             
                     $ make menuconfig
                             
                     $ make xconfig

  2. J[lC[Wrhɂ́Aȉ̂悤ɓ͂Ă:

                     $ make dep
                     $ make bzImage
                     $ make modules
                     $ make modules_install
                     $ cp arch/i386/boot/bzImage /boot/rtzImage

  3.  LILO ̐ݒs܂B/etc/lilo.conf t@CɈȉ4s
     ĂB

                     image=/boot/rtzImage
                     label=rtl
                     read-only
                     root=/dev/hda1

  x: L /dev/hda1 AȂ̊ɂ郋[gt@CVXe
  ɒuĂBׂt@CVXełȒPȕ
  @́A /etc/lilo.conf t@C̊̃Ggɂ "root=" 
  ƂłB

  4. ł̓Rs[^ċNALILO vvg 'rtl' Ɠ͂
     RTLinux J[l[hĂBꂩ /usr/src/rtlinux/ 
     'cd' ARTLinux ݒ肵܂B

                     $ make config
                             
                     $ make menuconfig
                             
                     $ make xconfig

  5. 悤₭ RTLinux ̃RpCł

                     $ make
                     $ make devices
                     $ make install

  Ō̎菇ɂAȉ̃fBNg쐬܂:

  /usr/rtlinux-xx (xx ̓o[WӖ)

   RTLinux ̃ftHg̃CXg[ƂȂfBNgŁA[
  UvO쐬RpĈɕKvȂ (include t@C
  A[eBeBAhLgȂ) ܂B܂AŌ̎菇ɂ
   /usr/rtlinux-xx wȉ̃V{bNN쐬܂B

  /usr/rtlinux

  ɂ킽݊mۂ邽߂ɁAȂg쐬ׂĂ
  RTLinux pvOɂāAftHg̃pX /usr/rtlinux Kp
  悤ɂĂB

  L:  Linux J[l̃IvVύXꍇ́Aȉ̎菇s
  ƂYȂ:

                  $ cd /usr/src/rtlinux
                  $ make clean
                  $ make
                  $ make install

  3.  Ȃ RTLinux Ȃ̂

  W Linux J[l̓𒲂ׂ΁ARTLinux ݌vR
  ܂B Linux J[l̓n[hEFA[Ux̃^XN؂藣
  ܂BJ[l̓XPW[OASYpAϓIɗDꂽ
  \AX[vbg񋟂悤e^XNɗDx蓖Ă܂B]āA
  ǂ̃[Ux̃^XNłĂÃ^XN CPU ɂ芄蓖Ă
  Ă^CXCX𒴉߂A Linux J[l̓^XN~ł
  ܂B̃XPW[OASYɉAfoCXhCoA荞
  ݕs\ȃVXeR[A荞ݖ≼zȂǂ\s
  \(unpredictability) ̌ɂȂ܂B܂Aȏ̗vf^XN
  A^C\̏QɂȂĂ܂B
  Linux A^CȐ\ۏ؂ȂƂ́AႦ 'mpg123' Ȃǂ̃v
  C[ŉy𒮂ĂȂAɂm̂Ƃ܂B\ߌ
  ߂ꂽ^CXCXŃvZXsŁAW Linux J[l
  ̓^XN𒆒f CPU ɕʂ̃^XN(Ⴆ΁AX T[o Netscape ̗
  グs^XN)蓖Ă邱Ƃ\łBʂƂāAy̘A
  Ă܂܂B̂悤ɁA CPU ԂׂẴvZXɌ
  z悤Ǝ݂邱ƂɂAJ[l͑̃CxgNȂ悤
  ł̂łB

  A^CJ[lȂ΁ÃJ[ľœvZXv^
  C~Oۏ؂邱Ƃ\Ȃ͂łBRTLinux J[ĺAŋc_
  \s\̌ƂȂ̂邱Ƃɂ胊A^C\
  Ă܂BRTLinux J[ĺAW Linux J[lƃn[hEFA
  ̊ԂɈʒuƍl邱Ƃł܂B Linux J[ĺAA^C
  w̃n[hEFAƂ݂Ȃ܂B܂胆[ÚA̃^XN
  ̓Ƃ̗Dx̐ݒ̗s܂B[U̓XPW[OA
  SYADxAspxȂǂ߂邱ƂŃvZX̐mȎs^C~
  Oł܂B RTLinux J[ĺAW Linux J[lɍŒ
  Dx蓖Ă܂B邱ƂŃ[U^XNA^CɎs
  邱ƂɂȂ܂B

  ۂ̃A^C\́AׂẴn[hEFA荞݂Ւf邱Ƃ
  B܂BRTLinux Ɋ֘A銄荞݂ɑ΂Ă̂݁AK؂Ȋ荞
  ݃T[rX[`삵܂BȊO̊荞݂͑SĈUۗ
  ARTLinux J[lAChԂɂȂW Linux J[lғ
  ƂɃ\tgEFA荞݂ƂăJ[lɂ킽܂B RTLinux ̎
  ŝ̂̓mvGveBułB

  A^C^XN͗D悳(܂肻̓n[hEFAɒڃANZX
  )Az͗p܂BA^C^XŃAɓI
  [h\ȁA Linux W[Ƃď܂BA^C^
  XN̏R[h́AA^C^XN\̂A RTLinux
  J[lɂ̊AAĉԐʒm܂B

  Linux J[lɂ͎Ȃ̂ŁARTLinux  Linux J[lƋ
  ܂BrIPȏCʂs΁A Linux J̖WɂȂ邱
  ƂȂA Linux J[ln[hA^Cɂ܂ς邱
  Ƃł܂B

  4.  RTLinux ̃vO

  4.1.  W[̏

  ăW[Ƃ͉ł傤? Linux ̃W[́Aʏ gcc  -c
  tOtĐꂽIuWFNgt@Cɉ߂܂BW[
  ̂́Amain() ֐̂Ȃʂ C t@CRpC邱Ƃ
  萶܂Bmain() ֐ȂɁAinit_module ֐
  cleanup_module ֐̃yA܂܂܂:

  o  init_module() ́ÃW[J[lɑg݂ލۂɃR[
     ܂Bɂ 0 ԂAsƂɂ͕̒lԂ܂B

  o  cleanup_module() ́ÃW[폜钼OɃR[܂B

  ʏ init_module() ł́AJ[lɉsnho^
  AJ[l̊֐̈Ǝ̃R[h(ʏ͉sAꂩ猳̊
  R[R[h)ɒu邩܂B cleanup_module() ֐
  ́Ainit_module() sƂׂĂɖ߂ƂɂȂĂ̂ŁA
  W[SɊOƂ\łB

  Ⴆ΁Amodule.c ƂO C t@C(main() ֐̑
  init_module()  cleanup_module() )ƂAȉ̂悤
  ɓ͂΁ÃR[hW[ɕϊ܂:

          $ gcc -c {SOME-FLAGS} my_module.c

  ̃R}hɂ module.o ƂÕW[t@C
  B module.o  'insmod' R}hgpăJ[lɑg݂߂܂:

          $ insmod module.o

  lɃW[폜ɂ 'rmmod' g΂悢ł:

          $ rmmod module

  4.2.  RTLinux ɂXbh̍쐬

  ʏ탊A^CAvP[V́A̎suXbhvō\
  BXbh́Aʂ̃AhXԂLyʂ̃vZX
  BRTLinux ł́AׂẴXbh Linux J[l̃AhXԂ
  L܂BXbhgƂ̗_́AReLXgXCb`ɔׂăX
  bhԂ̐؂ւɂ߂ČyƂɂ܂Bȉ̗ŏЉe
  𗘗p΁AXbh̎sSɐł܂B

  4.3.  vO

  Xbh̓𗝉̂ɍłǂ̂́AA^CvOg
  [X邱ƂłBႦ΁AȉɎvÓA1bɈxsA
  ̓x 'Hello World' Əo͂܂B

  vOR[h (file - hello.c) :

  #include <rtl.h>
  #include <time.h>
  #include <pthread.h>

  pthread_t thread;

  void * thread_code(void)
  {
          pthread_make_periodic_np(pthread_self(), gethrtime(), 1000000000);

          while (1)
          {
                  pthread_wait_np ();
                  rtl_printf("Hello World\n");
          }

          return 0;
  }

  int init_module(void)
  {
     return pthread_create(&thread, NULL, thread_code, NULL);
  }

  void cleanup_module(void)
  {
     pthread_delete_np(thread);
  }

  ł init_module() n߂܂傤Binit_module() 
  pthread_create() R[Ă܂Bpthread_create() ́AR[X
  bhƓɓ삷AVK̃Xbh쐬֐łB̊֐
  ́ALinux J[lXbh炵 (܂Ainit_module() pĂ
  )R[Ă͂܂B

          int  pthread_create(pthread_t  * thread,
                              pthread_attr_t * attr,
                              void * (*thread_code)(void *),
                              void * arg);

  쐬ꂽVKXbȟ^ pthread_t ŁA pthread.h wb_t@
  CŒ`Ă܂B̃Xbh́A֐ thread_code() sA
   arg Ƃēn܂B attr ́AVKXbhɓKp
  Xbhw肵܂B attr  NULL ȂAftHg̑
  Kp܂B

  ł thread_code() ͈ȂŃR[܂Bthread_code ́A
  A^CAďIƂO̍\vf琬܂B

  tF[Ył́Apthread_make_periodic_np() R[܂B

          int pthread_make_periodic_np(pthread_t thread,
                                       hrtime_t start_time,
                                       hrtime_t period);

  pthread_make_periodic_np ́As̏łXbh thread w
  ܂BXbh start_time Ŏw肳ꂽԂɎsJnAimbP
  ʂŎw肳ꂽ period ̊ԓ삵܂B
  gethrtime ́AVXeu[gĂ̎ԂimbPʂŕԂ܂B

         hrtime_t gethrtime(void);

  ̎Ԃ̓Zbg邱ƂC邱Ƃ܂Bgethrtime 
  ɁAPɑlԂ܂Bhrtime_t 64rbg̕t^
  łB

  pthread_make_periodic_np() ֐R[ƁAXbh͎ 1Hz 
  pxŒIɎs悤AXPW[ɖ߂܂BŃXbh
  ͏I܂B

  while() [v pthread_wait_np() ֐̃R[Ŏn܂܂B̊֐
  ́A̎Jn܂ŁAݓ삵Ă郊A^CXbh̎s
  ~܂B̃Xbh͑O pthread_make_periodic_np ɂsw
  肪Ă܂BXbhĂуR[ƁA pthread_wait_np() 
  炽߂ăR[܂ while [v̎c̏s܂B

  [v𔲂iĂȂ̂ŁÃXbh 1Hz Ԋuŉiv
  sꑱ邱ƂɂȂ܂BvO~B̎íA rmmod
  R}hɂ肻J[l폜邱ƂłB rmmod 
  cleanup_module() R[܂Aꂪ Xbh𒆎~Ã\[
  X pthread_delete_np() R[̂łB

  5.  RpCƎs

  hello.c vOsɂ(łArtlinux ̃u[g
  ł)Aȉ̎菇sȂ΂Ȃ܂:

  1. GCC RpCgă\[XR[hRpCAW[𐶐
     ܂BƂ͂AMakefile 쐬čƂȗقǂ
     B΃\[XR[hRpĈ 'make' Ɠ͂邾
     ōς݂܂BMakefile ́A'Makefile' ƂÕt@CɈȉ
     e͂邱Ƃō쐬ł܂B

          include rtl.mk
          all: hello.o
          clean:
              rm -f *.o
          hello.o: hello.c
              $(CC) ${INCLUDE} ${CFLAGS} -c hello.c

  2. rtl.mk t@CAhello.c  Makefile ̂ƓfBN
     gɒuĂBrtl.mk t@ĆAR[hRpĈ
     KvȂׂẴtO܂ include t@CłBrtl.mk t@C
     RTLinux ̃\[Xc[Rs[ hello.c t@CƓfBN
     gɊi[ł܂B

  3. R[hRpCɂ́A'make' R}hgpĂB

             $ make

  4. ̌ʂłIuWFNgoCíAJ[l RTLinux ɂs
     镔ɑg݂܂ȂĂ͂Ȃ܂B'rtlinux' R}hgp
     Ă (ɂ 'root' ɂȂKv܂)B
             $ rtlinux start hello

   hello.o vObZ[W𖈕bo͂̂mFł͂
  łB}V̐ݒɂẮAR\[Œڌ邱Ƃł͂ł
  AłȂΈȉ̃R}h͂Ό邱Ƃł܂:

          $ dmesg

  vO~ɂ́AJ[l폜Kv܂B
  sɂ́Aȉ̃R}h͂Ă:

          $ rtlinux stop hello

  W[̑g݂݁A폜sʂ̂ƂāAꂼ insmod 
  rmmod 𗘗pƂ̂܂B

  ܂ł͗ƂȂvOȒP߂܂B܂ŌĂ̂ƈ
  Aۂɂ͈̃vOɕ̃Xbh݂邩܂
  BDxXbh쐬ɐݒ肵AŏC邱Ƃ\
  B܂AׂXPW[OASYI邱Ƃ\
  B́AƎ̃XPW[OASYƂ\Ȃł!

  X̗ł́Athread_code() ֐̐擪Ɉȉ3s}邱ƂŁAX
  bh̗Dx1ɐݒ肵AFIFO XPW[OIł܂B

          struct sched_param p;
          p . sched_priority = 1;
          pthread_setschedparam (pthread_self(), SCHED_FIFO, &p);

  6.  vZXԒʐM

  ܂ŌĂvÓAA^CvZXƌĂ΂̂
  BAvP[VvÔׂĂ̕A^CpɏKv
  ͂܂BvO̒łmȎԐv镔
  A^CvZXƂďׂł邱Ƃ܂BȊO
  [UԂŎs悤ɏĂ܂܂B[UԂ̃vZX́A
  ̏ꍇA^CXbh쐬AsAăfobOeՂ
  B̈ŁA[UԂɂ Linux vZXƃA^CX
  bh̊ԂŒʐMsipӂׂłB

  vZXԒʐMsi͂܂BʐMsłL͂ňʓI
  Ȏił郊A^C FIFO ɂċc_܂B

  6.1.  A^C FIFO

  A^C FIFO ́ÃL[ł(First In First Out:o
  )B܂vZX FIFO Ƀf[^ƁAFIFO ̂
  񂪕ʂ̃vZXɓǂ݂܂܂BʏAvZX̕Б
  A^CXbhŁA[UԂ̃vZXɂȂ܂B

  A^C FIFO ́Aۂɂ̓W[io[150̃LN^[foC
  X (/dev/rtf*)łBA^CXbh́Ae FIFO QƂ̂ɐ
  p܂(Ⴆ /dev/rtf2 Ȃ2)B FIFO ̐ɂ͐܂BFIFO
  ֐ɂ́Artf_create(), rtf_destroy(), rtf_get(), rtf_put() Ȃ
  ܂B

  ALinux ̃[UvZX̓A^C FIFO 𕁒ʂ̃LN^[f
  oCXƂ݂Ȃ܂B̂߁Aopen(), close(), read()  write()
  Ƃ֐̃foCXɑ΂ėpł܂B

  6.2.  FIFO 𗘗pAvP[V

  ܂ PC ̃Xs[J[(̉Ȃ)ytȒP C
  vO(t@C pcaudio.c)lĂ݂܂傤Bʂ́A
  炷ɂ̓LN^[foCX /dev/rtf3 ɏނł悢Ƃɂ
  傤(ŁA FIFO (/dev/rtf3)ǂ݂݁A PC ̃Xs[J[ɑM
  郊A^CԃvZXl܂)B

  #include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>
  #include <unistd.h>

  #define DELAY 30000

  void make_tone1(int fd)
  {
          static char buf = 0;
          write (fd, &buf, 1);
  }

  void make_tone2(int fd)
  {
          static char buf = 0xff;
          write (fd, &buf, 1);
  }

  main()
  {
          int i, fd = open ("/dev/rtf3", O_WRONLY);
          while (1)
          {
                  for (i=0;i<DELAY;i++);
                  make_tone1(fd);
                  for (i=0;i<DELAY;i++);
                  make_tone2(fd);
          }
  }

  āAɎvO(pcaudio.c)RpCđ点ƁA`
  gɑKIȉ𐶐͂łB̑O '/dev/rtf3'
  ǂ݂݂sAΉf[^ PC ̃Xs[J[ɑM郂W[
  KvłB̃A^CvÓA rtlinux ̃\[Xc[
  (/usr/src/rtlinux/examples/sound/)Ō܂B'insmod' R}h
  p sound.o W[g݂łB

  foCXǂ݂݂sW[g݂񂾂̂ŁAvOs
  ł悤ɂȂ܂('gcc' ŃRpCAɂĂł
  'a.out' sĂ)BVXeɑ(Ԃ)vZX
  Ȃꍇ́AvZX͂xKIȉ𐶐܂BAʂ̃R
  \[ X T[oNĂƁAȂ܂B܂
  'find' R}h(/usr fBNgɂt@Cɑ΂)s肷
  ƁA͂䂪ł܂܂BȂ̂́AX񃊃A^
  CI FIFO Ƀf[^ł邩łB

  ł́ȀQȂ悤ɁAA^Cɂ̃vZ
  X𑖂点@l܂B܂L̃vOA^CȃvO
  ɕϊ܂(t@C rtaudio.c)B

  #include <rtl.h>
  #include <pthread.h>
  #include <rtl_fifo.h>
  #include <time.h>

  #define FIFO_NO 3
  #define DELAY 30000
  pthread_t thread;

  void * sound_thread(int fd)
  {
          int i;
          static char buf = 0;
          while (1)
          {
                  for(i=0; i<DELAY; i++);
                  buf = 0xff;
                  rtf_put(FIFO_NO, &buf, 1);

                  for(i=0;i<DELAY;i++);
                  buf = 0x0;
                  rtf_put(FIFO_NO, &buf, 1);
          }
          return 0;
  }

  int init_module(void)
  {
          return pthread_create(&thread, NULL, sound_thread, NULL);
  }

  void cleanup_module(void)
  {
          pthread_delete_np(thread);
  }

  ܂sĂȂȂ΁Asound.o W[J[l̒ɁuvOC
  vĂB(Oɉʂ)p Makefile AɎ
  vORpC 'rtaudio.o' W[쐬Ă
  B̃W[g݂ޑOɁAsĂƂ܂B
  L̃vO[v̒邱ƂɒӂĂB܂AX
  bh̃X[v~sR[hȂƁÃXbh͎s~
  ߂܂BȒPɌ΁APC ̃Xs[J[͉炵Â
  sɂ̓Rs[^ċNȂĂ͂ȂȂȂ܂B

  ŁAXbhg̊Ԃɒx悤ɁA(sound_thread() ֐
  )R[hςĂ݂܂傤B
  void * sound_thread(int fd)
  {
          static char buf = 0;
          pthread_make_periodic_np (pthread_self(), gethrtime(), 500000000);

          while (1)
          {
                  pthread_wait_np();
                  buf = (int)buf^0xff;
                  rtf_put(FIFO_NO, &buf, 1);
          }
          return 0;

  }

  x́A'rmmod' R}hpăW[폜邾ŃvZX
  ~܂B

  ܂ŃA^C FIFO vZXԒʐMłǂ̂悤ɗpł邩
  Ă܂B܂ RTLinux {ɕKvł邱ƂAL̗Ⴉ炨
  肢ł傤B

  7.  ɍs

  ̕ɂāARTLinux ɂvO~O̊bɂĈʂ
  ܂Bx{TO𗝉Ă܂΁A͂Őɐiނ͓̂
  ܂B RTLinux ̃\[XƂƂɓł鑼ׂ̂Ă̗
  vO𒲂ׂ邱Ƃł킯łB΁AW[A
  eXgsƂ\ɂȂ͂łBW[̃vO~OɊւ
  񂪂Ɨ~ꍇ́AOri Pomerantz ɂ 'Linux Kernel Module
  Programming Guide' QƂ̂ǂł傤B

  8.  {ɂ

  { Linux Japanese FAQ Project 쐬܂B|Ɋւ邲
   JF vWFNg <JF@linux.or.jp> ܂́Ayomoyomo
  <ymgrtq@ma.neweb.ne.jp> ɘAĂB

  {{ɂāAEL̎wEĉ̕XɊӂ
  (50)B

  o  앐Y <nakano@apm.seikei.ac.jp>

  o  R <tyamagch@bd.mbn.or.jp>

  o  R`V <dica@eurus.dti.ne.jp>

