- From: SA <n0td1scl0s3d_at_ntlworld.com>
- Date: Fri, 2 Sep 2005 09:30:43 +0100
FYI the write and ioctl methods I used in this driver:
As you can see they don't do anything much. The write method appears to have a
much higher overhead that the ioctl and uses copy_from_user instead of an argument
or put_user (which I thought makes the data transfers slower for read / write).
However the read / write methods are much faster than the ioctl()s regardless of the
datasize transferred. I don't know where the additional ioctl overhead comes from
and I found it very surprising that there was such a difference.
SA
static ssize_t dio_write(struct file * file, const char * buf, size_t count, loff_t *ppos){
// this is a test, just read port0
u32 *buff;
int length,i;
if((dio_write_seq&(DIO_PORT_0|DIO_PORT_1|DIO_PORT_2))==0)
return -EINVAL;
if(dio_write_n==0)
return -EINVAL;
buff=file->private_data;
// clip and quantise count
if(count>DIO_BUFF_SIZE)count=DIO_BUFF_SIZE;
length=dio_write_n*(count/(sizeof(u32)*dio_write_n));
if(length==0)
return -EINVAL;
copy_from_user(buff,buf,length*sizeof(u32));
for(i=0;i<length;){
if(dio_write_seq&DIO_PORT_0)writel(buff[i++],dio_base+DIO_IO_PORT_0);
if(dio_write_seq&DIO_DELAY_0)dio_delay();
if(dio_write_seq&DIO_PORT_1)writel(buff[i++],dio_base+DIO_IO_PORT_1);
if(dio_write_seq&DIO_DELAY_1)dio_delay();
if(dio_write_seq&DIO_PORT_2)writel(buff[i++],dio_base+DIO_IO_PORT_2);
if(dio_write_seq&DIO_DELAY_2)dio_delay();
}
length=i*sizeof(u32);
return length;
}
static int dio_ioctl(struct inode * inode,struct file *file, unsigned int cmd, unsigned long arg){
switch(cmd){
...
...
case DIO_WRITE_0:
writel((u32)arg,dio_base+DIO_IO_PORT_0);
break;
case DIO_WRITE_1:
writel((u32)arg,dio_base+DIO_IO_PORT_1);
break;
case DIO_WRITE_2:
writel((u32)arg,dio_base+DIO_IO_PORT_2);
break;
case DIO_READ_0:
return put_user(readl(dio_base+DIO_IO_PORT_0),(u32 __user *)arg);
break;
case DIO_READ_1:
return put_user(readl(dio_base+DIO_IO_PORT_1),(u32 __user *)arg);
break;
case DIO_READ_2:
return put_user(readl(dio_base+DIO_IO_PORT_2),(u32 __user *)arg);
break;
...
...
default:
PRINT_DEBUG("dio: ioctl: Unknown ioctl cmd %x\n",(int)cmd);
return -ENOTTY;
}
return 0;
}
On Friday 02 Sep 2005 08:50, SA wrote:
> On Thursday 01 Sep 2005 15:59, walt wrote:
>
> Fishcamp FPCI-DIO96 PCI card. It is a pretty simple device with a PLX PCI
> bridge that maps three memory addresses onto three 32 bit DIO ports.
> I am not sure the firm is still active though...
>
> > SA,
> >
> > Can you say what HARDWARE you were using when you got 3M to 6M/sec?
> >
> > NI does have some "HS" cards intended for high speed data IO, but I have
> > not tried these.
> >
> > Thanks,
> >
> > Walt
> >
> > On Thursday 01 September 2005 04:29, SA wrote:
> > > Calin,
> > >
> > > I would also like to do this - I have another card supported by comedi
> > > which is similarly restricted in its speed. The message from the list
> > > was "this is how long it takes".
> > >
> > > Outside of comedi I wrote a driver for a different DIO card ages ago
> > > and I was recently converting the driver to kernel 2.6.
> > >
> > > Originally my driver used read / write methods but during the update
> > > and solely motivated by laziness I elected to use ioctl()s instead. At
> > > this point the speed dropped by at least ten fold. I have subsequently
> > > reimplemented the read / write methods and restored the speed.
> > >
> > > With this driver the ioctl() method achieves around 150k read/writes
> > > /second with the read / write methods I got around 3M read/s and 6M
> > > writes/s (memory caching influences the userland<->kernel space
> > > transfers and favours writes). Even doing very small read / writes
> > > (single word) the speed was increase ten fold.
> > >
> > > This really surprised me.
> > >
> > > Furthermore I can achieve hardware limited rates (9Mr/w) if I give up
> > > the userland->kernel transfers and just have the driver hassle the card
> > > (ie if I just want to generate a complex clock signal and program the
> > > kernel driver to do this - obviously if the process is interupted you
> > > get a timing delay / glitch but this doesn't matter to me).
> > >
> > > I do not know if this is directly related to the comedi performance but
> > > I think this means that it is definitely possible to go much faster if
> > > you use read/write instead of ioctl and faster still if you do the work
> > > in kernel space.
> > >
> > > SA
> >
> > _______________________________________________
> > comedi mailing list
> > comedi_at_comedi.org
> > https://cvs.comedi.org/cgi-bin/mailman/listinfo/comedi
>
> _______________________________________________
> comedi mailing list
> comedi_at_comedi.org
> https://cvs.comedi.org/cgi-bin/mailman/listinfo/comedi
Received on 2005-09-02Z07:30:43