source: rtems/testsuites/samples/fileio/init.c @ acc9d064

5
Last change on this file since acc9d064 was 98c6d50, checked in by Chris Johns <chrisj@…>, on 10/19/17 at 05:39:16

testsuite: Use printk for all test output where possible.

  • Remove the printf support leaving the direct printk support configured with TESTS_USE_PRINTK and all other output goes via a buffered vsniprintf call to printk.
  • Control the test's single init for functions and global data with TEST_INIT and not CONFIGURE_INIT. They are now separate.

Updates #3170.

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