Hi karl
I solwed the problem. It does work and can put task to be suspended for a
while
test the attached code.
I have tried to make the waiting with a wait_quque_head_t, but that did not
work out.
I gees that the thread it preemtet and leves the system in a undefiined
state while trying to start new task.
What happend is -> it worked out fine until i tried to open fx netscape.
Anders Gnistrup
ps. If you have a better solution I whould like to know.
karl rentsch wrote:
> Hi all,
>
> I've got a problem I hope someone can help me with. I'm trying to put a
> thread to sleep but I don't want to tie up the system using usleep() or
> nanosleep(). I've tried using pthread_make_periodic_np configured as a
> one shot timer (ie. it needs to repeat several times but for different
> time intervals) but it doesn't seem to work
> Any help would be much appreciated
> Thanks
> Karl Rentsch
>
> -- [rtl] ---
> To unsubscribe:
> echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
> echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
> --
> For more information on Real-Time Linux see:
> http://www.rtlinux.org/rtlinux/
#include <linux/errno.h>
#include <rtl.h>
#include <time.h>
#include <rtl_time.h>
#include <rtl_sched.h>
#include <rtl_fifo.h>
#include <semaphore.h>
#include <rtl_posixio.h>
#include <unistd.h>
/*
* definition af read/write fifos til rt_serial
*-------------------------------------------------*/
#define COM_CNT 2
#define RS485 0
#define RS232 1
#define READ_RS485 2
#define WRITE_RS485 0
#define READ_RS232 3
#define WRITE_RS232 1
/*
* handler funktions
*------------------*/
static int handler_rs485(unsigned int fifo);
static int handler_rs232(unsigned int fifo);
struct rt_com_struct {
char *devname;
int read_fifo; /* seen from userspace */
int write_fifo; /* seen from userscape */
int (*handler) (unsigned int); /* handler for read_fifo */
sem_t sem_read;
sem_t sem_write;
int fd;
};
static struct rt_com_struct rt_com_table[COM_CNT] =
{
{"/dev/ttyS0",READ_RS485, WRITE_RS485, handler_rs485},
{"/dev/ttyS1",READ_RS232, WRITE_RS232, handler_rs232},
};
/*
* funktions
*-----------*/
pthread_t timer_create_ID;
static void *timer_create(void *t);
static inline void timer_wait( int );
struct wait_timer_struct {
sem_t sem_timer;
int timer_counter;
} wait_timer;
/*
* program
*----------------*/
static int handler_rs485(unsigned int fifo) {
struct rt_com_struct *p=&(rt_com_table[RS485]);
int error,i;
char buf[10], bufmes[10] = "hej linux\n";
char mes[4] = {1,0x21};
rtl_printf("TEST : handler_rs485\n");
/* get message */
i=0;
while ( ((error = rtf_get(p->write_fifo, &buf[i],1)) == 1) && i++<10);
rtl_printf("TEST %s\n",buf);
if( rtf_put(p->read_fifo, bufmes, sizeof(bufmes))<0 ) {
rtl_printf("TEST : error writing to read_fifo\n");
}
/* trying to write to smr */
write(p->fd,mes,2);
timer_wait(7);
read(p->fd,mes,4);
rtl_printf("TEST : %x %x %x %d\n",mes[0],mes[1],mes[2],mes[3]);
return 0;
}
static int handler_rs232(unsigned int fifo) {
struct rt_com_struct *p=&(rt_com_table[RS232]);
int error,i;
char buf[10], bufmes[10] = "hej linux\n";
i=0;
rtl_printf("TEST : handler_rs232\n");
/* get message */
while ( ((error = rtf_get(p->write_fifo, &buf[i],1)) == 1) && i++<10);
rtl_printf("TEST %s\n",buf);
if( rtf_put(p->read_fifo, bufmes, sizeof(bufmes)) < 0 ) {
rtl_printf("TEST : error writing to read_fifo\n");
}
return 0;
}
/*
* timer finktion
*-------------------------*/
static void *timer_create(void *t) {
struct wait_timer_struct *p = &wait_timer;
int timer_counter;
sem_init(&(p->sem_timer),0,0);
p->timer_counter = 0;
while(1) {
pthread_wait_np();
timer_counter = p->timer_counter;
while(timer_counter>0) {
sem_post(&p->sem_timer);
timer_counter--;
}
}
return 0;
}
static inline void timer_wait(int nr_chars) {
struct wait_timer_struct *p = &wait_timer;
p->timer_counter++;
while(nr_chars-->=0) {
sem_wait(&p->sem_timer);
}
p->timer_counter--;
}
/*
* init etc
*----------------*/
int init_module(void) {
int i;
struct rt_com_struct *p;
pthread_attr_t attr;
struct sched_param sched_param;
hrtime_t period = (hrtime_t) 1000000000/ 11520;
for(i=0;i<COM_CNT; i++) {
p=&rt_com_table[i];
p->fd = open(p->devname,O_RDWR);
rtf_destroy(p->read_fifo);
rtf_destroy(p->write_fifo);
rtf_create(p->read_fifo,256);
rtf_create(p->write_fifo,256);
rtf_make_user_pair(p->write_fifo,p->read_fifo); /* makes fifo bidirectional in
user space */
rtf_create_handler(p->write_fifo, p->handler);
}
/* create task for queue waiting */
pthread_attr_init(&attr);
sched_param.sched_priority = 4;
pthread_attr_setschedparam(&attr,&sched_param);
pthread_create(&timer_create_ID,&attr, timer_create, (void *) 11520 /* HZ */);
pthread_make_periodic_np(timer_create_ID, gethrtime(), period);
return 0;
}
void cleanup_module(void) {
int i;
struct rt_com_struct *p;
for(i=0;i<COM_CNT; i++) {
p=&rt_com_table[i];
rtf_destroy(p->read_fifo);
rtf_destroy(p->write_fifo);
close(p->fd);
}
pthread_suspend_np(timer_create_ID);
pthread_cancel(timer_create_ID);
pthread_join(timer_create_ID, NULL);
}