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

4.11
Last change on this file since 796967c was 796967c, checked in by Sebastian Huber <sebastian.huber@…>, on Feb 28, 2012 at 4:19:49 PM

libblock: Change bdbuf API

The functions

o rtems_bdbuf_get(),
o rtems_bdbuf_read(),
o rtems_bdbuf_syncdev(), and
o rtems_bdbuf_purge_dev(),

use now the disk device instead of the device identifier. This makes
bdbuf independent of rtems_disk_obtain() and rtems_disk_release(). It
is the responsiblity of the file system to obtain the disk device. This
also reduces the overhead to get a buffer.

The key for the AVL tree uses now the disk device instead of the device
identifier. The pointer is interpreted as an unsigned integer. This
reduces the memory overhead and makes the comparison operation a bit
faster.

Removed function rtems_bdbuf_purge_major(). This function was too
destructive and could have unpredictable side effects.

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