next up previous
Next: 宿題 Up: ソフトウェア特論 講義資料 リアルタイムOSとロボットプログラミング Previous: 8 おわり

付録

サンプルプログラムのありかは以下 http://www.jsk.t.u-tokyo.ac.jp/ k-okada/realtime/

include /usr/rtlinux/rtl.mk

CC      = gcc

TARGET  = sound1 sound2 sound_module1 sound_module2 sound_app

all: $(TARGET)

.c.o:
  $(CC) -O2 -c $<

sound1: sound1.o
  $(CC) -O2 -o $@ $^

sound2: sound2.o
  $(CC) -O2 -o $@ $^

sound3: sound3.o
  $(CC) -O2 -o $@ $^

sound_module1: sound_module1.c
  $(CC) ${INCLUDE} ${CFLAGS} -c sound_module1.c \
                             -o sound_module1.o

sound_module2: sound_module2.c
  $(CC) ${INCLUDE} ${CFLAGS} -c sound_module2.c \
                             -o sound_module2.o

sound_app: sound_app.c
  $(CC) ${INCLUDE} ${USER_CFLAGS} -O2 -Wall $^ -o $@

test:
  ./sound1 1c d e2 c d e2 g e d c d e d2

rt-test:
  insmod sound_module1.o
  rmmod sound_module1

xmas:
  ./sound_app 4g2 a8 g e2 e g2 a8 g e2 e \
  5d2 d 4b2 b 5c2 c 4g2 g \
  4a2 a 5c 4b a g2 a8 g e2 e \
  4a2 a 5c 4b a g2 a8 g e2 e \
  5d2 d f2 d8 4b 5c2 c e2 e \
  5c2 4g8 e4 4g2 f8 d4 c2

clean:
  rm -f *.o *~ *.tgz $(TARGET)
/*

  Copyright (C) 2002 Kei Okada <k-okada@jsk.t.u-tokyo.ac.jp>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA  02111-1307, USA.

*/

#define C1 33
#define D1 37
#define E1 41
#define F1 44
#define G1 49
#define A1 55
#define B1 62

#define C2 65
#define D2 73
#define E2 82
#define F2 87
#define G2 98
#define A2 110
#define B2 123

#define C3 131
#define D3 147
#define E3 165
#define F3 175
#define G3 196
#define A3 220
#define B3 257

#define C4 262
#define D4 294
#define E4 330
#define F4 349
#define G4 391
#define A4 440
#define B4 494

#define C5 523
#define D5 587
#define E5 659
#define F5 698
#define G5 784
#define A5 880
#define B5 989

#define C6 1047
#define D6 1185
#define E6 1319
#define F6 1397
#define G6 1568
#define A6 1760
#define B6 1976

int note[42] = {C1,D1,E1,F1,G1,A1,B1, C2,D2,E2,F2,G2,A2,B2,
                C3,D3,E3,F3,G3,A3,B3, C4,D4,E4,F4,G4,A4,B4,
                C5,D5,E5,F5,G5,A5,B5, C6,D6,E6,F6,G6,A6,B6};

/*

  Copyright (C) 2002 Kei Okada <k-okada@jsk.t.u-tokyo.ac.jp>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA  02111-1307, USA.

*/

#include <stdio.h>
#include <sys/io.h>

#include "sound.h"

int play_sound (int hz, int time) { 
                //  hz(Hz), time(msec)
  int tmp, i;

  for (i = 0; i < hz * 2 * time / 1000; ++i) {
    usleep(500*1000/hz);
    tmp = inb(0x61);
    tmp = (i & 1) ? tmp | 0x02 : tmp & ~0x02;
    outb(tmp, 0x61);
  }
  outb((inb(0x61) & ~0x02), 0x61);
}
 
int main(int argc, char *argv[]){
  int i, j;
  int pitch, octave, length;
  struct {
    int note;
    int length;
  } score[100];
  int score_index = 0;

  if (argc <= 1 ) {
    printf("usage: %s <octave:opt><pitch><length:opt>\n", 
           argv[0]);
    printf("excample: %s 4c d e2 c d e2 g e d c d e d2\n", 
            argv[0]);
    exit(1);
  }else{
    octave = 0;
    while (argc > 1 ){
      if ( isdigit(argv[1][0]) ){ 
        octave = *(argv[1]) - '0'; 
        argv[1]++;
      }
      if ( octave > 5 ) octave = 5;
      if ( octave < 0 ) octave = 0;    
    
      pitch = argv[1][0] - 'c';
      if ( pitch < 0) pitch += 7;
      if ( pitch > 6) pitch = 6;
      
      if ( isdigit(argv[1][1]) ){
        length = argv[1][1] - '0';
      }else{
        length = 4;
      }

      printf("octave %d, pitch %d, length %d, note no %3d, 
note Hz %3d\n", octave, pitch, length, octave*7+pitch, 
note[octave*7+pitch]);
      score[score_index].note = note[octave*7+pitch];
      score[score_index].length = length;      
      score_index++;
      argv++;
      argc--;
    }
  }

  if (ioperm(0x61, 1, 1) == -1) {
    perror("ioperm");
    exit(1);
  }

  for (i = 0; i < score_index; i++){
    play_sound(score[i].note, 500*4/score[i].length);
    usleep(10*1000);
  }
  return 0;
}


