From 65063d785ea505d8d7903c5a0242b026a31efccc Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 23 Nov 2015 16:04:11 +0000 Subject: [PATCH] demo/mmap: support integer wraparound and large sample size Currently, the 'front' and 'back' variables are of type 'int' (signed 32-bit integers). The loop will break when 'front < back', which will happen when more than 'INT_MAX' bytes of data have been produced. Redefine them as 'unsigned int' and also allow 'front < back' which will happen when more than 'UINT_MAX' bytes of data have been produced. Because the buffer size is not necessarily a power of 2, we can no longer just use '(back + i) % size' to get the buffer position corresponding to 'back + i', so introduce a new variable 'bufpos' to keep track of the buffer position. Also allow for subdevices that set the 'SDF_LSAMPL' flag to indicate they use the large (32-bit, 'lsampl_t') sample type instead of the small (16-bit, 'sampl_t') sample type. Also, rename the buffer size variable 'size' to 'bufsize'. --- demo/mmap.c | 58 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/demo/mmap.c b/demo/mmap.c index 55bf58d..46042c5 100644 --- a/demo/mmap.c +++ b/demo/mmap.c @@ -38,10 +38,15 @@ int main(int argc, char *argv[]) { comedi_t *dev; comedi_cmd c,*cmd=&c; - int size; - int front, back; + unsigned int bufsize; + unsigned int front, back; int ret; - int i; + unsigned int i; + unsigned int bufpos; + unsigned int subdev_flags; + unsigned int sample_size; + unsigned int nsamples; + unsigned int col; struct parsed_options options; init_parsed_options(&options); @@ -53,10 +58,23 @@ int main(int argc, char *argv[]) exit(1); } - size = comedi_get_buffer_size(dev, options.subdevice); - fprintf(stderr,"buffer size is %d\n", size); + ret = comedi_get_buffer_size(dev, options.subdevice); + if(ret < 0){ + comedi_perror("comedi_get_buffer_size"); + exit(1); + } + bufsize = ret; + fprintf(stderr,"buffer size is %u\n", bufsize); + ret = comedi_get_subdevice_flags(dev, options.subdevice); + if(ret < 0){ + comedi_perror("comedi_get_subdevice_flags"); + } + subdev_flags = ret; + sample_size = (subdev_flags & SDF_LSAMPL) + ? sizeof(lsampl_t) : sizeof(sampl_t); + fprintf(stderr,"sample size is %u\n", sample_size); - map = mmap(NULL,size,PROT_READ,MAP_SHARED, comedi_fileno(dev), 0); + map = mmap(NULL,bufsize,PROT_READ,MAP_SHARED, comedi_fileno(dev), 0); fprintf(stderr, "map=%p\n", map); if( map == MAP_FAILED ){ perror( "mmap" ); @@ -89,24 +107,40 @@ int main(int argc, char *argv[]) front = 0; back = 0; + bufpos = 0; + col = 0; while(1){ - front += comedi_get_buffer_contents(dev, options.subdevice); - if(options.verbose) fprintf(stderr, "front = %d, back = %d\n", front, back); - if(front < back) break; + ret = comedi_get_buffer_contents(dev, options.subdevice); + if(ret < 0){ + comedi_perror("comedi_get_buffer_contents"); + break; + } + front += ret; + nsamples = (front - back) / sample_size; + front = back + nsamples * sample_size; + if(options.verbose) fprintf(stderr, "front = %u, back = %u, samples = %u\n", front, back, nsamples); if(front == back){ //comedi_poll(dev, options.subdevice); usleep(10000); continue; } + for(i = 0; i < nsamples; i++){ + unsigned int sample; - for(i = back; i < front; i += sizeof(sampl_t)){ - static int col = 0; - printf("%d ",*(sampl_t *)(map + (i % size))); + if(sample_size == sizeof(sampl_t)) + sample = *(sampl_t *)((char *)map + bufpos); + else + sample = *(lsampl_t *)((char *)map + bufpos); + printf("%u ", sample); col++; if(col == options.n_chan){ printf("\n"); col = 0; } + bufpos += sample_size; + if(bufpos >= bufsize){ + bufpos = 0; + } } ret = comedi_mark_buffer_read(dev, options.subdevice, front - back);