- From: Dominic <I-C-H_at_gmx.de>
- Date: Thu, 22 Aug 2002 22:12:35 +0200
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