Real-Time Signal Analysis & Real-Time Linux: Part 1
by Matt Sherer


Listing One

struct command {
   int signal_hz;
   int noise_hz;
   int sample_hz;
   } ;
static pthread_t signal_gen_t;
static pthread_t sampler_t;
static int sampled_fd;
static int signal_fd;
static int control_to_rtl_fd;
static int control_from_rtl_fd;

int init_module(void) {
   pthread_attr_t attr;
   struct rtl_sigaction sigact_r;
   struct rtl_sigaction sigact_w;

   mkfifo("/pure_signal",0777);
   signal_fd = open("/pure_signal", O_RDWR|O_NONBLOCK);
   ftruncate(signal_fd, sizeof(int)*10);

   mkfifo("/sampled_signal",0777);
   sampled_fd = open("/sampled_signal", O_RDWR|O_NONBLOCK);
   ftruncate(sampled_fd, sizeof(int)*10);

   mkfifo("/control_to_rtl", 0777);
   control_to_rtl_fd = open("/control_to_rtl", O_RDWR|O_NONBLOCK);
   ftruncate(control_to_rtl_fd, sizeof(struct command));
   sigact_r.sa_sigaction = control_to_rtl_handler;
   sigact_r.sa_fd = control_to_rtl_fd;
   sigact_r.sa_flags = RTL_SA_WRONLY|RTL_SA_SIGINFO;
   rtl_sigaction(RTL_SIGPOLL, &sigact_r, NULL);

   mkfifo("/control_from_rtl", 0777);
   control_from_rtl_fd = open("/control_from_rtl", O_RDWR|O_NONBLOCK);
   ftruncate(control_from_rtl_fd, sizeof(struct command));
   sigact_w.sa_sigaction = control_from_rtl_handler;
   sigact_w.sa_fd = control_from_rtl_fd;
   sigact_w.sa_flags = RTL_SA_RDONLY|RTL_SA_SIGINFO;
   rtl_sigaction(RTL_SIGPOLL, &sigact_w, NULL);

   pthread_attr_init(&attr);
   pthread_attr_setfp_np(&attr,1);
   pthread_create(&signal gen_t, &attr, signal_gen, 0);
   pthread_create(&sampler_t, &attr, sampler, 0);
   return 0;


Listing Two

void *signal_gen(void *arg) {
#define THREAD_PERIOD 5000000
#define SAMPLE_FRACTION 1000000000/THREAD_PERIOD
struct timespec next;
   float x1 = 0;
   float x2 = 1.5;
   float incr1;
   float incr2;
   float cur1;
   float cur2;
   int icur;
   clock_gettime(CLOCK_REALTIME, &next);
      while (1) {
         timespec_add_ns(&next, THREAD_PERIOD);
         clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &next, NULL);
         incr1 = 2*PI / (SAMPLE_FRACTION / signal_hz);
         x1 += incr1;
         cur1 = (float)sin(x1);
         incr2 = 2*PI / (SAMPLE_FRACTION / noise_hz);
         x2 += incr2;
         cur2 = (float)sin(x2);
         cur signal = cur1 + (0.5*cur2);
         icur = (int)(cur_signal * 10000);
         icur = htonl(icur);
         write(signal_fd,&icur,sizeof(int));
      }
   return 0;
}


Listing Three

void control_from_rtl_handler(int_sig, rtl_siginfo_t *siginfo, void *v) {
      int_ret;
      struct command com;
      com.signal_hz = htonl(signal_hz);
      com.noise_hz = htonl(noise_hz);
      com.sample_hz = htonl(sample_hz);
      ret = write(siginfo ->rtl_si_fd, &com, sizeof(struct command));
}
static int count = 0;
static unsigned char readdata[sizeof(struct command)];
static char *ptr = readdata;
void control_to_rtl_handler(int_sig, rtl_siginfo_t *siginfo, void *v) {
      int ret;
      struct command com;
      ret = read(siginfo ->rtl_si_fd, ptr, sizeof(unsigned char));
      count += ret;
      ptr += ret;
         if (count >= sizeof(struct command)) {
            memcpy(&com, readdata, sizeof(struct command));
               signal_hz = ntohl(com.signal_hz);
               noise_hz = ntohl(com.noise_hz);
               sample_hz = ntohl(com.sample_hz);
               count = 0; ptr = readdata;
   }
}


Listing Four

void cleanup_module(void) {
   pthread_cancel(signal_gen_t);
   pthread_join(signal_gen_t, NULL);
   pthread_cancel(sampler_t);
   pthread_join(sampler_t, NULL);
   close(signal_fd);
   unlink("/pure_signal");
   close(sampled_fd);
   unlink("/sampled_signal");
   close(control_to_rtl_fd);
   unlink("/control_to_rtl");
   close(control_from_rtl_fd);
   unlink("/control_from_rtl");
}


Listing Five

class SignalCommand {
   private int signal_hz;
   private int noise_hz;
   private int sample_hz;
   private DataInputStream dis;
   private DataOutputStream dos;
   private String write_fifo, read_fifo;
   public SignalCommand(String write_fifo, String read_fifo) {
      this.write fifo = write_fifo;
      this.read fifo = read_fifo;
      try {
         dis = new DataInputStream(
               new FileInputStream(read_fifo));
        dos = new DataOutputStream(
              new FileOutputStream(write_fifo));
      } catch (Exception e) {
               System.out.println("Could not open FIFO: " + e);
      }
   }
   public void setSignalHz(int signal_hz) {
      this.signal_hz = signal_hz;
   }
   public void setNoiseHz(int noise_hz) {
      this.noise_hz = noise_hz;
   }
   public void setSampleHz(int sample_hz) {
      this.sample_hz = sample_hz;
   }
   public int getSignalHz() { return this.signal_hz; }
   public int getNoiseHz() { return this.noise_hz; }
   public int getSampleHz() { return this.sample_hz; }
   public void receiveCommand() {
      try {
        signal_hz = dis.readInt();
        noise_hz = dis.readInt();
        sample_hz = dis.readInt();
      } catch (Exception e) {
         System.out.println("Error reading commands: " + e);
      }
   }
   public void sendCommand() {
      Process proc;
      try {
         dos.writeInt(signal_hz);
         dos.writeInt(noise_hz); 50
         dos.writeInt(sample_hz);
      } catch (Exception e) {
         System.out.println("Error writing commands: " + e);
      }
   }
}


Listing Six

class Reader extends Thread
{
   DataInputStream dis;
   XYSeries series;
   JLabel lab;
   public Reader(String device, XYSeries series, JLabel lab) {
      this.series = series;
      this.lab = lab;
      try {
         dis = new DataInputStream(
               new FileInputStream(device));
      } catch (Exception e) {
         System.out.println("Failed open: " + e);
      }
   }
final static int area_len = 200;
public void run() { int i = 0;
   int count = 0;
   int newval = 0;
   int zerval = 0;
   for (i = 0; i < area_len; i++) {
      series.add(i,0);
   }
   while (true) {
      try {
         i = dis.readInt()/100;
      } catch (Exception e) {
         System.out.println("Failed: " + e);
      }
      try {
         count++;
         newval = count % area_len;
         zerval = newval - (int)(area len * .95);
         if (zerval < 0)
            zerval = area len + zerval;
         series.update(newval, new Integer(i));
         series.update(zerval, new Integer(0));
         lab.setText((new Date()).toString());
     } catch (Exception ee) {
     }
   }
 }
}





