Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:33

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (c) 2012 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031 
0032 #include "tmacros.h"
0033 
0034 #include <sys/stat.h>
0035 #include <errno.h>
0036 #include <string.h>
0037 #include <stdint.h>
0038 #include <unistd.h>
0039 #include <fcntl.h>
0040 
0041 #include <rtems/flashdisk.h>
0042 #include <rtems/libio.h>
0043 #include <rtems/blkdev.h>
0044 #include <rtems/rtems-rfs-format.h>
0045 
0046 #include "test-file-system.h"
0047 
0048 const char rtems_test_name[] = "FLASHDISK 1";
0049 
0050 /* forward declarations to avoid warnings */
0051 static rtems_task Init(rtems_task_argument argument);
0052 
0053 #define FLASHDISK_CONFIG_COUNT 1
0054 
0055 #define FLASHDISK_DEVICE_COUNT 1
0056 
0057 #define FLASHDISK_SEGMENT_COUNT 4U
0058 
0059 #define FLASHDISK_SEGMENT_SIZE (16 * 1024)
0060 
0061 #define FLASHDISK_BLOCK_SIZE 512U
0062 
0063 #define FLASHDISK_BLOCKS_PER_SEGMENT \
0064   (FLASHDISK_SEGMENT_SIZE / FLASHDISK_BLOCK_SIZE)
0065 
0066 #define FLASHDISK_SIZE \
0067   (FLASHDISK_SEGMENT_COUNT * FLASHDISK_SEGMENT_SIZE)
0068 
0069 static const rtems_rfs_format_config rfs_config;
0070 
0071 static const char device [] = "/dev/fdda";
0072 
0073 static const char mnt [] = "/mnt";
0074 
0075 static const char file [] = "/mnt/file";
0076 
0077 static uint8_t flashdisk_data [FLASHDISK_SIZE];
0078 
0079 static void flashdisk_print_status(const char *disk_path)
0080 {
0081   int rv;
0082   int fd = open(disk_path, O_RDWR);
0083   rtems_test_assert(fd >= 0);
0084 
0085   rv = ioctl(fd, RTEMS_FDISK_IOCTL_PRINT_STATUS);
0086   rtems_test_assert(rv == 0);
0087 
0088   rv = close(fd);
0089   rtems_test_assert(rv == 0);
0090 }
0091 
0092 static int test_rfs_mount_handler(
0093   const char *disk_path,
0094   const char *mount_path,
0095   void *arg
0096 )
0097 {
0098   return mount_and_make_target_path(
0099     disk_path,
0100     mount_path,
0101     RTEMS_FILESYSTEM_TYPE_RFS,
0102     RTEMS_FILESYSTEM_READ_WRITE,
0103     NULL
0104   );
0105 }
0106 
0107 static int test_rfs_format_handler(
0108   const char *disk_path,
0109   void *arg
0110 )
0111 {
0112   flashdisk_print_status(disk_path);
0113 
0114   rtems_test_assert(0);
0115 
0116   errno = EIO;
0117 
0118   return -1;
0119 }
0120 
0121 static const test_file_system_handler test_rfs_handler = {
0122   .mount = test_rfs_mount_handler,
0123   .format = test_rfs_format_handler
0124 };
0125 
0126 static void test(void)
0127 {
0128   int rv;
0129   const void *data = NULL;
0130 
0131   rv = mkdir(mnt, S_IRWXU | S_IRWXG | S_IRWXO);
0132   rtems_test_assert(rv == 0);
0133 
0134   rv = rtems_rfs_format(device, &rfs_config);
0135   rtems_test_assert(rv == 0);
0136 
0137   rv = mount(
0138     device,
0139     mnt,
0140     RTEMS_FILESYSTEM_TYPE_RFS,
0141     RTEMS_FILESYSTEM_READ_WRITE,
0142     data
0143   );
0144   rtems_test_assert(rv == 0);
0145 
0146   rv = mknod(file, S_IFREG | S_IRWXU | S_IRWXG | S_IRWXO, 0);
0147   rtems_test_assert(rv == 0);
0148 
0149   rv = unmount(mnt);
0150   rtems_test_assert(rv == 0);
0151 
0152   test_file_system_with_handler(
0153     0,
0154     device,
0155     mnt,
0156     &test_rfs_handler,
0157     NULL
0158   );
0159 
0160   flashdisk_print_status(device);
0161 }
0162 
0163 static void Init(rtems_task_argument arg)
0164 {
0165   TEST_BEGIN();
0166 
0167   test();
0168 
0169   TEST_END();
0170 
0171   rtems_test_exit(0);
0172 }
0173 
0174 static void erase_device(void)
0175 {
0176   memset(&flashdisk_data [0], 0xff, FLASHDISK_SIZE);
0177 }
0178 
0179 static rtems_device_driver flashdisk_initialize(
0180   rtems_device_major_number major,
0181   rtems_device_minor_number minor,
0182   void *arg
0183 )
0184 {
0185   erase_device();
0186 
0187   return rtems_fdisk_initialize(major, minor, arg);
0188 }
0189 
0190 static uint8_t *get_data_pointer(
0191   const rtems_fdisk_segment_desc *sd,
0192   uint32_t segment,
0193   uint32_t offset
0194 )
0195 {
0196   offset += sd->offset + (segment - sd->segment) * sd->size;
0197 
0198   return &flashdisk_data [offset];
0199 }
0200 
0201 static int flashdisk_read(
0202   const rtems_fdisk_segment_desc *sd,
0203   uint32_t device,
0204   uint32_t segment,
0205   uint32_t offset,
0206   void *buffer,
0207   uint32_t size
0208 )
0209 {
0210   int eno = 0;
0211   const uint8_t *data = get_data_pointer(sd, segment, offset);
0212 
0213   memcpy(buffer, data, size);
0214 
0215   return eno;
0216 }
0217 
0218 static int flashdisk_write(
0219   const rtems_fdisk_segment_desc *sd,
0220   uint32_t device,
0221   uint32_t segment,
0222   uint32_t offset,
0223   const void *buffer,
0224   uint32_t size
0225 )
0226 {
0227   int eno = 0;
0228   uint8_t *data = get_data_pointer(sd, segment, offset);
0229 
0230   memcpy(data, buffer, size);
0231 
0232   return eno;
0233 }
0234 
0235 static int flashdisk_blank(
0236   const rtems_fdisk_segment_desc *sd,
0237   uint32_t device,
0238   uint32_t segment,
0239   uint32_t offset,
0240   uint32_t size
0241 )
0242 {
0243   int eno = 0;
0244   const uint8_t *current = get_data_pointer(sd, segment, offset);
0245   const uint8_t *end = current + size;
0246 
0247   while (eno == 0 && current != end) {
0248     if (*current != 0xff) {
0249       eno = EIO;
0250     }
0251     ++current;
0252   }
0253 
0254   return eno;
0255 }
0256 
0257 static int flashdisk_verify(
0258   const rtems_fdisk_segment_desc *sd,
0259   uint32_t device,
0260   uint32_t segment,
0261   uint32_t offset,
0262   const void *buffer,
0263   uint32_t size
0264 )
0265 {
0266   int eno = 0;
0267   uint8_t *data = get_data_pointer(sd, segment, offset);
0268 
0269   if (memcmp(data, buffer, size) != 0) {
0270     eno = EIO;
0271   }
0272 
0273   return eno;
0274 }
0275 
0276 static int flashdisk_erase(
0277   const rtems_fdisk_segment_desc *sd,
0278   uint32_t device,
0279   uint32_t segment
0280 )
0281 {
0282   int eno = 0;
0283   uint8_t *data = get_data_pointer(sd, segment, 0);
0284 
0285   memset(data, 0xff, sd->size);
0286 
0287   return eno;
0288 }
0289 
0290 static int flashdisk_erase_device(
0291   const rtems_fdisk_device_desc *sd,
0292   uint32_t device
0293 )
0294 {
0295   int eno = 0;
0296 
0297   erase_device();
0298 
0299   return eno;
0300 }
0301 
0302 static const rtems_fdisk_segment_desc flashdisk_segment_desc = {
0303   .count = FLASHDISK_SEGMENT_COUNT,
0304   .segment = 0,
0305   .offset = 0,
0306   .size = FLASHDISK_SEGMENT_SIZE
0307 };
0308 
0309 static const rtems_fdisk_driver_handlers flashdisk_ops = {
0310   .read = flashdisk_read,
0311   .write = flashdisk_write,
0312   .blank = flashdisk_blank,
0313   .verify = flashdisk_verify,
0314   .erase = flashdisk_erase,
0315   .erase_device = flashdisk_erase_device
0316 };
0317 
0318 static const rtems_fdisk_device_desc flashdisk_device = {
0319   .segment_count = 1,
0320   .segments = &flashdisk_segment_desc,
0321   .flash_ops = &flashdisk_ops
0322 };
0323 
0324 const rtems_flashdisk_config
0325 rtems_flashdisk_configuration [FLASHDISK_CONFIG_COUNT] = {
0326   {
0327     .block_size = FLASHDISK_BLOCK_SIZE,
0328     .device_count = FLASHDISK_DEVICE_COUNT,
0329     .devices = &flashdisk_device,
0330     .flags = RTEMS_FDISK_CHECK_PAGES
0331       | RTEMS_FDISK_BLANK_CHECK_BEFORE_WRITE,
0332     .unavail_blocks = FLASHDISK_BLOCKS_PER_SEGMENT,
0333     .compact_segs = 2,
0334     .avail_compact_segs = 1,
0335     .info_level = 0
0336   }
0337 };
0338 
0339 uint32_t rtems_flashdisk_configuration_size = FLASHDISK_CONFIG_COUNT;
0340 
0341 #define FLASHDISK_DRIVER { .initialization_entry = flashdisk_initialize }
0342 
0343 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0344 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0345 #define CONFIGURE_APPLICATION_EXTRA_DRIVERS FLASHDISK_DRIVER
0346 #define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
0347 
0348 #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 6
0349 
0350 #define CONFIGURE_FILESYSTEM_RFS
0351 
0352 #define CONFIGURE_MAXIMUM_TASKS 2
0353 #define CONFIGURE_MAXIMUM_SEMAPHORES 1
0354 
0355 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0356 
0357 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0358 
0359 #define CONFIGURE_INIT_TASK_STACK_SIZE (32U * 1024U)
0360 
0361 #define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
0362 
0363 #define CONFIGURE_INIT
0364 
0365 #include <rtems/confdefs.h>