/*

  Copyright (C) 2002 Kei Okada <k-okada@jsk.t.u-tokyo.ac.jp>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA  02111-1307, USA.

*/

#include <stdio.h>
#include <sys/io.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>

#include "sound.h"

int play_sound (int hz, int time) { 
                //  hz(Hz), time(msec)
  int tmp, i;
  long int d;
  struct timeval tv[2];
  struct timezone tz;
  
  for (i = 0; i < hz * 2 * time / 1000; ++i) {
    gettimeofday(&tv[0], &tz);
    do {
      gettimeofday(&tv[1], &tz);
      d = (tv[1].tv_sec - tv[0].tv_sec)*(1000000) + 
        (tv[1].tv_usec - tv[0].tv_usec);
    } while (d < 500*1000/hz);
    tmp = inb(0x61);
    tmp = (i & 1) ? tmp | 0x02 : tmp & ~0x02;
    outb(tmp, 0x61);
  }
  outb((inb(0x61) & ~0x02), 0x61);
}
 
int main(int argc, char *argv[]){
  int i, j;
  int pitch, octave, length;
  struct {
    int note;
    int length;
  } score[100];
  int score_index = 0;

  if (argc <= 1 ) {
    printf("usage: %s <octave:opt><pitch><length:opt>\n", 
argv[0]);
    printf("excample: %s 4c d e2 c d e2 g e d c d e d2\n", 
argv[0]);
    exit(1);
  }else{
    octave = 0;
    while (argc > 1 ){
      if ( isdigit(argv[1][0]) ){ 
        octave = *(argv[1]) - '0'; 
        argv[1]++;
      }
      if ( octave > 5 ) octave = 5;
      if ( octave < 0 ) octave = 0;    

      pitch = argv[1][0] - 'c';
      if ( pitch < 0) pitch += 7;
      if ( pitch > 6) pitch = 6;
      
      if ( isdigit(argv[1][1]) ){
        length = argv[1][1] - '0';
      }else{
        length = 4;
      }

      printf("octave %d, pitch %d, length %d, note no %3d, 
note Hz %3d\n", octave, pitch, length, octave*7+pitch, 
note[octave*7+pitch]);
      score[score_index].note = note[octave*7+pitch];
      score[score_index].length = length;      
      score_index++;
      argv++;
      argc--;
    }
  }

  if (ioperm(0x61, 1, 1) == -1) {
    perror("ioperm");
    exit(1);
  }

  for (i = 0; i < score_index; i++){
    play_sound(score[i].note, 500*4/score[i].length);
    usleep(10*1000);
  }
  return 0;
}

/*

  Copyright (C) 2002 Kei Okada <k-okada@jsk.t.u-tokyo.ac.jp>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA  02111-1307, USA.

*/

#include <stdio.h>
#include <sys/io.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>

#include "sound.h"

volatile int count = 0;
struct timezone tz;
volatile int i = 0;

void sig_action(){
  int tmp;
  tmp = inb(0x61);
  tmp = (i & 1) ? tmp | 0x02 : tmp & ~0x02;
  outb(tmp, 0x61);
  count = 1;
}

int play_sound (int hz, int time) { 
                //  hz(Hz), time(msec)
  struct sigaction act, oldact;
  struct itimerval value, ovalue;

  for (i = 0; i < hz * 2 * time / 1000; ++i) {

    count = 0;
    act.sa_handler = sig_action;
    act.sa_flags = 0;
    sigaction(SIGALRM, &act, &oldact);
    
    value.it_value.tv_usec = 500*1000/hz;
    value.it_value.tv_sec = 0;
    value.it_interval.tv_usec = 500*100/hz;
    value.it_interval.tv_sec = 0;
    setitimer(ITIMER_REAL, &value, &ovalue);
    //usleep_timer(500*1000/hz);

    while(count == 0);
    setitimer(ITIMER_REAL, &ovalue, &value);
    sigaction(SIGALRM, &oldact, NULL);
  }
  outb((inb(0x61) & ~0x02), 0x61);
}
 

