source: rtems/testsuites/samples/fileio/init.c @ 96bb783a

4.115
Last change on this file since 96bb783a was 96bb783a, checked in by Ralf Corsepius <ralf.corsepius@…>, on Oct 18, 2011 at 1:36:37 PM

2011-10-18 Ralf Corsépius <ralf.corsepius@…>

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