David Schleef schrieb:

> It can be duplicated using something similar to the attached
> file.

select() is not bad, but you can't guarantee a stable
period (means a delay is propagated to the following
periods).

For this reason, i prefer pthread_cond_timedwait()
(see file attached).
Suspending can be done by using pthread_cond_wait().

Bernhard
// gcc -Wall -O2 -I/usr/src/rtai/include -D__KERNEL__ -DMODULE -c rt_thread.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <asm/io.h>

#include <rtai.h>
#include <rtai_sched.h>
#include <rtai_pthread.h>

#define PORT 0x378

pthread_t thread_data;

pthread_mutex_t wait_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t wait_cond = PTHREAD_COND_INITIALIZER;

volatile int kill=0;

int position=0;
MODULE_PARM(position,"i");


void add_ns(struct timespec *time,long ns) {
  time->tv_nsec+=ns;
  time->tv_sec  +=  time->tv_nsec/(1000000000LL);
  time->tv_nsec  =  time->tv_nsec%(1000000000LL);
};


void thread_code(int arg) {

  struct timespec time;
  clock_gettime(CLOCK_REALTIME,&time);

  while(!kill) {

    outb(0xff,PORT);
    add_ns(&time,1000000+position);
    pthread_mutex_lock(&wait_mutex);
    pthread_cond_timedwait(&wait_cond,&wait_mutex,&time);
    pthread_mutex_unlock(&wait_mutex);

    outb(0x00,PORT);
    add_ns(&time,19000000-position);
    pthread_mutex_lock(&wait_mutex);
    pthread_cond_timedwait(&wait_cond,&wait_mutex,&time);
    pthread_mutex_unlock(&wait_mutex);

  };

  kill=2;
  pthread_exit(0);

};


int init_module(void) {
  printk("rt_task: started, position=%i\n",position);
  rt_set_oneshot_mode();
  start_rt_timer(0);
  pthread_create(&thread_data,0,(void*)thread_code,0);
  return 0; 
};


void cleanup_module(void) {
  kill=1;
  while(kill!=2);

  pthread_cond_destroy(&wait_cond);
  pthread_mutex_destroy(&wait_mutex);

  stop_rt_timer();
  printk("rt_task: stopped, position=%i\n",position);
};

Reply via email to