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