Q: comedi_callback performance :-(

I have managed to get comedi's callback mechanism running on rt-linux.
After switching to comedi-cvs.

But there are some performance issues:

Currently even the rt-scheduler is better in regard to jitter and
sampling-rate.

(1) I do use comedi_data_read (6-7uS) in the callback.
     I assume that's not the way it's supposed to be.
     But I cannot find any examples which do read data with kcomedilib.
     cmd.data does not contain anything when the callback is invoked :-(
     Is it even used? Recent examples do not even use it.
     I even tried letting comedi assigning values to it, but did not
     change anything...
(2) I invoke comedi_command&comedi_callback everytime the callback is
     called. But things like stop.arg=TRIG_NONE simply crash the system.

Ciao,
  Dominic



/*
  * Dominic Hillenbrand August 2002
  * Universität Kaiserslautern
  *
  */

#include <rtl.h>
#include <rtl_time.h>
#include <rtl_fifo.h>
#include <time.h>
#include <rtl_sched.h>
#include <rtl_sync.h>
#include <pthread.h>
#include <unistd.h>
#include <rtl_debug.h>
#include <rtl_mutex.h>
#include <errno.h>


#include <linux/comedi.h>
#include <linux/comedilib.h>
#include <linux/comedidev.h>

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/types.h>
#include <asm/io.h>

//#define DHX_ENTER rtl_printf("enter %s\n", __PRETTY_FUNCTION__);
//#define DHX_LEAVE rtl_printf("leave %s\n", __PRETTY_FUNCTION__);
#define DHX_ENTER
#define DHX_LEAVE

#define DHX_DEBUG(cmd) cmd

#define DHX_KHZ_TO_NANO(khz) (1.0/khz*1000000)
#define DHX_KHZ_SEC_TO_TICKS(s) (s*DHX_KHZ*1000)

//#define DHX_VALUE (1.0/40*1000000)
//#define DHX_KHZ 1
//#define DHX_MESS 1


#define BUFSIZE  512

comedi_cmd cmd;
comedi_t *dev;
int subd=0;
int subdevice_ao=0;

sampl_t data[BUFSIZE];

unsigned int  dhx_time_max=0;
unsigned int  dhx_time_min=999999999;
unsigned int  dhx_time_delta;
unsigned int  dhx_time_5=0;

hrtime_t dhx_time_1;
hrtime_t dhx_time_2;
	

int test=0;
int first=0;



int callback(unsigned int i,void *arg);

int do_cmd(void)
{
	int ret;

	
	unsigned int chanlist[1];

	cmd.subdev = subd;
	cmd.flags = 0;

	cmd.start_src = TRIG_NOW;
	cmd.start_arg = 0;

	cmd.scan_begin_src = TRIG_TIMER;
	cmd.scan_begin_arg = DHX_VALUE;

	cmd.convert_src = TRIG_TIMER;
	cmd.convert_arg = DHX_VALUE;

	cmd.scan_end_src = TRIG_COUNT;
	cmd.scan_end_arg = 1;

	cmd.stop_src = TRIG_COUNT; //TRIG_COUNT
	cmd.stop_arg = 100;    //100

	cmd.chanlist = chanlist;
	cmd.chanlist_len = 1;

	chanlist[0] = CR_PACK(0,0,0);

	cmd.data=data;
	cmd.data_len=BUFSIZE*sizeof(sampl_t);

	ret = comedi_command_test(dev,&cmd);
	//printk("command test returned %d\n",ret);

	cmd.chanlist = chanlist;
	cmd.chanlist_len = 1;
	cmd.data=data;
	cmd.data_len=BUFSIZE*sizeof(sampl_t);

	ret = comedi_command_test(dev,&cmd);
	//printk("command test returned %d\n",ret);
	if(ret)return ret;

	cmd.chanlist = chanlist;
	cmd.chanlist_len = 1;
	//cmd.data=data;
	//cmd.data_len=BUFSIZE*sizeof(sampl_t);
	
	
	comedi_register_callback(dev,subd,COMEDI_CB_EOS,callback,NULL);

	ret = comedi_command(dev,&cmd);

	return ret;
}






int callback(unsigned int i,void *arg)
{
	lsampl_t v;
	
	//rtl_stop_interrupts();

	
	dhx_time_1 = gethrtime();
	dhx_time_delta = (unsigned int ) (dhx_time_1 - dhx_time_2);
	dhx_time_2 = dhx_time_1;
		
	if (first<DHX_KHZ_SEC_TO_TICKS(1)) {
		 first++;
		 goto leave;
	}
		
     if (first<DHX_KHZ_SEC_TO_TICKS(6)) {
	   if (dhx_time_delta > dhx_time_max) dhx_time_max=dhx_time_delta;
	   if (dhx_time_delta < dhx_time_min) dhx_time_min=dhx_time_delta;
				
	    dhx_time_delta=abs(dhx_time_delta);
	    if 
(abs(dhx_time_delta-DHX_KHZ_TO_NANO(DHX_KHZ))>DHX_KHZ_TO_NANO(DHX_KHZ)*0.2) 
{
		 
	   dhx_time_5++;
	    }
			
	    first++;
	    test++;


     }
	
	comedi_data_read(dev,subd,0,0,AREF_GROUND,&v);
     comedi_data_write(dev,subdevice_ao,0,0,AREF_GROUND, v>>4);
	
leave:
	//rtl_allow_interrupts();
	do_cmd();
	return 0;
}

int init_module(void)
{
	
	int ret;
	
	//printk("Comedi real-time example #1\n");

	dev = comedi_open("/dev/comedi0");
	//printk("comedi_open: %d\n", (int)dev);

	ret = comedi_lock(dev,subd);
	//printk("comedi_lock: %d\n",ret);
	
	subdevice_ao=comedi_find_subdevice_by_type(dev,COMEDI_SUBD_AO,0);
	//rtl_printf("subdevice_ao=%d\n", subdevice_ao);
	
	do_cmd();
	
	return 0;
	
}


void cleanup_module(void)
{
	int ret;

	ret = comedi_cancel(dev,subd);
	//printk("comedi_cancel: %d\n",ret);

	ret = comedi_unlock(dev,subd);
	//printk("comedi_unlock: %d\n",ret);

	comedi_close(dev);
	//printk("comedi_close:\n");
	//printk("counter %d\n", counter);

	rtl_printf("%d,%d,%d,%d,%d\n", DHX_KHZ, dhx_time_max, dhx_time_min, 
dhx_time_5,5*DHX_KHZ*1000);
	rtl_printf("%d %d\n", test,first);

	
     	
}

Received on 2002-08-22Z19:12:35