simple_putdata.c

Go to the documentation of this file.
00001 
00035 #include "edtinc.h"
00036 
00037 #include <string.h>
00038 #include <stdlib.h>
00039 #ifndef _NT_
00040 #include <unistd.h>
00041 #endif
00042 
00043 #define NUMBUFS 4   /* Four is the optimal number of buffers for EDT boards */
00044 int numbufs = NUMBUFS ;
00045 int buffers_inuse ;
00046 
00047 
00048 void
00049 usage(char *err)
00050 {
00051     puts(err);
00052     puts("usage: putdata") ;
00053     puts("\t-u <unit>      - unit number") ;
00054     puts("\t-c <channel>   - channel number") ;
00055     puts("\t-n <num>       - set number of ring buffers") ;
00056     puts("\t-b             - set byteswap on") ;
00057     puts("\t-s <size>      - specifies buffer size in bytes") ;
00058     puts("\t-k <size>      - specifies buffer size in kbytes") ;
00059     puts("\t-l <loops>     - specifies number of loops") ;
00060     puts("\t-i <infile>    - specifies input filename (\"-i -\" uses stdandard input");
00061     puts("\t-h             - prints this message") ;
00062 
00063     exit(1);
00064 }
00065 
00066 void init_buf(u_char *buf, int size) ;
00067 
00068 int
00069 main(int argc, char **argv)
00070 {
00071     EdtDev *edt_p ;
00072     int unit ;
00073     int loop ;
00074         int loopcount ;
00075         int byteswap=0;
00076         double dtime ;
00077     unsigned int size ;
00078     u_char *buf ;
00079     char *infile ;
00080     int ifd = -1 ;
00081         int lstcnt ;
00082         int curcnt ;
00083         int timeouts ;
00084         int channel = 0;
00085         int fill;
00086         int done = 0;
00087         int total_buffers = 0;
00088         double num_bytes;
00089     /* 
00090      * set defaults 
00091      */
00092     unit = 0 ;
00093     infile = NULL ;
00094     /* default to 100 writes of 1 Megabyte */
00095     size = 1024*1024 ;
00096     loopcount = 100 ;
00097     timeouts = 0 ;
00098 
00099     --argc;
00100     ++argv;
00101     while (argc && argv[0][0] == '-')
00102     {
00103                 switch (argv[0][1])
00104                 {
00105                 case 'u':
00106                         ++argv;
00107                         --argc;
00108                         if (argc < 1) 
00109             {
00110                         usage("Error: option 'u' requires a numeric argument\n");
00111                 }
00112                 if ((argv[0][0] >= '0') && (argv[0][0] <= '9'))
00113             {
00114                 unit = atoi(argv[0]);
00115             }
00116             else 
00117             {
00118                         usage("Error: option 'u' requires a numeric argument\n");
00119                 }
00120                 break;
00121 
00122                 case 'b':
00123                         byteswap = 1;
00124                         break ;
00125                 case 's':
00126                         ++argv;
00127                         --argc;
00128                         size = strtol(argv[0],0,0);
00129                         break ;
00130                 case 'k':
00131                         ++argv;
00132                         --argc;
00133                         size = atoi(argv[0]) * 1024;
00134                         break ;
00135                 case 'n':
00136                         ++argv;
00137                         --argc;
00138             if (argc < 1) 
00139             {
00140                         usage("Error: option 'n' requires a numeric argument\n");
00141                 }
00142                 if ((argv[0][0] >= '0') && (argv[0][0] <= '9'))
00143             {
00144                 numbufs = atoi(argv[0]) ;
00145                             if (numbufs < 2)
00146                             {
00147                                     printf("numbufs should be at least two to take\n") ;
00148                                     printf("advantage of ring buffer mode\n") ;
00149                                     exit(1) ;
00150                             }
00151             }
00152             else 
00153             {
00154                         usage("Error: option 'n' requires a numeric argument\n");
00155                 }
00156                 break;
00157                         
00158                 case 'l':
00159                         ++argv;
00160                         --argc;
00161                         if (argc < 1) 
00162             {
00163                         usage("Error: option 'l' requires a numeric argument\n");
00164                 }
00165                 if ((argv[0][0] >= '0') && (argv[0][0] <= '9'))
00166             {
00167                 loopcount = atoi(argv[0]) ;
00168             }
00169             else 
00170             {
00171                         usage("Error: option 'l' requires a numeric argument\n");
00172                 }
00173                 break;
00174 
00175                 case 'i':
00176                         ++argv ;
00177                         --argc ;
00178                         infile = strdup(argv[0]) ;
00179                         if (strcmp(infile, "-") == 0)
00180                                 ifd = fileno(stdin) ;
00181                         else
00182                         {
00183 #ifdef _NT_
00184                                 ifd =   (int)CreateFile(
00185                                         infile,
00186                                         GENERIC_READ | GENERIC_WRITE ,
00187                                         FILE_SHARE_READ | FILE_SHARE_WRITE,
00188                                         NULL,
00189                                         OPEN_EXISTING,
00190                                         FILE_ATTRIBUTE_NORMAL,
00191                                         NULL);
00192                                 if (ifd == (int)INVALID_HANDLE_VALUE)
00193                                 {
00194                                         fprintf(stderr, "failed open %s\n",infile) ;
00195                                         exit(1) ;
00196                                 }
00197 #else
00198                                 if ((ifd = open(infile, 0666)) < 0)
00199                                 {
00200                                         printf("create of %s failed\n", infile) ;
00201                                         perror("infile") ;
00202                                         exit(1) ;
00203                                 }
00204 #endif
00205                         }
00206                         break ;
00207                 case 'c':
00208                         ++argv ;
00209                         --argc ;
00210                         if (argc < 1) 
00211             {
00212                         usage("Error: option 'c' requires a numeric argument\n");
00213                 }
00214                 if ((argv[0][0] >= '0') && (argv[0][0] <= '9'))
00215             {
00216                 channel = atoi(argv[0]);
00217             }
00218             else 
00219             {
00220                         usage("Error: option 'c' requires a numeric argument\n");
00221                 }
00222                 break;
00223 
00224                 case 'h':
00225                 case '?':
00226             usage("help");
00227             break;
00228 
00229                 default:
00230                         usage("unknown option") ;
00231                 }
00232                 --argc;
00233                 ++argv;
00234     }
00235 
00236     if (infile )
00237             printf("writing buffers until end of file of %d bytes from unit %d channel %d with %d bufs\n",
00238                  size, unit, channel, numbufs) ;
00239     else
00240             printf("writing %d buffers of %d bytes from unit %d channel %d with %d bufs\n",
00241                 loopcount, size, unit, channel, numbufs) ;
00242 
00243     if ((edt_p = edt_open_channel(EDT_INTERFACE, unit,channel)) == NULL)
00244     {
00245                 perror("edt_open") ;
00246                 exit(1) ;
00247     }
00248 
00249     /*
00250      * Have edt_configure_ring_buffers allocate the ring buffers by
00251      * passing the last argument as NULL.  Otherwise pass in an array
00252      * of pointers to the buffers.
00253      */
00254         
00255     if (edt_configure_ring_buffers(edt_p, size, numbufs, EDT_WRITE, NULL) == -1)
00256     {
00257         perror("edt_configure_ring_buffers") ;
00258         exit(1) ;
00259     }
00260 
00261         (void)edt_dtime();
00262 #ifdef PCD
00263         if (byteswap)
00264             pcd_set_byteswap(edt_p, 1) ;
00265 #endif
00266 
00267     buffers_inuse = 0 ;
00268         curcnt = edt_timeouts(edt_p) ;
00269         lstcnt = curcnt ;
00270     done = 0;
00271     if (infile)
00272         loopcount = 0;
00273 
00274     for(loop = 0 ; (loop < loopcount || loopcount == 0) && !done ; loop++)
00275     {
00276                 /*
00277                  * Initialize and start ring buffers until they're all in use,
00278                  * i.e. don't wait for a buffer until they're all being used.
00279                  */
00280                 if (buffers_inuse >= numbufs)
00281                 {
00282                         /* All ring buffers are in use; wait for the next one to finish */
00283                         edt_wait_for_buffers(edt_p, 1) ;
00284                         --buffers_inuse ;
00285                         curcnt = edt_timeouts(edt_p) ;
00286                         if (lstcnt != curcnt) 
00287                         {
00288                                 putchar('x') ;
00289                                 timeouts++ ;
00290                                 lstcnt = curcnt ;
00291                                 edt_reset_ring_buffers(edt_p,0) ;
00292                                 edt_flush_fifo(edt_p) ;
00293                                 edt_start_buffers(edt_p, 0) ; /* start the transfers in free running mode */
00294                         }
00295                         else putchar('.') ;
00296                         fflush(stdout) ;
00297                 }
00298 
00299                 /*
00300                  * Copy data into each ring buffer, then start DMA.
00301                  * Data could come from a file, a tape drive, etc,
00302                  * and is written to the external device connected to
00303                  * the EDT board continuously via the ring buffers.
00304                  */
00305                 for(fill=buffers_inuse; fill<numbufs; fill++)
00306                 {
00307                 buf = edt_next_writebuf(edt_p) ;
00308 
00309                 if (infile)
00310                 {
00311                         unsigned long Length ;
00312 #ifdef _NT_             
00313                         ReadFile((void *)ifd, buf, size, &Length, NULL) ;
00314 #else
00315                         Length = read(ifd, buf, size) ;
00316 #endif
00317                         buf += size;
00318                         if (Length != size)
00319                                 {
00320                                 /* change size on last if not full buf */
00321                                 printf("end of file\n") ;
00322                                 done = 1;
00323                                 }
00324                 }
00325                 else 
00326                         init_buf(buf, size);
00327                 }
00328 
00329 
00330                 if (done == 0) 
00331                 {
00332                         /* Start the transfers on this buffer */
00333                         edt_start_buffers(edt_p, numbufs - buffers_inuse); 
00334                         total_buffers = total_buffers + (numbufs - buffers_inuse);
00335                         buffers_inuse = numbufs;
00336                 }
00337     }
00338 
00339     /* Now wait for remaining buffers to finish */
00340     while (buffers_inuse)
00341     {
00342                 --buffers_inuse ;
00343                 edt_wait_for_buffers(edt_p, 1) ;
00344 
00345                 putchar('.') ;
00346                 fflush(stdout) ;
00347     }
00348 
00349         dtime = edt_dtime() ;
00350         num_bytes = (double)total_buffers * (double)size;
00351         printf("\ntotalbuffers %d %f bytes/sec %d timeouts\n",
00352                 total_buffers, num_bytes / dtime,timeouts) ;
00353         printf("\nput %f bytes in %f seconds for %f bytes/second\n",
00354                             num_bytes,
00355                             dtime,
00356                             num_bytes/dtime);
00357         edt_close(edt_p) ;
00358         exit(0) ;
00359         return(0) ;
00360 }
00361 
00362 /*
00363  * initialize buffer with 16-bit incremented data
00364  * could replace with read of data from file, other device, or ???
00365  */
00366 void
00367 init_buf(u_char *buf, int size)
00368 {
00369     u_short word = 0;
00370     u_short *p, *endp;
00371     static int count = 0 ;
00372 
00373     if (++count > numbufs)
00374         return ;
00375 
00376     endp = (u_short *) (buf + size);
00377     p = (u_short *) buf;
00378 
00379     while (p < endp)
00380     {
00381         *p++ = word++;
00382     }
00383 }

Generated on 19 Jun 2015 by  doxygen 1.4.7