source: rtems/testsuites/samples/fileio/init.c @ 771803b

4.10
Last change on this file since 771803b was 771803b, checked in by Chris Johns <chrisj@…>, on 05/26/11 at 23:37:16

2011-05-27 Chris Johns <chrisj@…>

  • samples/fileio/init.c, samples/fileio/system.h: Add support for create a RAM disk from the shell to aid bug testing on the 4.10 branch.
  • Property mode set to 100644
File size: 29.6 KB
Line 
1/*  Init
2 *
3 *  This routine is the initialization task for this test program.
4 *  It is called from init_exec and has the responsibility for creating
5 *  and starting the tasks that make up the test.  If the time of day
6 *  clock is required for the test, it should also be set to a known
7 *  value by this function.
8 *
9 *  Input parameters:  NONE
10 *
11 *  Output parameters:  NONE
12 *
13 *  COPYRIGHT (c) 1989-2009.
14 *  On-Line Applications Research Corporation (OAR).
15 *
16 *  The license and distribution terms for this file may be
17 *  found in the file LICENSE in this distribution or at
18 *  http://www.rtems.com/license/LICENSE.
19 *
20 *  $Id$
21 */
22
23#define CONFIGURE_INIT
24#include "system.h"
25#include <stdio.h>
26#include <string.h>
27#include <unistd.h>
28#include <stdlib.h>
29#include <errno.h>
30#include <rtems.h>
31#include <fcntl.h>
32#include <inttypes.h>
33#include <rtems/error.h>
34#include <rtems/dosfs.h>
35#include <ctype.h>
36#include <rtems/bdpart.h>
37#include <rtems/libcsupport.h>
38#include <rtems/fsmount.h>
39#include <rtems/ramdisk.h>
40#include <rtems/nvdisk.h>
41#include <rtems/nvdisk-sram.h>
42
43#if FILEIO_BUILD
44
45/**
46 * Let the IO system allocation the next available major number.
47 */
48#define RTEMS_DRIVER_AUTO_MAJOR (0)
49
50/*
51 * RAM disk driver so you can create a RAM disk from the shell prompt.
52 */
53/**
54 * The RAM Disk configuration.
55 */
56rtems_ramdisk_config rtems_ramdisk_configuration[] =
57{
58  {
59    block_size: 512,
60    block_num:  1024,
61    location:   NULL
62  }
63};
64
65/**
66 * The number of RAM Disk configurations.
67 */
68size_t rtems_ramdisk_configuration_size = 1;
69
70/**
71 * Create the RAM Disk Driver entry.
72 */
73rtems_driver_address_table rtems_ramdisk_io_ops = {
74  initialization_entry: ramdisk_initialize,
75  open_entry:           rtems_blkdev_generic_open,
76  close_entry:          rtems_blkdev_generic_close,
77  read_entry:           rtems_blkdev_generic_read,
78  write_entry:          rtems_blkdev_generic_write,
79  control_entry:        rtems_blkdev_generic_ioctl
80};
81
82/**
83 * The NV Device descriptor. For this test it is just DRAM.
84 */
85rtems_nvdisk_device_desc rtems_nv_heap_device_descriptor[] =
86{
87  {
88    flags:  0,
89    base:   0,
90    size:   1 * 1024 * 1024,
91    nv_ops: &rtems_nvdisk_sram_handlers
92  }
93};
94
95/**
96 * The NV Disk configuration.
97 */
98const rtems_nvdisk_config rtems_nvdisk_configuration[] =
99{
100  {
101    block_size:         512,
102    device_count:       1,
103    devices:            &rtems_nv_heap_device_descriptor[0],
104    flags:              0,
105    info_level:         0
106  }
107};
108
109/**
110 * The number of NV Disk configurations.
111 */
112uint32_t rtems_nvdisk_configuration_size = 1;
113
114/**
115 * Create the NV Disk Driver entry.
116 */
117rtems_driver_address_table rtems_nvdisk_io_ops = {
118  initialization_entry: rtems_nvdisk_initialize,
119  open_entry:           rtems_blkdev_generic_open,
120  close_entry:          rtems_blkdev_generic_close,
121  read_entry:           rtems_blkdev_generic_read,
122  write_entry:          rtems_blkdev_generic_write,
123  control_entry:        rtems_blkdev_generic_ioctl
124};
125
126int
127setup_nvdisk (const char* mntpath)
128{
129  rtems_device_major_number major;
130  rtems_status_code         sc;
131
132  /*
133   * For our test we do not have any static RAM or EEPROM devices so
134   * we allocate the memory from the heap.
135   */
136  rtems_nv_heap_device_descriptor[0].base =
137    malloc (rtems_nv_heap_device_descriptor[0].size);
138
139  if (!rtems_nv_heap_device_descriptor[0].base)
140  {
141    printf ("error: no memory for NV disk\n");
142    return 1;
143  }
144 
145  /*
146   * Register the NV Disk driver.
147   */
148  printf ("Register NV Disk Driver: ");
149  sc = rtems_io_register_driver (RTEMS_DRIVER_AUTO_MAJOR,
150                                 &rtems_nvdisk_io_ops,
151                                 &major);
152  if (sc != RTEMS_SUCCESSFUL)
153  {
154    printf ("error: nvdisk driver not initialised: %s\n",
155            rtems_status_text (sc));
156    return 1;
157  }
158 
159  printf ("successful\n");
160
161  return 0;
162}
163
164/*
165 * Table of FAT file systems that will be mounted
166 * with the "fsmount" function.
167 * See cpukit/libmisc/fsmount for definition of fields
168 */
169fstab_t fs_table[] = {
170  {
171    "/dev/hda1","/mnt/hda1", "dosfs",
172    RTEMS_FILESYSTEM_READ_WRITE,
173    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
174    0
175  },
176  {
177    "/dev/hda2","/mnt/hda2", "dosfs",
178    RTEMS_FILESYSTEM_READ_WRITE,
179    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
180    0
181  },
182  {
183    "/dev/hda3","/mnt/hda3", "dosfs",
184    RTEMS_FILESYSTEM_READ_WRITE,
185    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
186    0
187  },
188  {
189    "/dev/hda4","/mnt/hda4", "dosfs",
190    RTEMS_FILESYSTEM_READ_WRITE,
191    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
192    0
193  },
194  {
195    "/dev/hdc1","/mnt/hdc1", "dosfs",
196    RTEMS_FILESYSTEM_READ_WRITE,
197    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
198    0
199  },
200  {
201    "/dev/hdc2","/mnt/hdc2", "dosfs",
202    RTEMS_FILESYSTEM_READ_WRITE,
203    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
204    0
205  },
206  {
207    "/dev/hdc3","/mnt/hdc3", "dosfs",
208    RTEMS_FILESYSTEM_READ_WRITE,
209    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
210    0
211  },
212  {
213    "/dev/hdc4","/mnt/hdc4", "dosfs",
214    RTEMS_FILESYSTEM_READ_WRITE,
215    FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED,
216    0
217  }
218};
219
220#define MIN(a,b) (((a) > (b)) ? (b) : (a))
221
222#define USE_SHELL
223
224#ifdef USE_SHELL
225#include <rtems/shell.h>
226
227int
228shell_nvdisk_trace (int argc, char* argv[])
229{
230  const char* driver;
231  int         level;
232
233  if (argc != 3)
234  {
235    printf ("error: invalid number of options\n");
236    return 1;
237  }
238
239  driver = argv[1];
240  level  = strtoul (argv[2], 0, 0);
241 
242  int fd = open (driver, O_WRONLY, 0);
243  if (fd < 0)
244  {
245    printf ("error: driver open failed: %s\n", strerror (errno));
246    return 1;
247  }
248 
249  if (ioctl (fd, RTEMS_NVDISK_IOCTL_INFO_LEVEL, level) < 0)
250  {
251    printf ("error: driver set level failed: %s\n", strerror (errno));
252    return 1;
253  }
254 
255  close (fd);
256 
257  return 0;
258}
259
260int
261shell_nvdisk_erase (int argc, char* argv[])
262{
263  const char* driver = NULL;
264  int         arg;
265  int         fd;
266 
267  for (arg = 1; arg < argc; arg++)
268  {
269    if (argv[arg][0] == '-')
270    {
271      printf ("error: invalid option: %s\n", argv[arg]);
272      return 1;
273    }
274    else
275    {
276      if (!driver)
277        driver = argv[arg];
278      else
279      {
280        printf ("error: only one driver name allowed: %s\n", argv[arg]);
281        return 1;
282      }
283    }
284  }
285 
286  printf ("erase nv disk: %s\n", driver);
287 
288  fd = open (driver, O_WRONLY, 0);
289  if (fd < 0)
290  {
291    printf ("error: nvdisk driver open failed: %s\n", strerror (errno));
292    return 1;
293  }
294 
295  if (ioctl (fd, RTEMS_NVDISK_IOCTL_ERASE_DISK) < 0)
296  {
297    printf ("error: nvdisk driver erase failed: %s\n", strerror (errno));
298    return 1;
299  }
300 
301  close (fd);
302 
303  printf ("nvdisk erased successful\n");
304
305  return 0;
306}
307
308int
309shell_bdbuf_trace (int argc, char* argv[])
310{
311#if RTEMS_BDBUF_TRACE
312  extern bool rtems_bdbuf_tracer;
313  rtems_bdbuf_tracer = !rtems_bdbuf_tracer;
314  printf ("bdbuf trace: %d\n", rtems_bdbuf_tracer);
315#else
316  printf ("bdbuf trace disabled. Rebuild with enabled.\n");
317#endif
318  return 0;
319}
320
321int
322disk_test_set_block_size (dev_t dev, size_t size)
323{
324  rtems_disk_device* dd;
325  int                rc;
326 
327  dd = rtems_disk_obtain (dev);
328  if (!dd)
329  {
330    printf ("error: cannot obtain disk\n");
331    return 1;
332  }
333 
334  rc = dd->ioctl (dd, RTEMS_BLKIO_SETBLKSIZE, &size);
335
336  rtems_disk_release (dd);
337
338  return rc;
339}
340
341int
342disk_test_write_blocks (dev_t dev, int start, int count, size_t size)
343{
344  int                 block;
345  uint32_t*           ip;
346  uint32_t            value = 0;
347  int                 i;
348  rtems_bdbuf_buffer* bd;
349  rtems_status_code   sc;
350 
351  if (disk_test_set_block_size (dev, size) < 0)
352  {
353    printf ("error: set block size failed: %s\n", strerror (errno));
354    return 1;
355  }
356
357  for (block = start; block < (start + count); block++)
358  {
359    sc = rtems_bdbuf_read (dev, block, &bd);
360    if (sc != RTEMS_SUCCESSFUL)
361    {
362      printf ("error: get block %d bd failed: %s\n",
363              block, rtems_status_text (sc));
364      return 1;
365    }
366
367    ip = (uint32_t*) bd->buffer;
368    for (i = 0; i < (size / sizeof (uint32_t)); i++, ip++, value++)
369      *ip = (size << 16) | value;
370
371    sc = rtems_bdbuf_release_modified (bd);
372    if (sc != RTEMS_SUCCESSFUL)
373    {
374      printf ("error: release block %d bd failed: %s\n",
375              block, rtems_status_text (sc));
376      return 1;
377    }
378  }
379
380  return 0;
381}
382
383int
384disk_test_block_sizes (int argc, char *argv[])
385{
386  struct stat st;
387  char*       name;
388  int         start;
389  int         count;
390  int         size;
391 
392  if (argc != (4 + 1))
393  {
394    printf ("error: need to supply a device path, start, block and size\n");
395    return 1;
396  }
397
398  name = argv[1];
399 
400  if (stat (name, &st) < 0)
401  {
402    printf ("error: stat '%s' failed: %s\n", name, strerror (errno));
403    return 1;
404  }
405
406  start = strtoul (argv[2], 0, 0);
407  count = strtoul (argv[3], 0, 0);
408  size  = strtoul (argv[4], 0, 0);
409 
410  return disk_test_write_blocks (st.st_rdev, start, count, size);
411}
412
413size_t
414parse_size_arg (const char* arg)
415{
416  size_t size;
417  size_t scalar = 1;
418 
419  size = strtoul (arg, 0, 0);
420  switch (arg[strlen (arg) - 1])
421  {
422    case 'M':
423      scalar = 1000 * 1024;
424      break;
425    case 'm':
426      scalar = 1000000;
427      break;
428    case 'K':
429      scalar = 1024;
430      break;
431    case 'k':
432      scalar = 1000;
433      break;
434    default:
435      printf ("error: invalid scalar (M/m/K/k): %c\n", arg[strlen (arg) - 1]);
436      return 0;
437  }
438  return size * scalar;
439 }
440
441int
442create_ramdisk (int argc, char *argv[])
443{
444  rtems_device_major_number major;
445  rtems_status_code         sc;
446  int                       arg;
447  size_t                    size = 0;
448  size_t                    block_size = 0;
449
450  for (arg = 0; arg < argc; ++arg)
451  {
452    if (argv[arg][0] == '-')
453    {
454      switch (argv[arg][0])
455      {
456        case 's':
457          ++arg;
458          if (arg == argc)
459          {
460            printf ("error: -s needs a size\n");
461            return 1;
462          }
463          size = parse_size_arg (argv[arg]);
464          if (size == 0)
465            return 1;
466          break;
467        case 'b':
468          ++arg;
469          if (arg == argc)
470          {
471            printf ("error: -b needs a size\n");
472            return 1;
473          }
474          block_size = parse_size_arg (argv[arg]);
475          if (size == 0)
476            return 1;
477          break;
478        default:
479          printf ("error: invalid option: %s\n", argv[arg]);
480          return 1;
481      }
482    }
483  }
484
485  if (block_size)
486    rtems_ramdisk_configuration[0].block_size = block_size;
487  if (size)
488    rtems_ramdisk_configuration[0].block_num =
489      size / rtems_ramdisk_configuration[0].block_size;
490   
491  /*
492   * Register the RAM Disk driver.
493   */
494  printf ("Register RAM Disk Driver [blocks=%" PRIu32 \
495          " block-size=%" PRIu32"]:",
496          rtems_ramdisk_configuration[0].block_num,
497          rtems_ramdisk_configuration[0].block_size);
498 
499  sc = rtems_io_register_driver (RTEMS_DRIVER_AUTO_MAJOR,
500                                 &rtems_ramdisk_io_ops,
501                                 &major);
502  if (sc != RTEMS_SUCCESSFUL)
503  {
504    printf ("error: ramdisk driver not initialised: %s\n",
505            rtems_status_text (sc));
506    return 1;
507  }
508 
509  printf ("successful\n");
510
511  return 0;
512}
513
514int
515create_nvdisk (int argc, char *argv[])
516{
517  rtems_device_major_number major;
518  rtems_status_code         sc;
519  int                       arg;
520  size_t                    size = 0;
521#if ADD_WHEN_NVDISK_HAS_CHANGED
522  size_t                    block_size = 0;
523#endif
524 
525  for (arg = 0; arg < argc; ++arg)
526  {
527    if (argv[arg][0] == '-')
528    {
529      switch (argv[arg][0])
530      {
531        case 's':
532          ++arg;
533          if (arg == argc)
534          {
535            printf ("error: -s needs a size\n");
536            return 1;
537          }
538          size = parse_size_arg (argv[arg]);
539          if (size == 0)
540            return 1;
541          break;
542#if ADD_WHEN_NVDISK_HAS_CHANGED
543        case 'b':
544          ++arg;
545          if (arg == argc)
546          {
547            printf ("error: -b needs a size\n");
548            return 1;
549          }
550          block_size = parse_size_arg (argv[arg]);
551          if (size == 0)
552            return 1;
553          break;
554#endif
555        default:
556          printf ("error: invalid option: %s\n", argv[arg]);
557          return 1;
558      }
559    }
560  }
561
562#if ADD_WHEN_NVDISK_HAS_CHANGED
563  if (block_size)
564    rtems_nvdisk_configuration[0].block_size = block_size;
565#endif
566  if (size)
567    rtems_nv_heap_device_descriptor[0].size = size;
568   
569  /*
570   * For our test we do not have any static RAM or EEPROM devices so
571   * we allocate the memory from the heap.
572   */
573  rtems_nv_heap_device_descriptor[0].base =
574    malloc (rtems_nv_heap_device_descriptor[0].size);
575
576  if (!rtems_nv_heap_device_descriptor[0].base)
577  {
578    printf ("error: no memory for NV disk\n");
579    return 1;
580  }
581 
582  /*
583   * Register the RAM Disk driver.
584   */
585  printf ("Register NV Disk Driver [size=%" PRIu32 \
586          " block-size=%" PRIu32"]:",
587          rtems_nv_heap_device_descriptor[0].size,
588          rtems_nvdisk_configuration[0].block_size);
589 
590  sc = rtems_io_register_driver (RTEMS_DRIVER_AUTO_MAJOR,
591                                 &rtems_nvdisk_io_ops,
592                                 &major);
593  if (sc != RTEMS_SUCCESSFUL)
594  {
595    printf ("error: nvdisk driver not initialised: %s\n",
596            rtems_status_text (sc));
597    return 1;
598  }
599 
600  printf ("successful\n");
601
602  return 0;
603}
604
605static void writeFile(
606  const char *name,
607  mode_t      mode,
608  const char *contents
609)
610{
611  int sc;
612  sc = setuid(0);
613  if ( sc ) {
614    printf( "setuid failed: %s: %s\n", name, strerror(errno) );
615  }
616
617  rtems_shell_write_file( name, contents );
618
619  sc = chmod ( name, mode );
620  if ( sc ) {
621    printf( "chmod %s: %s\n", name, strerror(errno) );
622  }
623}
624
625#define writeScript( _name, _contents ) \
626        writeFile( _name, 0777, _contents )
627
628static void fileio_start_shell(void)
629{
630  int sc;
631
632  sc = mkdir("/scripts", 0777);
633  if ( sc ) {
634    printf( "mkdir /scripts: %s:\n", strerror(errno) );
635  }
636
637  sc = mkdir("/etc", 0777);
638  if ( sc ) {
639    printf( "mkdir /etc: %s:\n", strerror(errno) );
640  }
641
642  printf(
643    "Creating /etc/passwd and group with three useable accounts\n"
644    "root/pwd , test/pwd, rtems/NO PASSWORD"
645  );
646
647  writeFile(
648    "/etc/passwd",
649    0644,
650    "root:7QR4o148UPtb.:0:0:root::/:/bin/sh\n"
651    "rtems:*:1:1:RTEMS Application::/:/bin/sh\n"
652    "test:8Yy.AaxynxbLI:2:2:test account::/:/bin/sh\n"
653    "tty:!:3:3:tty owner::/:/bin/false\n"
654  );
655  writeFile(
656    "/etc/group",
657    0644,
658    "root:x:0:root\n"
659    "rtems:x:1:rtems\n"
660    "test:x:2:test\n"
661    "tty:x:3:tty\n"
662  );
663
664  writeScript(
665    "/scripts/js",
666    "#! joel\n"
667    "\n"
668    "date\n"
669    "echo Script successfully ran\n"
670    "date\n"
671    "stackuse\n"
672  );
673
674  writeScript(
675    "/scripts/j1",
676    "#! joel -s 20480 -t JESS\n"
677    "stackuse\n"
678  );
679
680  rtems_shell_write_file(
681    "/scripts/j2",
682    "echo j2 TEST FILE\n"
683    "echo j2   SHOULD BE non-executable AND\n"
684    "echo j2   DOES NOT have the magic first line\n"
685  );
686
687  rtems_shell_add_cmd ("mkrd", "files",
688                       "Create a RAM disk driver", create_ramdisk);
689  rtems_shell_add_cmd ("mknvd", "files",
690                       "Create a NV disk driver", create_nvdisk);
691  rtems_shell_add_cmd ("nverase", "misc",
692                       "nverase driver", shell_nvdisk_erase);
693  rtems_shell_add_cmd ("nvtrace", "misc",
694                       "nvtrace driver level", shell_nvdisk_trace);
695  rtems_shell_add_cmd ("bdbuftrace", "files",
696                       "bdbuf trace toggle", shell_bdbuf_trace);
697  rtems_shell_add_cmd ("td", "files",
698                       "Test disk", disk_test_block_sizes);
699#if RTEMS_RFS_TRACE
700  rtems_shell_add_cmd ("rfs", "files",
701                       "RFS trace",
702                       rtems_rfs_trace_shell_command);
703#endif
704#if RTEMS_RFS_RTEMS_TRACE
705  rtems_shell_add_cmd ("rrfs", "files",
706                       "RTEMS RFS trace",
707                       rtems_rfs_rtems_trace_shell_command);
708#endif
709
710  printf("\n =========================\n");
711  printf(" starting shell\n");
712  printf(" =========================\n");
713  rtems_shell_init(
714    "SHLL",                          /* task_name */
715    RTEMS_MINIMUM_STACK_SIZE * 4,    /* task_stacksize */
716    100,                             /* task_priority */
717    "/dev/console",                  /* devname */
718    false,                           /* forever */
719    true,                            /* wait */
720    NULL                             /* login */
721  );
722}
723#endif /* USE_SHELL */
724
725static void fileio_print_free_heap(void)
726{
727  printf("--- unused dynamic memory: %lu bytes ---\n",
728         (unsigned long) malloc_free_space());
729}
730
731
732static void fileio_part_table_initialize(void)
733{
734  char devname[64];
735  rtems_status_code rc;
736
737  printf(" =========================\n");
738  printf(" Initialize partition table\n");
739  printf(" =========================\n");
740  fileio_print_free_heap();
741  printf(" Enter device to initialize ==>");
742  fflush(stdout);
743  fgets(devname,sizeof(devname)-1,stdin);
744  while (devname[strlen(devname)-1] == '\n') {
745    devname[strlen(devname)-1] = '\0';
746  }
747  /*
748   * call function
749   */
750  rc = rtems_bdpart_register_from_disk(devname);
751  printf("result = %d\n",rc);
752  fileio_print_free_heap();
753}
754
755static void fileio_fsmount(void)
756{
757  rtems_status_code rc;
758
759  printf(" =========================\n");
760  printf(" Process fsmount table\n");
761  printf(" =========================\n");
762  fileio_print_free_heap();
763  /*
764   * call function
765   */
766  rc = rtems_fsmount( fs_table,
767                      sizeof(fs_table)/sizeof(fs_table[0]),
768                      NULL);
769  printf("result = %d\n",rc);
770  fileio_print_free_heap();
771}
772
773static void fileio_list_file(void)
774{
775  char fname[1024];
776  char *buf_ptr = NULL;
777  ssize_t   flen = 0;
778  int fd = -1;
779  ssize_t n;
780  size_t buf_size = 100;
781
782  rtems_interval start_tick,curr_tick,ticks_per_sec;
783
784  printf(" =========================\n");
785  printf(" LIST FILE ...            \n");
786  printf(" =========================\n");
787  fileio_print_free_heap();
788  printf(" Enter filename to list ==>");
789  fflush(stdout);
790  fgets(fname,sizeof(fname)-1,stdin);
791  while (fname[strlen(fname)-1] == '\n') {
792    fname[strlen(fname)-1] = '\0';
793  }
794  /*
795   * allocate buffer of given size
796   */
797  if (buf_size > 0) {
798    buf_ptr = malloc(buf_size);
799  }
800
801  if (buf_ptr != NULL) {
802    printf("\n Trying to open file \"%s\" for read\n",fname);
803    fd = open(fname,O_RDONLY);
804    if (fd < 0) {
805      printf("*** file open failed, errno = %d(%s)\n",errno,strerror(errno));
806    }
807  }
808
809  if (fd >= 0) {
810    rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_tick);
811    do {
812      n = read(fd,buf_ptr,buf_size);
813      if (n > 0) {
814        write(1,buf_ptr,(size_t) n);
815        flen += n;
816      }
817    } while (n > 0);
818
819    rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &curr_tick);
820
821    printf("\n ******** End of file reached, flen = %zd\n",flen);
822    close(fd);
823
824    ticks_per_sec = rtems_clock_get_ticks_per_second();
825    printf("time elapsed for read:  %g seconds\n",
826           ((double)curr_tick-start_tick)/ticks_per_sec);
827  }
828  /*
829   * free buffer
830   */
831  if (buf_ptr != NULL) {
832    free(buf_ptr);
833  }
834  fileio_print_free_heap();
835}
836
837/*
838 * convert a size string (like 34K or 12M) to actual byte count
839 */
840static bool fileio_str2size(const char *str,uint32_t   *res_ptr)
841{
842  bool failed = false;
843  unsigned long size;
844  unsigned char suffix = ' ';
845
846  if (1 > sscanf(str,"%lu%c",&size,&suffix)) {
847    failed = true;
848  }
849  else if (toupper((int)suffix) == 'K') {
850    size *= 1024;
851  }
852  else if (toupper((int)suffix) == 'M') {
853    size *= 1024UL*1024UL;
854  }
855  else if (isalpha((int)suffix)) {
856    failed = true;
857  }
858
859  if (!failed) {
860    *res_ptr = size;
861  }
862  return failed;
863}
864
865static void fileio_write_file(void)
866{
867  char fname[1024];
868  char tmp_str[32];
869  uint32_t   file_size = 0;
870  uint32_t   buf_size  = 0;
871  size_t curr_pos,bytes_to_copy;
872  int fd = -1;
873  ssize_t n;
874  rtems_interval start_tick,curr_tick,ticks_per_sec;
875  char *bufptr = NULL;
876  bool failed = false;
877  static const char write_test_string[] =
878    "The quick brown fox jumps over the lazy dog\n";
879  static const char write_block_string[] =
880    "\n----- end of write buffer ------\n";
881
882  printf(" =========================\n");
883  printf(" WRITE FILE ...           \n");
884  printf(" =========================\n");
885  fileio_print_free_heap();
886  /*
887   * get number of ticks per second
888   */
889  ticks_per_sec = rtems_clock_get_ticks_per_second();
890
891  /*
892   * get path to file to write
893   */
894  if (!failed) {
895    printf("Enter path/filename ==>");
896    fflush(stdout);
897    fgets(fname,sizeof(fname)-1,stdin);
898    while (fname[strlen(fname)-1] == '\n') {
899      fname[strlen(fname)-1] = '\0';
900    }
901    if (0 == strlen(fname)) {
902      printf("*** no filename entered, aborted\n");
903      failed = true;
904    }
905  }
906  /*
907   * get total file size to write
908   */
909  if (!failed) {
910    printf("use suffix K for Kbytes, M for Mbytes or no suffix for bytes:\n"
911           "Enter filesize to write ==>");
912    fflush(stdout);
913    fgets(tmp_str,sizeof(tmp_str)-1,stdin);
914    failed = fileio_str2size(tmp_str,&file_size);
915    if (failed) {
916      printf("*** illegal file size, aborted\n");
917    }
918  }
919  /*
920   * get block size to write
921   */
922  if (!failed) {
923    printf("use suffix K for Kbytes, M for Mbytes or no suffix for bytes:\n"
924           "Enter block size to use for write calls ==>");
925    fflush(stdout);
926    fgets(tmp_str,sizeof(tmp_str)-1,stdin);
927    failed = fileio_str2size(tmp_str,&buf_size);
928    if (failed) {
929      printf("*** illegal block size, aborted\n");
930    }
931  }
932
933  /*
934   * allocate buffer
935   */
936  if (!failed) {
937    printf("... allocating %lu bytes of buffer for write data\n",
938           (unsigned long)buf_size);
939    bufptr = malloc(buf_size+1); /* extra space for terminating NUL char */
940    if (bufptr == NULL) {
941      printf("*** malloc failed, aborted\n");
942      failed = true;
943    }
944  }
945  /*
946   * fill buffer with test pattern
947   */
948  if (!failed) {
949    printf("... filling buffer with write data\n");
950    curr_pos = 0;
951    /*
952     * fill buffer with test string
953     */
954    while (curr_pos < buf_size) {
955      bytes_to_copy = MIN(buf_size-curr_pos,
956                          sizeof(write_test_string)-1);
957      memcpy(bufptr+curr_pos,write_test_string,bytes_to_copy);
958      curr_pos += bytes_to_copy;
959    }
960    /*
961     * put "end" mark at end of buffer
962     */
963    bytes_to_copy = sizeof(write_block_string)-1;
964    if (buf_size >= bytes_to_copy) {
965      memcpy(bufptr+buf_size-bytes_to_copy,
966             write_block_string,
967             bytes_to_copy);
968    }
969  }
970  /*
971   * create file
972   */
973  if (!failed) {
974    printf("... creating file \"%s\"\n",fname);
975    fd = open(fname,O_WRONLY | O_CREAT | O_TRUNC,S_IREAD|S_IWRITE);
976    if (fd < 0) {
977      printf("*** file create failed, errno = %d(%s)\n",errno,strerror(errno));
978      failed = true;
979    }
980  }
981  /*
982   * write file
983   */
984  if (!failed) {
985    printf("... writing to file\n");
986    rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_tick);
987    curr_pos = 0;
988    do {
989      bytes_to_copy = buf_size;
990      do {
991        n = write(fd,
992          bufptr + (buf_size-bytes_to_copy),
993                  MIN(bytes_to_copy,file_size-curr_pos));
994        if (n > 0) {
995          bytes_to_copy -= (size_t) n;
996          curr_pos      += (size_t) n;
997        }
998      } while ((bytes_to_copy > 0)  && (n > 0));
999    } while ((file_size > curr_pos) && (n > 0));
1000    rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &curr_tick);
1001    if (n < 0) {
1002      failed = true;
1003      printf("*** file write failed, "
1004             "%lu bytes written, "
1005             "errno = %d(%s)\n",
1006             (unsigned long)curr_pos,errno,strerror(errno));
1007    }
1008    else {
1009      printf("time elapsed for write:  %g seconds\n",
1010             ((double)curr_tick-start_tick)/ticks_per_sec);
1011      printf("write data rate: %g KBytes/second\n",
1012             (((double)file_size) / 1024.0 /
1013              (((double)curr_tick-start_tick)/ticks_per_sec)));
1014    }
1015  }
1016  if (fd >= 0) {
1017    printf("... closing file\n");
1018    close(fd);
1019  }
1020  if (bufptr != NULL) {
1021    printf("... deallocating buffer\n");
1022    free(bufptr);
1023    bufptr = NULL;
1024  }
1025  printf("\n ******** End of file write\n");
1026  fileio_print_free_heap();
1027}
1028
1029static void fileio_read_file(void)
1030{
1031  char fname[1024];
1032  char tmp_str[32];
1033  uint32_t   buf_size  = 0;
1034  size_t curr_pos;
1035  int fd = -1;
1036  ssize_t n;
1037  rtems_interval start_tick,curr_tick,ticks_per_sec;
1038  char *bufptr = NULL;
1039  bool failed = false;
1040
1041  printf(" =========================\n");
1042  printf(" READ FILE ...            \n");
1043  printf(" =========================\n");
1044  fileio_print_free_heap();
1045  /*
1046   * get number of ticks per second
1047   */
1048  ticks_per_sec = rtems_clock_get_ticks_per_second();
1049
1050  /*
1051   * get path to file to read
1052   */
1053  if (!failed) {
1054    printf("Enter path/filename ==>");
1055    fflush(stdout);
1056    fgets(fname,sizeof(fname)-1,stdin);
1057    while (fname[strlen(fname)-1] == '\n') {
1058      fname[strlen(fname)-1] = '\0';
1059    }
1060    if (0 == strlen(fname)) {
1061      printf("*** no filename entered, aborted\n");
1062      failed = true;
1063    }
1064  }
1065  /*
1066   * get block size to read
1067   */
1068  if (!failed) {
1069    printf("use suffix K for Kbytes, M for Mbytes or no suffix for bytes:\n"
1070           "Enter block size to use for read calls ==>");
1071    fflush(stdout);
1072    fgets(tmp_str,sizeof(tmp_str)-1,stdin);
1073    failed = fileio_str2size(tmp_str,&buf_size);
1074    if (failed) {
1075      printf("*** illegal block size, aborted\n");
1076    }
1077  }
1078
1079  /*
1080   * allocate buffer
1081   */
1082  if (!failed) {
1083    printf("... allocating %lu bytes of buffer for write data\n",
1084           (unsigned long)buf_size);
1085    bufptr = malloc(buf_size+1); /* extra space for terminating NUL char */
1086    if (bufptr == NULL) {
1087      printf("*** malloc failed, aborted\n");
1088      failed = true;
1089    }
1090  }
1091  /*
1092   * open file
1093   */
1094  if (!failed) {
1095    printf("... opening file \"%s\"\n",fname);
1096    fd = open(fname,O_RDONLY);
1097    if (fd < 0) {
1098      printf("*** file open failed, errno = %d(%s)\n",errno,strerror(errno));
1099      failed = true;
1100    }
1101  }
1102  /*
1103   * read file
1104   */
1105  if (!failed) {
1106    printf("... reading from file\n");
1107    rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_tick);
1108    curr_pos = 0;
1109    do {
1110      n = read(fd,
1111               bufptr,
1112               buf_size);
1113      if (n > 0) {
1114        curr_pos      += (size_t) n;
1115      }
1116    } while (n > 0);
1117    rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &curr_tick);
1118    if (n < 0) {
1119      failed = true;
1120      printf("*** file read failed, "
1121             "%lu bytes read, "
1122             "errno = %d(%s)\n",
1123             (unsigned long)curr_pos,errno,strerror(errno));
1124    }
1125    else {
1126      printf("%lu bytes read\n",
1127             (unsigned long)curr_pos);
1128      printf("time elapsed for read:  %g seconds\n",
1129             ((double)curr_tick-start_tick)/ticks_per_sec);
1130      printf("read data rate: %g KBytes/second\n",
1131             (((double)curr_pos) / 1024.0 /
1132              (((double)curr_tick-start_tick)/ticks_per_sec)));
1133    }
1134  }
1135  if (fd >= 0) {
1136    printf("... closing file\n");
1137    close(fd);
1138  }
1139  if (bufptr != NULL) {
1140    printf("... deallocating buffer\n");
1141    free(bufptr);
1142    bufptr = NULL;
1143  }
1144  printf("\n ******** End of file read\n");
1145  fileio_print_free_heap();
1146
1147}
1148
1149static void fileio_menu (void)
1150{
1151  char inbuf[10];
1152
1153  /*
1154   * Wait for characters from console terminal
1155   */
1156  for (;;) {
1157    printf(" =========================\n");
1158    printf(" RTEMS FILE I/O Test Menu \n");
1159    printf(" =========================\n");
1160    printf("   p -> part_table_initialize\n");
1161    printf("   f -> mount all disks in fs_table\n");
1162    printf("   l -> list  file\n");
1163    printf("   r -> read  file\n");
1164    printf("   w -> write file\n");
1165#ifdef USE_SHELL
1166    printf("   s -> start shell\n");
1167#endif
1168    printf("   Enter your selection ==>");
1169    fflush(stdout);
1170
1171    inbuf[0] = '\0';
1172    fgets(inbuf,sizeof(inbuf),stdin);
1173    switch (inbuf[0]) {
1174    case 'l':
1175      fileio_list_file ();
1176      break;
1177    case 'r':
1178      fileio_read_file ();
1179      break;
1180    case 'w':
1181      fileio_write_file ();
1182      break;
1183    case 'p':
1184      fileio_part_table_initialize ();
1185      break;
1186    case 'f':
1187      fileio_fsmount ();
1188      break;
1189#ifdef USE_SHELL
1190    case 's':
1191      fileio_start_shell ();
1192      break;
1193#endif
1194    default:
1195      printf("Selection `%c` not implemented\n",inbuf[0]);
1196      break;
1197    }
1198
1199  }
1200  exit (0);
1201}
1202
1203/*
1204 * RTEMS File Menu Task
1205 */
1206static rtems_task
1207fileio_task (rtems_task_argument ignored)
1208{
1209  fileio_menu();
1210}
1211
1212/*
1213 * RTEMS Startup Task
1214 */
1215rtems_task
1216Init (rtems_task_argument ignored)
1217{
1218  rtems_name Task_name;
1219  rtems_id   Task_id;
1220  rtems_status_code status;
1221
1222  puts( "\n\n*** FILE I/O SAMPLE AND TEST ***" );
1223
1224  Task_name = rtems_build_name('F','M','N','U');
1225
1226  status = rtems_task_create(
1227    Task_name, 1, RTEMS_MINIMUM_STACK_SIZE * 2,
1228    RTEMS_DEFAULT_MODES ,
1229    RTEMS_FLOATING_POINT | RTEMS_DEFAULT_ATTRIBUTES, &Task_id
1230  );
1231
1232  status = rtems_task_start( Task_id, fileio_task, 1 );
1233
1234  status = rtems_task_delete( RTEMS_SELF );
1235}
1236
1237#if defined(USE_SHELL)
1238/*
1239 *  RTEMS Shell Configuration -- Add a command and an alias for it
1240 */
1241
1242static int main_usercmd(int argc, char **argv)
1243{
1244  int i;
1245  printf( "UserCommand: argc=%d\n", argc );
1246  for (i=0 ; i<argc ; i++ )
1247    printf( "argv[%d]= %s\n", i, argv[i] );
1248  return 0;
1249}
1250
1251static rtems_shell_cmd_t Shell_USERCMD_Command = {
1252  "usercmd",                                       /* name */
1253  "usercmd n1 [n2 [n3...]]     # echo arguments",  /* usage */
1254  "user",                                          /* topic */
1255  main_usercmd,                                    /* command */
1256  NULL,                                            /* alias */
1257  NULL                                             /* next */
1258};
1259
1260static rtems_shell_alias_t Shell_USERECHO_Alias = {
1261  "usercmd",                 /* command */
1262  "userecho"                 /* alias */
1263};
1264
1265
1266#define CONFIGURE_SHELL_USER_COMMANDS &Shell_USERCMD_Command
1267#define CONFIGURE_SHELL_USER_ALIASES &Shell_USERECHO_Alias
1268#define CONFIGURE_SHELL_COMMANDS_INIT
1269#define CONFIGURE_SHELL_COMMANDS_ALL
1270#define CONFIGURE_SHELL_MOUNT_MSDOS
1271#define CONFIGURE_SHELL_MOUNT_RFS
1272#define CONFIGURE_SHELL_DEBUGRFS
1273
1274#include <rtems/shellconfig.h>
1275#endif
1276
1277#else
1278/*
1279 * RTEMS Startup Task
1280 */
1281rtems_task
1282Init (rtems_task_argument ignored)
1283{
1284  puts( "\n\n*** FILE I/O SAMPLE AND TEST ***" );
1285  puts( "\n\n*** NOT ENOUGH MEMORY TO BUILD AND RUN ***" );
1286}
1287#endif
Note: See TracBrowser for help on using the repository browser.