int main(int argc, char *argv[]){
  int i, j;
  int pitch, octave, length;
  struct {
    int note;
    int length;
  } score[100];
  int score_index = 0;

  if (argc <= 1 ) {
    printf("usage: %s <octave:opt><pitch><length:opt>\n", 
argv[0]);
    printf("excample: %s 4c d e2 c d e2 g e d c d e d2\n",
argv[0]);
    exit(1);
  }else{
    octave = 0;
    while (argc > 1 ){
      if ( isdigit(argv[1][0]) ){ 
        octave = *(argv[1]) - '0'; 
        argv[1]++;
      }
      if ( octave > 5 ) octave = 5;
      if ( octave < 0 ) octave = 0;    
    
      pitch = argv[1][0] - 'c';
      if ( pitch < 0) pitch += 7;
      if ( pitch > 6) pitch = 6;
      
      if ( isdigit(argv[1][1]) ){
        length = argv[1][1] - '0';
      }else{
        length = 4;
      }

      printf("octave %d, pitch %d, length %d, note no %3d, 
note Hz %3d\n",octave, pitch, length, octave*7+pitch, 
note[octave*7+pitch]);
      score[score_index].note = note[octave*7+pitch];
      score[score_index].length = length;      
      score_index++;
      argv++;
      argc--;
    }
  }

  if (ioperm(0x61, 1, 1) == -1) {
    perror("ioperm");
    exit(1);
  }

  for (i = 0; i < score_index; i++){
    play_sound(score[i].note, 500*4/score[i].length);
    usleep(10*1000);
  }
  return 0;
}


/*

  Copyright (C) 2002 Kei Okada <k-okada@jsk.t.u-tokyo.ac.jp>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA  02111-1307, USA.

*/

#include <linux/errno.h>
#include <rtl.h>
#include <time.h>

#include <rtl_sched.h>
#include <rtl_fifo.h>

#include <sys/io.h>
#include "sound.h"

pthread_t task;

void play_sound (int hz, int time) { // hz(Hz), time(msec)
  int i, wait, ret, tmp;

  wait = 500*1000/hz;

  rtl_printf("play_sound wait %d, times %d = %d\n", wait, 
         hz * 2 * time / 1000, hz * 2 * time / 1000*wait);
  pthread_make_periodic_np(pthread_self(), 
                           gethrtime(), wait*1000);
    
  for (i = 0; i < hz * 2 * time / 1000; ++i) {
    ret = pthread_wait_np();
    tmp = rtl_inb(0x61);
    tmp = (i & 1) ? tmp | 0x02 : tmp & ~0x02;
    rtl_outb(tmp, 0x61);
  }
  rtl_outb((inb(0x61) & ~0x02), 0x61);
}

#define set_score(octave, pitch, len) \
    score[score_index].note = note[octave*7+pitch]; \
    score[score_index].length = len; \
    score_index++;

void *thread_code(void *t)
{
  int i;
  struct {
    int note;
    int length;
  } score[100];
  int score_index = 0;

  set_score(4, 0, 4);
  set_score(4, 1, 4);
  set_score(4, 2, 2);
  
  set_score(4, 0, 4);
  set_score(4, 1, 4);
  set_score(4, 2, 2);    

  set_score(4, 4, 4);
  set_score(4, 2, 4);
  set_score(4, 1, 4);
  set_score(4, 0, 4);
  set_score(4, 1, 4);
  set_score(4, 2, 4);
  set_score(4, 1, 2);          
  
  for (i = 0; i < score_index; i++){
    play_sound(score[i].note, 500*4/score[i].length);
  }

  rtl_printf("done play_sound()\n");
  return 0;
}

int init_module(void)
{
  pthread_attr_t attr;
  struct sched_param sched_param;
  int ret;

  pthread_attr_init (&attr);
  sched_param.sched_priority = 4;
  pthread_attr_setschedparam (&attr, &sched_param);
  ret = pthread_create (&task,  &attr, thread_code, NULL);

  return 0;
}


void cleanup_module(void)
{
  pthread_cancel (task);
  pthread_join (task, NULL);
}


/*

  Copyright (C) 2002 Kei Okada <k-okada@jsk.t.u-tokyo.ac.jp>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA  02111-1307, USA.

*/

