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);
};