source: rtems/testsuites/samples/fileio/init.c @ 5f0cd34

4.11
Last change on this file since 5f0cd34 was 5f0cd34, checked in by Joel Sherrill <joel.sherrill@…>, on May 12, 2012 at 4:12:57 PM

samples - Eliminate missing prototype warnings

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