#include <linux/errno.h>
#include <rtl.h>
#include <time.h>

#include <rtl_sched.h>
#include <rtl_fifo.h>

#include <sys/io.h>
#include "sound.h"

pthread_t task;

void play_sound (int hz, int time) { // hz(Hz), time(msec)
  int i, wait, ret, tmp;

  wait = 500*1000/hz;

  rtl_printf("play_sound wait %d, times %d = %d\n", wait, 
         hz * 2 * time / 1000, hz * 2 * time / 1000*wait);
  pthread_make_periodic_np(pthread_self(), 
                           gethrtime(), 
                           wait*1000);
    
  for (i = 0; i < hz * 2 * time / 1000; ++i) {
    ret = pthread_wait_np();
    tmp = rtl_inb(0x61);
    tmp = (i & 1) ? tmp | 0x02 : tmp & ~0x02;
    rtl_outb(tmp, 0x61);
  }
  rtl_outb((inb(0x61) & ~0x02), 0x61);
}

typedef struct {
  int note;
  int length;
} struct_score;
struct_score score[100];

void *thread_code(void *t)
{
  int i;

  while (1){
    rtl_printf("play_sound : waiting...\n");
    pthread_suspend_np(pthread_self());
    for (i = 0; i < 100; i++){
      if (score[i].length == 0 ) break;
      rtl_printf("play_sound : %d %d\n", score[i].note, s
                  core[i].length);
      play_sound(score[i].note, 500*4/score[i].length);
    }
  }

  rtl_printf("play_sound : done\n");
  return 0;
}

int my_handler(unsigned int fifo){
  int err, size;
    
  size = sizeof(struct_score)*100;
  
  rtl_printf("FIFO handler: waiting for score...\n");
  
  while ((err = rtf_get(1, &score, size)) == size){
    rtl_printf("FIFO handler: receiveing the score\n");

    pthread_wakeup_np (task);
  }

  rtl_printf("FIFO handler: done\n");
  
  if (err != 0) {
    return -EINVAL;
  }
  return 0;
}

int init_module(void)
{
  pthread_attr_t attr;
  struct sched_param sched_param;
  int ret;
  int c[5];

  rtf_destroy(1);
  c[0] = rtf_create(1, 4000);
  rtf_create_handler(1, &my_handler); 

  pthread_attr_init (&attr);
  sched_param.sched_priority = 4;
  pthread_attr_setschedparam (&attr, &sched_param);
  ret = pthread_create (&task,  &attr, thread_code, NULL);

  return 0;
}


void cleanup_module(void)
{
  rtf_destroy(1);
  
  pthread_cancel (task);
  pthread_join (task, NULL);
}
#include <stdio.h>
#include <sys/io.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include <rtl_fifo.h>
#include <rtl_time.h>

#include "sound.h"

int main(int argc, char *argv[]){
  int pitch, octave, length;
  struct {
    int note;
    int length;
  } score[100];
  int score_index = 0;
  int fd;

  if (argc <= 1 ) {
    printf("usage: %s <octave:opt><pitch><length:opt>\n", 
argv[0]);
    printf("excample: %s 4c d e2 c d e2 g e d c d e d2\n",
argv[0]);
    exit(1);
  }else{
    octave = 0;
    while (argc > 1 ){
      if ( isdigit(argv[1][0]) ){ 
        octave = *(argv[1]) - '0'; 
        argv[1]++;
      }
      if ( octave > 5 ) octave = 5;
      if ( octave < 0 ) octave = 0;    
    
      pitch = argv[1][0] - 'c';
      if ( pitch < 0) pitch += 7;
      if ( pitch > 6) pitch = 6;
      
      if ( isdigit(argv[1][1]) ){
        length = argv[1][1] - '0';
      }else{
        length = 4;
      }

      printf("octave %d, pitch %d, length %d, note no %3d, 
note Hz %3d\n", octave, pitch, length, octave*7+pitch,
note[octave*7+pitch]);
      score[score_index].note = note[octave*7+pitch];
      score[score_index].length = length;      
      score_index++;
      argv++;
      argc--;
    }
  }

  score[score_index].length = 0;  

  if ((fd = open("/dev/rtf1", O_WRONLY)) < 0) {
    fprintf(stderr, "Error opening /dev/rtf1\n");
    exit(1);
  }

  if (write(fd, &score, sizeof(score)) < 0 ) {
    fprintf(stderr, "Can't send a command to RT-task\n");
    exit(1);
  }

  return 0;
}


generated through LaTeX2HTML. M.Inaba 平成18年5月6日