/* Init * * This routine is the initialization task for this test program. * It is called from init_exec and has the responsibility for creating * and starting the tasks that make up the test. If the time of day * clock is required for the test, it should also be set to a known * value by this function. * * Input parameters: NONE * * Output parameters: NONE * * COPYRIGHT (c) 1989-2011. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. * * $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define CONFIGURE_INIT #include "system.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if FILEIO_BUILD /** * Let the IO system allocation the next available major number. */ #define RTEMS_DRIVER_AUTO_MAJOR (0) /* * RAM disk driver so you can create a RAM disk from the shell prompt. */ /** * The RAM Disk configuration. */ rtems_ramdisk_config rtems_ramdisk_configuration[] = { { block_size: 512, block_num: 1024, location: NULL } }; /** * The number of RAM Disk configurations. */ size_t rtems_ramdisk_configuration_size = 1; /** * Create the RAM Disk Driver entry. */ rtems_driver_address_table rtems_ramdisk_io_ops = { initialization_entry: ramdisk_initialize, open_entry: rtems_blkdev_generic_open, close_entry: rtems_blkdev_generic_close, read_entry: rtems_blkdev_generic_read, write_entry: rtems_blkdev_generic_write, control_entry: rtems_blkdev_generic_ioctl }; /** * The NV Device descriptor. For this test it is just DRAM. */ rtems_nvdisk_device_desc rtems_nv_heap_device_descriptor[] = { { flags: 0, base: 0, size: 1 * 1024 * 1024, nv_ops: &rtems_nvdisk_sram_handlers } }; /** * The NV Disk configuration. */ const rtems_nvdisk_config rtems_nvdisk_configuration[] = { { block_size: 512, device_count: 1, devices: &rtems_nv_heap_device_descriptor[0], flags: 0, info_level: 0 } }; /** * The number of NV Disk configurations. */ uint32_t rtems_nvdisk_configuration_size = 1; /** * Create the NV Disk Driver entry. */ rtems_driver_address_table rtems_nvdisk_io_ops = { initialization_entry: rtems_nvdisk_initialize, open_entry: rtems_blkdev_generic_open, close_entry: rtems_blkdev_generic_close, read_entry: rtems_blkdev_generic_read, write_entry: rtems_blkdev_generic_write, control_entry: rtems_blkdev_generic_ioctl }; int setup_nvdisk (const char* mntpath) { rtems_device_major_number major; rtems_status_code sc; /* * For our test we do not have any static RAM or EEPROM devices so * we allocate the memory from the heap. */ rtems_nv_heap_device_descriptor[0].base = malloc (rtems_nv_heap_device_descriptor[0].size); if (!rtems_nv_heap_device_descriptor[0].base) { printf ("error: no memory for NV disk\n"); return 1; } /* * Register the NV Disk driver. */ printf ("Register NV Disk Driver: "); sc = rtems_io_register_driver (RTEMS_DRIVER_AUTO_MAJOR, &rtems_nvdisk_io_ops, &major); if (sc != RTEMS_SUCCESSFUL) { printf ("error: nvdisk driver not initialised: %s\n", rtems_status_text (sc)); return 1; } printf ("successful\n"); return 0; } /* * Table of FAT file systems that will be mounted * with the "fsmount" function. * See cpukit/libmisc/fsmount for definition of fields */ fstab_t fs_table[] = { { "/dev/hda1","/mnt/hda1", "dosfs", RTEMS_FILESYSTEM_READ_WRITE, FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED, 0 }, { "/dev/hda2","/mnt/hda2", "dosfs", RTEMS_FILESYSTEM_READ_WRITE, FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED, 0 }, { "/dev/hda3","/mnt/hda3", "dosfs", RTEMS_FILESYSTEM_READ_WRITE, FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED, 0 }, { "/dev/hda4","/mnt/hda4", "dosfs", RTEMS_FILESYSTEM_READ_WRITE, FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED, 0 }, { "/dev/hdc1","/mnt/hdc1", "dosfs", RTEMS_FILESYSTEM_READ_WRITE, FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED, 0 }, { "/dev/hdc2","/mnt/hdc2", "dosfs", RTEMS_FILESYSTEM_READ_WRITE, FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED, 0 }, { "/dev/hdc3","/mnt/hdc3", "dosfs", RTEMS_FILESYSTEM_READ_WRITE, FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED, 0 }, { "/dev/hdc4","/mnt/hdc4", "dosfs", RTEMS_FILESYSTEM_READ_WRITE, FSMOUNT_MNT_OK | FSMOUNT_MNTPNT_CRTERR | FSMOUNT_MNT_FAILED, 0 } }; #define MIN(a,b) (((a) > (b)) ? (b) : (a)) #define USE_SHELL #ifdef USE_SHELL #include int shell_nvdisk_trace (int argc, char* argv[]) { const char* driver; int level; if (argc != 3) { printf ("error: invalid number of options\n"); return 1; } driver = argv[1]; level = strtoul (argv[2], 0, 0); int fd = open (driver, O_WRONLY, 0); if (fd < 0) { printf ("error: driver open failed: %s\n", strerror (errno)); return 1; } if (ioctl (fd, RTEMS_NVDISK_IOCTL_INFO_LEVEL, level) < 0) { printf ("error: driver set level failed: %s\n", strerror (errno)); return 1; } close (fd); return 0; } int shell_nvdisk_erase (int argc, char* argv[]) { const char* driver = NULL; int arg; int fd; for (arg = 1; arg < argc; arg++) { if (argv[arg][0] == '-') { printf ("error: invalid option: %s\n", argv[arg]); return 1; } else { if (!driver) driver = argv[arg]; else { printf ("error: only one driver name allowed: %s\n", argv[arg]); return 1; } } } printf ("erase nv disk: %s\n", driver); fd = open (driver, O_WRONLY, 0); if (fd < 0) { printf ("error: nvdisk driver open failed: %s\n", strerror (errno)); return 1; } if (ioctl (fd, RTEMS_NVDISK_IOCTL_ERASE_DISK) < 0) { printf ("error: nvdisk driver erase failed: %s\n", strerror (errno)); return 1; } close (fd); printf ("nvdisk erased successful\n"); return 0; } int shell_bdbuf_trace (int argc, char* argv[]) { #if RTEMS_BDBUF_TRACE extern bool rtems_bdbuf_tracer; rtems_bdbuf_tracer = !rtems_bdbuf_tracer; printf ("bdbuf trace: %d\n", rtems_bdbuf_tracer); #else printf ("bdbuf trace disabled. Rebuild with enabled.\n"); #endif return 0; } int disk_test_set_block_size (dev_t dev, size_t size) { rtems_disk_device* dd; int rc; dd = rtems_disk_obtain (dev); if (!dd) { printf ("error: cannot obtain disk\n"); return 1; } rc = dd->ioctl (dd, RTEMS_BLKIO_SETBLKSIZE, &size); rtems_disk_release (dd); return rc; } int disk_test_write_blocks (dev_t dev, int start, int count, size_t size) { int block; uint32_t* ip; uint32_t value = 0; int i; rtems_bdbuf_buffer* bd; rtems_status_code sc; if (disk_test_set_block_size (dev, size) < 0) { printf ("error: set block size failed: %s\n", strerror (errno)); return 1; } for (block = start; block < (start + count); block++) { sc = rtems_bdbuf_read (dev, block, &bd); if (sc != RTEMS_SUCCESSFUL) { printf ("error: get block %d bd failed: %s\n", block, rtems_status_text (sc)); return 1; } ip = (uint32_t*) bd->buffer; for (i = 0; i < (size / sizeof (uint32_t)); i++, ip++, value++) *ip = (size << 16) | value; sc = rtems_bdbuf_release_modified (bd); if (sc != RTEMS_SUCCESSFUL) { printf ("error: release block %d bd failed: %s\n", block, rtems_status_text (sc)); return 1; } } return 0; } int disk_test_block_sizes (int argc, char *argv[]) { struct stat st; char* name; int start; int count; int size; if (argc != (4 + 1)) { printf ("error: need to supply a device path, start, block and size\n"); return 1; } name = argv[1]; if (stat (name, &st) < 0) { printf ("error: stat '%s' failed: %s\n", name, strerror (errno)); return 1; } start = strtoul (argv[2], 0, 0); count = strtoul (argv[3], 0, 0); size = strtoul (argv[4], 0, 0); return disk_test_write_blocks (st.st_rdev, start, count, size); } size_t parse_size_arg (const char* arg) { size_t size; size_t scalar = 1; size = strtoul (arg, 0, 0); switch (arg[strlen (arg) - 1]) { case 'M': scalar = 1000 * 1024; break; case 'm': scalar = 1000000; break; case 'K': scalar = 1024; break; case 'k': scalar = 1000; break; default: printf ("error: invalid scalar (M/m/K/k): %c\n", arg[strlen (arg) - 1]); return 0; } return size * scalar; } int create_ramdisk (int argc, char *argv[]) { rtems_device_major_number major; rtems_status_code sc; int arg; size_t size = 0; size_t block_size = 0; for (arg = 0; arg < argc; ++arg) { if (argv[arg][0] == '-') { switch (argv[arg][0]) { case 's': ++arg; if (arg == argc) { printf ("error: -s needs a size\n"); return 1; } size = parse_size_arg (argv[arg]); if (size == 0) return 1; break; case 'b': ++arg; if (arg == argc) { printf ("error: -b needs a size\n"); return 1; } block_size = parse_size_arg (argv[arg]); if (size == 0) return 1; break; default: printf ("error: invalid option: %s\n", argv[arg]); return 1; } } } if (block_size) rtems_ramdisk_configuration[0].block_size = block_size; if (size) rtems_ramdisk_configuration[0].block_num = size / rtems_ramdisk_configuration[0].block_size; /* * Register the RAM Disk driver. */ printf ("Register RAM Disk Driver [blocks=%" PRIu32 \ " block-size=%" PRIu32"]:", rtems_ramdisk_configuration[0].block_num, rtems_ramdisk_configuration[0].block_size); sc = rtems_io_register_driver (RTEMS_DRIVER_AUTO_MAJOR, &rtems_ramdisk_io_ops, &major); if (sc != RTEMS_SUCCESSFUL) { printf ("error: ramdisk driver not initialised: %s\n", rtems_status_text (sc)); return 1; } printf ("successful\n"); return 0; } int create_nvdisk (int argc, char *argv[]) { rtems_device_major_number major; rtems_status_code sc; int arg; size_t size = 0; #if ADD_WHEN_NVDISK_HAS_CHANGED size_t block_size = 0; #endif for (arg = 0; arg < argc; ++arg) { if (argv[arg][0] == '-') { switch (argv[arg][0]) { case 's': ++arg; if (arg == argc) { printf ("error: -s needs a size\n"); return 1; } size = parse_size_arg (argv[arg]); if (size == 0) return 1; break; #if ADD_WHEN_NVDISK_HAS_CHANGED case 'b': ++arg; if (arg == argc) { printf ("error: -b needs a size\n"); return 1; } block_size = parse_size_arg (argv[arg]); if (size == 0) return 1; break; #endif default: printf ("error: invalid option: %s\n", argv[arg]); return 1; } } } #if ADD_WHEN_NVDISK_HAS_CHANGED if (block_size) rtems_nvdisk_configuration[0].block_size = block_size; #endif if (size) rtems_nv_heap_device_descriptor[0].size = size; /* * For our test we do not have any static RAM or EEPROM devices so * we allocate the memory from the heap. */ rtems_nv_heap_device_descriptor[0].base = malloc (rtems_nv_heap_device_descriptor[0].size); if (!rtems_nv_heap_device_descriptor[0].base) { printf ("error: no memory for NV disk\n"); return 1; } /* * Register the RAM Disk driver. */ printf ("Register NV Disk Driver [size=%" PRIu32 \ " block-size=%" PRIu32"]:", rtems_nv_heap_device_descriptor[0].size, rtems_nvdisk_configuration[0].block_size); sc = rtems_io_register_driver (RTEMS_DRIVER_AUTO_MAJOR, &rtems_nvdisk_io_ops, &major); if (sc != RTEMS_SUCCESSFUL) { printf ("error: nvdisk driver not initialised: %s\n", rtems_status_text (sc)); return 1; } printf ("successful\n"); return 0; } static void writeFile( const char *name, mode_t mode, const char *contents ) { int sc; sc = setuid(0); if ( sc ) { printf( "setuid failed: %s: %s\n", name, strerror(errno) ); } rtems_shell_write_file( name, contents ); sc = chmod ( name, mode ); if ( sc ) { printf( "chmod %s: %s\n", name, strerror(errno) ); } } #define writeScript( _name, _contents ) \ writeFile( _name, 0777, _contents ) static void fileio_start_shell(void) { int sc; sc = mkdir("/scripts", 0777); if ( sc ) { printf( "mkdir /scripts: %s:\n", strerror(errno) ); } sc = mkdir("/etc", 0777); if ( sc ) { printf( "mkdir /etc: %s:\n", strerror(errno) ); } printf( "Creating /etc/passwd and group with three useable accounts\n" "root/pwd , test/pwd, rtems/NO PASSWORD" ); writeFile( "/etc/passwd", 0644, "root:7QR4o148UPtb.:0:0:root::/:/bin/sh\n" "rtems:*:1:1:RTEMS Application::/:/bin/sh\n" "test:8Yy.AaxynxbLI:2:2:test account::/:/bin/sh\n" "tty:!:3:3:tty owner::/:/bin/false\n" ); writeFile( "/etc/group", 0644, "root:x:0:root\n" "rtems:x:1:rtems\n" "test:x:2:test\n" "tty:x:3:tty\n" ); writeScript( "/scripts/js", "#! joel\n" "\n" "date\n" "echo Script successfully ran\n" "date\n" "stackuse\n" ); writeScript( "/scripts/j1", "#! joel -s 20480 -t JESS\n" "stackuse\n" ); rtems_shell_write_file( "/scripts/j2", "echo j2 TEST FILE\n" "echo j2 SHOULD BE non-executable AND\n" "echo j2 DOES NOT have the magic first line\n" ); rtems_shell_add_cmd ("mkrd", "files", "Create a RAM disk driver", create_ramdisk); rtems_shell_add_cmd ("mknvd", "files", "Create a NV disk driver", create_nvdisk); rtems_shell_add_cmd ("nverase", "misc", "nverase driver", shell_nvdisk_erase); rtems_shell_add_cmd ("nvtrace", "misc", "nvtrace driver level", shell_nvdisk_trace); rtems_shell_add_cmd ("bdbuftrace", "files", "bdbuf trace toggle", shell_bdbuf_trace); rtems_shell_add_cmd ("td", "files", "Test disk", disk_test_block_sizes); #if RTEMS_RFS_TRACE rtems_shell_add_cmd ("rfs", "files", "RFS trace", rtems_rfs_trace_shell_command); #endif #if RTEMS_RFS_RTEMS_TRACE rtems_shell_add_cmd ("rrfs", "files", "RTEMS RFS trace", rtems_rfs_rtems_trace_shell_command); #endif printf("\n =========================\n"); printf(" starting shell\n"); printf(" =========================\n"); rtems_shell_init( "SHLL", /* task_name */ RTEMS_MINIMUM_STACK_SIZE * 4, /* task_stacksize */ 100, /* task_priority */ "/dev/console", /* devname */ false, /* forever */ true, /* wait */ NULL /* login */ ); } #endif /* USE_SHELL */ static void fileio_print_free_heap(void) { printf("--- unused dynamic memory: %lu bytes ---\n", (unsigned long) malloc_free_space()); } static void fileio_part_table_initialize(void) { char devname[64]; rtems_status_code rc; printf(" =========================\n"); printf(" Initialize partition table\n"); printf(" =========================\n"); fileio_print_free_heap(); printf(" Enter device to initialize ==>"); fflush(stdout); fgets(devname,sizeof(devname)-1,stdin); while (devname[strlen(devname)-1] == '\n') { devname[strlen(devname)-1] = '\0'; } /* * call function */ rc = rtems_bdpart_register_from_disk(devname); printf("result = %d\n",rc); fileio_print_free_heap(); } static void fileio_fsmount(void) { rtems_status_code rc; printf(" =========================\n"); printf(" Process fsmount table\n"); printf(" =========================\n"); fileio_print_free_heap(); /* * call function */ rc = rtems_fsmount( fs_table, sizeof(fs_table)/sizeof(fs_table[0]), NULL); printf("result = %d\n",rc); fileio_print_free_heap(); } static void fileio_list_file(void) { char fname[1024]; char *buf_ptr = NULL; ssize_t flen = 0; int fd = -1; ssize_t n; size_t buf_size = 100; rtems_interval start_tick,curr_tick,ticks_per_sec; printf(" =========================\n"); printf(" LIST FILE ... \n"); printf(" =========================\n"); fileio_print_free_heap(); printf(" Enter filename to list ==>"); fflush(stdout); fgets(fname,sizeof(fname)-1,stdin); while (fname[strlen(fname)-1] == '\n') { fname[strlen(fname)-1] = '\0'; } /* * allocate buffer of given size */ if (buf_size > 0) { buf_ptr = malloc(buf_size); } if (buf_ptr != NULL) { printf("\n Trying to open file \"%s\" for read\n",fname); fd = open(fname,O_RDONLY); if (fd < 0) { printf("*** file open failed, errno = %d(%s)\n",errno,strerror(errno)); } } if (fd >= 0) { start_tick = rtems_clock_get_ticks_since_boot(); do { n = read(fd,buf_ptr,buf_size); if (n > 0) { write(1,buf_ptr,(size_t) n); flen += n; } } while (n > 0); curr_tick = rtems_clock_get_ticks_since_boot(); printf("\n ******** End of file reached, flen = %zd\n",flen); close(fd); ticks_per_sec = rtems_clock_get_ticks_per_second(); printf("time elapsed for read: %g seconds\n", ((double)curr_tick-start_tick)/ticks_per_sec); } /* * free buffer */ if (buf_ptr != NULL) { free(buf_ptr); } fileio_print_free_heap(); } /* * convert a size string (like 34K or 12M) to actual byte count */ static bool fileio_str2size(const char *str,uint32_t *res_ptr) { bool failed = false; unsigned long size; unsigned char suffix = ' '; if (1 > sscanf(str,"%lu%c",&size,&suffix)) { failed = true; } else if (toupper((int)suffix) == 'K') { size *= 1024; } else if (toupper((int)suffix) == 'M') { size *= 1024UL*1024UL; } else if (isalpha((int)suffix)) { failed = true; } if (!failed) { *res_ptr = size; } return failed; } static void fileio_write_file(void) { char fname[1024]; char tmp_str[32]; uint32_t file_size = 0; uint32_t buf_size = 0; size_t curr_pos,bytes_to_copy; int fd = -1; ssize_t n; rtems_interval start_tick,curr_tick,ticks_per_sec; char *bufptr = NULL; bool failed = false; static const char write_test_string[] = "The quick brown fox jumps over the lazy dog\n"; static const char write_block_string[] = "\n----- end of write buffer ------\n"; printf(" =========================\n"); printf(" WRITE FILE ... \n"); printf(" =========================\n"); fileio_print_free_heap(); /* * get number of ticks per second */ ticks_per_sec = rtems_clock_get_ticks_per_second(); /* * get path to file to write */ if (!failed) { printf("Enter path/filename ==>"); fflush(stdout); fgets(fname,sizeof(fname)-1,stdin); while (fname[strlen(fname)-1] == '\n') { fname[strlen(fname)-1] = '\0'; } if (0 == strlen(fname)) { printf("*** no filename entered, aborted\n"); failed = true; } } /* * get total file size to write */ if (!failed) { printf("use suffix K for Kbytes, M for Mbytes or no suffix for bytes:\n" "Enter filesize to write ==>"); fflush(stdout); fgets(tmp_str,sizeof(tmp_str)-1,stdin); failed = fileio_str2size(tmp_str,&file_size); if (failed) { printf("*** illegal file size, aborted\n"); } } /* * get block size to write */ if (!failed) { printf("use suffix K for Kbytes, M for Mbytes or no suffix for bytes:\n" "Enter block size to use for write calls ==>"); fflush(stdout); fgets(tmp_str,sizeof(tmp_str)-1,stdin); failed = fileio_str2size(tmp_str,&buf_size); if (failed) { printf("*** illegal block size, aborted\n"); } } /* * allocate buffer */ if (!failed) { printf("... allocating %lu bytes of buffer for write data\n", (unsigned long)buf_size); bufptr = malloc(buf_size+1); /* extra space for terminating NUL char */ if (bufptr == NULL) { printf("*** malloc failed, aborted\n"); failed = true; } } /* * fill buffer with test pattern */ if (!failed) { printf("... filling buffer with write data\n"); curr_pos = 0; /* * fill buffer with test string */ while (curr_pos < buf_size) { bytes_to_copy = MIN(buf_size-curr_pos, sizeof(write_test_string)-1); memcpy(bufptr+curr_pos,write_test_string,bytes_to_copy); curr_pos += bytes_to_copy; } /* * put "end" mark at end of buffer */ bytes_to_copy = sizeof(write_block_string)-1; if (buf_size >= bytes_to_copy) { memcpy(bufptr+buf_size-bytes_to_copy, write_block_string, bytes_to_copy); } } /* * create file */ if (!failed) { printf("... creating file \"%s\"\n",fname); fd = open(fname,O_WRONLY | O_CREAT | O_TRUNC,S_IREAD|S_IWRITE); if (fd < 0) { printf("*** file create failed, errno = %d(%s)\n",errno,strerror(errno)); failed = true; } } /* * write file */ if (!failed) { printf("... writing to file\n"); start_tick = rtems_clock_get_ticks_since_boot(); curr_pos = 0; do { bytes_to_copy = buf_size; do { n = write(fd, bufptr + (buf_size-bytes_to_copy), MIN(bytes_to_copy,file_size-curr_pos)); if (n > 0) { bytes_to_copy -= (size_t) n; curr_pos += (size_t) n; } } while ((bytes_to_copy > 0) && (n > 0)); } while ((file_size > curr_pos) && (n > 0)); curr_tick = rtems_clock_get_ticks_since_boot(); if (n < 0) { failed = true; printf("*** file write failed, " "%lu bytes written, " "errno = %d(%s)\n", (unsigned long)curr_pos,errno,strerror(errno)); } else { printf("time elapsed for write: %g seconds\n", ((double)curr_tick-start_tick)/ticks_per_sec); printf("write data rate: %g KBytes/second\n", (((double)file_size) / 1024.0 / (((double)curr_tick-start_tick)/ticks_per_sec))); } } if (fd >= 0) { printf("... closing file\n"); close(fd); } if (bufptr != NULL) { printf("... deallocating buffer\n"); free(bufptr); bufptr = NULL; } printf("\n ******** End of file write\n"); fileio_print_free_heap(); } static void fileio_read_file(void) { char fname[1024]; char tmp_str[32]; uint32_t buf_size = 0; size_t curr_pos; int fd = -1; ssize_t n; rtems_interval start_tick,curr_tick,ticks_per_sec; char *bufptr = NULL; bool failed = false; printf(" =========================\n"); printf(" READ FILE ... \n"); printf(" =========================\n"); fileio_print_free_heap(); /* * get number of ticks per second */ ticks_per_sec = rtems_clock_get_ticks_per_second(); /* * get path to file to read */ if (!failed) { printf("Enter path/filename ==>"); fflush(stdout); fgets(fname,sizeof(fname)-1,stdin); while (fname[strlen(fname)-1] == '\n') { fname[strlen(fname)-1] = '\0'; } if (0 == strlen(fname)) { printf("*** no filename entered, aborted\n"); failed = true; } } /* * get block size to read */ if (!failed) { printf("use suffix K for Kbytes, M for Mbytes or no suffix for bytes:\n" "Enter block size to use for read calls ==>"); fflush(stdout); fgets(tmp_str,sizeof(tmp_str)-1,stdin); failed = fileio_str2size(tmp_str,&buf_size); if (failed) { printf("*** illegal block size, aborted\n"); } } /* * allocate buffer */ if (!failed) { printf("... allocating %lu bytes of buffer for write data\n", (unsigned long)buf_size); bufptr = malloc(buf_size+1); /* extra space for terminating NUL char */ if (bufptr == NULL) { printf("*** malloc failed, aborted\n"); failed = true; } } /* * open file */ if (!failed) { printf("... opening file \"%s\"\n",fname); fd = open(fname,O_RDONLY); if (fd < 0) { printf("*** file open failed, errno = %d(%s)\n",errno,strerror(errno)); failed = true; } } /* * read file */ if (!failed) { printf("... reading from file\n"); start_tick = rtems_clock_get_ticks_since_boot(); curr_pos = 0; do { n = read(fd, bufptr, buf_size); if (n > 0) { curr_pos += (size_t) n; } } while (n > 0); curr_tick = rtems_clock_get_ticks_since_boot(); if (n < 0) { failed = true; printf("*** file read failed, " "%lu bytes read, " "errno = %d(%s)\n", (unsigned long)curr_pos,errno,strerror(errno)); } else { printf("%lu bytes read\n", (unsigned long)curr_pos); printf("time elapsed for read: %g seconds\n", ((double)curr_tick-start_tick)/ticks_per_sec); printf("read data rate: %g KBytes/second\n", (((double)curr_pos) / 1024.0 / (((double)curr_tick-start_tick)/ticks_per_sec))); } } if (fd >= 0) { printf("... closing file\n"); close(fd); } if (bufptr != NULL) { printf("... deallocating buffer\n"); free(bufptr); bufptr = NULL; } printf("\n ******** End of file read\n"); fileio_print_free_heap(); } static void fileio_menu (void) { char inbuf[10]; /* * Wait for characters from console terminal */ for (;;) { printf(" =========================\n"); printf(" RTEMS FILE I/O Test Menu \n"); printf(" =========================\n"); printf(" p -> part_table_initialize\n"); printf(" f -> mount all disks in fs_table\n"); printf(" l -> list file\n"); printf(" r -> read file\n"); printf(" w -> write file\n"); #ifdef USE_SHELL printf(" s -> start shell\n"); #endif printf(" Enter your selection ==>"); fflush(stdout); inbuf[0] = '\0'; fgets(inbuf,sizeof(inbuf),stdin); switch (inbuf[0]) { case 'l': fileio_list_file (); break; case 'r': fileio_read_file (); break; case 'w': fileio_write_file (); break; case 'p': fileio_part_table_initialize (); break; case 'f': fileio_fsmount (); break; #ifdef USE_SHELL case 's': fileio_start_shell (); break; #endif default: printf("Selection `%c` not implemented\n",inbuf[0]); break; } } exit (0); } /* * RTEMS File Menu Task */ static rtems_task fileio_task (rtems_task_argument ignored) { fileio_menu(); } /* * RTEMS Startup Task */ rtems_task Init (rtems_task_argument ignored) { rtems_name Task_name; rtems_id Task_id; rtems_status_code status; puts( "\n\n*** FILE I/O SAMPLE AND TEST ***" ); Task_name = rtems_build_name('F','M','N','U'); status = rtems_task_create( Task_name, 1, RTEMS_MINIMUM_STACK_SIZE * 2, RTEMS_DEFAULT_MODES , RTEMS_FLOATING_POINT | RTEMS_DEFAULT_ATTRIBUTES, &Task_id ); directive_failed( status, "create" ); status = rtems_task_start( Task_id, fileio_task, 1 ); directive_failed( status, "start" ); status = rtems_task_delete( RTEMS_SELF ); directive_failed( status, "delete" ); } #if defined(USE_SHELL) /* * RTEMS Shell Configuration -- Add a command and an alias for it */ static int main_usercmd(int argc, char **argv) { int i; printf( "UserCommand: argc=%d\n", argc ); for (i=0 ; i #endif #else /* * RTEMS Startup Task */ rtems_task Init (rtems_task_argument ignored) { puts( "\n\n*** FILE I/O SAMPLE AND TEST ***" ); puts( "\n\n*** NOT ENOUGH MEMORY TO BUILD AND RUN ***" ); } #endif