comedilib/testing/cmd_3.c
Ian Abbott 67a364cf93 comedi_test: attempt to change read and write subdevice during test
When testing streaming input (or streaming output) command functionality
for a subdevice, attempt to make it the current 'read' (or 'write')
subdevice by calling the new 'comedi_set_read_subdevice()' (or
'comedi_set_write_subdevice()') function.

That is currently only supported by the Linux "in-tree" version of
Comedi, since kernel version 3.19.  If the attempt fails, and the
subdevice is not the current 'read' (or 'write') subdevice, the test
will report "not applicable" as before.
2016-05-13 11:48:31 +01:00

130 lines
2.4 KiB
C

#include <stdio.h>
#include <comedilib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <getopt.h>
#include <ctype.h>
#include <math.h>
#include <sys/time.h>
#include <string.h>
#include "comedi_test.h"
static int do_continuous(int multiplier);
#define BUFSZ 10000
int test_cmd_continuous(void)
{
int mult;
unsigned int flags = comedi_get_subdevice_flags(device,subdevice);
/* attempt to make subdevice the current 'read' subdevice */
if(flags&SDF_CMD_READ) comedi_set_read_subdevice(device,subdevice);
if(!(flags&SDF_CMD) || (comedi_get_read_subdevice(device)!=subdevice)){
printf("not applicable\n");
return 0;
}
/* as if doing _one_ infinite loop wasn't slow enough,
* we loop through with higher and higher multipliers,
* in case the test fails because of latency problems */
for(mult=1;mult<1024;mult*=2){
do_continuous(mult);
}
return 0;
}
static int do_continuous(int multiplier)
{
comedi_cmd cmd;
char buf[BUFSZ];
unsigned int chanlist[1];
int go;
int total=0;
int ret;
int chunks=0;
unsigned long total_secs = 0;
struct timeval tv,start_tv;
if(comedi_get_cmd_generic_timed(device,subdevice, &cmd, 1, 1)<0){
printf(" not supported\n");
return 0;
}
if(realtime)cmd.flags |= TRIG_RT;
cmd.chanlist = chanlist;
cmd.scan_end_arg = 1;
cmd.stop_src = TRIG_NONE;
cmd.stop_arg = 0;
cmd.chanlist_len = 1;
chanlist[0] = CR_PACK(0,0,0);
// slow down a bit
cmd.scan_begin_arg *= multiplier;
printf("multiplier=%d, scan_begin_arg=%d\n",
multiplier,
cmd.scan_begin_arg);
ret=comedi_command(device,&cmd);
if(ret<0){
perror("comedi_command");
}else{
printf("ret==%d\n",ret);
}
gettimeofday(&start_tv,NULL);
go=1;
while(go){
ret = read(comedi_fileno(device),buf,BUFSZ);
if(ret<0){
if(errno==EAGAIN){
usleep(10000);
}else{
go = 0;
perror("read");
}
}else if(ret==0){
go = 0;
}else{
total += ret;
chunks++;
gettimeofday(&tv,NULL);
tv.tv_sec-=start_tv.tv_sec;
tv.tv_usec-=start_tv.tv_usec;
if(tv.tv_usec<0){
tv.tv_usec+=1000000;
tv.tv_sec--;
}
if(tv.tv_sec>total_secs){
double t;
t=tv.tv_sec+1e-6*tv.tv_usec;
printf("%0.3f %d (%g) %d (%g)\n",
t,
chunks,chunks/t,
total,total/t);
total_secs++;
}
}
}
{
double t;
t=tv.tv_sec+1e-6*tv.tv_usec;
printf("end: %0.3f %d (%g) %d (%g)\n",
t,
chunks,chunks/t,
total,total/t);
}
return 0;
}