daniel
You dont really have to worry.
It is all done in the scheduler.

If you want to do some variable task timong you can always follow this
example

look in init_module

int init_module(void) {
  rtf_create(1,4000);
  rtf_create_handler(1,&rtf_handler);

  // start real time tasks
  rt_set_oneshot_mode();
  rt_task_init(&servo_task,periodic_servo_task,1,3000,1,0,0);
  rt_set_runnable_on_cpus(&servo_task,0x01);
  start_rt_timer(nano2count(1E7));

  // the task will run but must set its own period...
  rt_task_resume(&servo_task);

  printk(" servo task set up\n");
  return 0;

};


and in the task

void periodic_servo_task(int t) {
  for (;;) {
    int servo;
    for ( servo=0;servo<NUM_SERVOS; servo++) {
      outb(servo_data[servo].mask1,PORT);
      outb(servo_data[servo].mask2,PORT+2);
      /* possibly a macro for this is needed */
      //servo_task.period=servo_data[servo].len;
      // here we set the next period cool huh !!
      rt_sleep(nano2count(servo_data[servo].len));
    };
  };

Hope this helps
   Phil



/* rtai_servo.c orig from Berhard Kuhn  */

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

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

#define NUM_SERVOS 12

#define ONE_MS 1000000

struct servodata {
  RTIME len;
  const unsigned char mask1,mask2;

};

#define PORT 0x378

RT_TASK servo_task;

struct servodata servo_data[NUM_SERVOS]= {
  {ONE_MS,0x80,0x0b },  {ONE_MS,0x40,0x0b },
  {ONE_MS,0x20,0x0b },  {ONE_MS,0x10,0x0b },
  {ONE_MS,0x08,0x0b },  {ONE_MS,0x00,0x03 },
  {ONE_MS,0x04,0x0b },  {ONE_MS,0x00,0x0f },
  {ONE_MS,0x02,0x0b },  {ONE_MS,0x01,0x0b },
  {ONE_MS,0x00,0x0a },  {ONE_MS,0x00,0x09 },
};

void periodic_servo_task(int t) {
  for (;;) {
    int servo;
    for ( servo=0;servo<NUM_SERVOS; servo++) {
      outb(servo_data[servo].mask1,PORT);
      outb(servo_data[servo].mask2,PORT+2);
      /* possibly a macro for this is needed */
      //servo_task.period=servo_data[servo].len;
      rt_sleep(nano2count(servo_data[servo].len));
    };
  };
  
};

static int fifomescnt = 0;

/* rtfifo handler */
int rtf_handler( unsigned int fifo ) {
  struct { unsigned char channel,data;} msg;
  int err;

  while(err=(rtf_get(1,&msg,sizeof(msg))==sizeof(msg))) {
    fifomescnt++;
    if(msg.channel>=NUM_SERVOS) return -EINVAL;
    servo_data[msg.channel].len=ONE_MS+((ONE_MS*msg.data)>>8);
  };
  if(err) return -EINVAL;
  return 0;
};

int init_module(void) {
  rtf_create(1,4000);
  rtf_create_handler(1,&rtf_handler);
  // start real time tasks 
  rt_set_oneshot_mode();
  rt_task_init(&servo_task,periodic_servo_task,1,3000,1,0,0);
  rt_set_runnable_on_cpus(&servo_task,0x01);
  start_rt_timer(nano2count(1E7));
  rt_task_resume(&servo_task);
//  rt_task_make_periodic(&servo_task,rt_get_time(),50*ONE_MS);
  printk(" servo task set up\n");
  return 0;

};

void cleanup_module(void){
  stop_rt_timer();

  rt_task_delete(&servo_task);
  rtf_destroy(1);

  outb(0x00,PORT);
  outb(0x0b,PORT+2);
  printk(" servo task cleaned up %d messages\n",fifomescnt);

};

Reply via email to