source: rtems/testsuites/samples/fileio/init.c @ 24b94c4

Last change on this file since 24b94c4 was 24b94c4, checked in by Sebastian Huber <sebastian.huber@…>, on Jul 30, 2018 at 4:39:09 AM

ramdisk: Use rtems_blkdev_create()

Update #3358.

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