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

Reply via email to