[PATCH rtems6 - v1 07/16] Flashdev: Refactor write_block_size and add function to dergister flashdev

Bernd Moessner berndmoessner80 at gmail.com
Thu Jan 4 22:15:26 UTC 2024


On 04.01.2024 20:05, Kinsey Moore wrote:
> A few comments inline.
>
> On Thu, Jan 4, 2024 at 12:35 PM <berndmoessner80 at gmail.com> wrote:
>
>     From: Bernd Moessner <berndmoessner80 at gmail.com>
>
>     ---
>      cpukit/dev/flash/flashdev.c                   |  71 ++++--
>      cpukit/include/dev/flash/flashdev.h           |  22 +-
>      cpukit/libmisc/shell/main_flashdev.c          |  26 +--
>      testsuites/libtests/flashdev01/init.c         | 204
>     ++++++++++++------
>      .../libtests/flashdev01/test_flashdev.c       |  54 +++--
>      .../libtests/flashdev01/test_flashdev.h       |   4 +-
>      6 files changed, 264 insertions(+), 117 deletions(-)
>
>     diff --git a/cpukit/dev/flash/flashdev.c b/cpukit/dev/flash/flashdev.c
>     index 0020e8d2c1..f50d2235a1 100644
>     --- a/cpukit/dev/flash/flashdev.c
>     +++ b/cpukit/dev/flash/flashdev.c
>     @@ -124,7 +124,7 @@ static int rtems_flashdev_ioctl_get_page_count(
>        void *arg
>      );
>
>     -static int rtems_flashdev_ioctl_get_write_block_size(
>     +static int rtems_flashdev_ioctl_get_min_write_size(
>
>
> I'm not sure I agree with this renaming. As I understood it, it is 
> actually the write block size which implies all writes must be a 
> multiple of the write block size versus minimum write size implying 
> that writes must only be larger than (or equal to) the provided size. 
> The NOR chips that support ECC when writing in 16-byte chunks would 
> disable ECC for partial writes of a 16-byte block performed primarily 
> on adjacent blocks. I should probably check that there is a write 
> alignment guarantee in flashdev.

No matter on what we agree we, we should document our expectation how a 
flash memory is organized.

The memory organization on page 12 in

https://www.macronix.com/Lists/Datasheet/Attachments/8745/MX25L51245G,%203V,%20512Mb,%20v1.7.pdf

is, from my point of view, the most traditional view on a flash. Perhaps 
it is problem of me, but when someone speaks of "block" wrt. to flash 
memories I immediately assume it is a multiple of sections.

However, I know flashes like the S25FL512S which has the ECC feature 
you've mentioned. This special device has "16 Byte Programming Blocks" 
with an ECC feature. However, does this lead "min_write_block_size" or 
"min_ecc_block_size"? There are other reasons than ECC for which a 
driver might want to report back min write size and aligned writes. 
Calling it simply "min_write_size" gives us both, it does not get 
confused with a block size and it can report back a size / alignment 
information. Perhaps, we could add an IOCTL to allow / forbid aligned 
writes.


>        rtems_flashdev *flash,
>        void *arg
>      );
>     @@ -146,8 +146,7 @@ static int rtems_flashdev_get_abs_addr(
>      static int rtems_flashdev_update_and_return(
>        rtems_libio_t *iop,
>        int status,
>     -  size_t count,
>     -  off_t new_offset
>     +  size_t count
>      );
>
>      static uint32_t rtems_flashdev_find_unallocated_region(
>     @@ -225,13 +224,20 @@ static const
>     rtems_filesystem_file_handlers_r rtems_flashdev_handler = {
>        .poll_h = rtems_filesystem_default_poll,
>        .readv_h = rtems_filesystem_default_readv,
>        .writev_h = rtems_filesystem_default_writev };
>     -
>     +/*
>      static const IMFS_node_control
>        rtems_flashdev_node_control = IMFS_GENERIC_INITIALIZER(
>          &rtems_flashdev_handler,
>          IMFS_node_initialize_generic,
>          rtems_flashdev_node_destroy
>      );
>     +*/
>
>
> The above definition should be removed instead of commented out.
>
I`ll keep Aarons implementation.
>
>     +static const IMFS_node_control rtems_flashdev_node_control = {
>     +  .handlers = &rtems_flashdev_handler,
>     +  .node_initialize = IMFS_node_initialize_generic,
>     +  .node_remove = IMFS_node_remove_default,
>     +  .node_destroy = rtems_flashdev_node_destroy
>     +};
>
>      static void rtems_flashdev_node_destroy(
>        IMFS_jnode_t *node
>     @@ -321,7 +327,7 @@ static int rtems_flashdev_read_write(
>        int status;
>
>        if ( read_buff == NULL && write_buff == NULL ) {
>     -    return 0;
>     +    return EINVAL;
>        }
>
>        /* Get flash address */
>     @@ -335,12 +341,35 @@ static int rtems_flashdev_read_write(
>        if ( read_buff != NULL ) {
>          status = ( *flash->read )( flash, addr, count, read_buff );
>        } else if ( write_buff != NULL ) {
>     +    size_t min_write_size = 0;
>     +    status = (flash)->get_min_write_size(flash, &min_write_size);
>     +
>     +    if ( status < 0 ) {
>     +      return status;
>     +    }
>     +
>     +    if (0 == min_write_size )
>     +    {
>     +      rtems_set_errno_and_return_minus_one( EIO );
>     +    }
>     +    else
>     +    {
>     +      if (count % min_write_size)
>     +      {
>     +        rtems_set_errno_and_return_minus_one( EINVAL );
>     +      }
>     +      if (addr % min_write_size)
>     +      {
>     +        rtems_set_errno_and_return_minus_one( EFAULT );
>     +      }
>     +    }
>     +
>          status = ( *flash->write )( flash, addr, count, write_buff );
>        }
>        rtems_flashdev_release( flash );
>
>        /* Update offset and return */
>     -  return rtems_flashdev_update_and_return( iop, status, count,
>     addr + count );
>     +  return rtems_flashdev_update_and_return( iop, status, count );
>      }
>
>      static int rtems_flashdev_ioctl(
>     @@ -388,8 +417,8 @@ static int rtems_flashdev_ioctl(
>          case RTEMS_FLASHDEV_IOCTL_GET_PAGE_COUNT:
>            err = rtems_flashdev_ioctl_get_page_count( flash, arg );
>            break;
>     -    case RTEMS_FLASHDEV_IOCTL_GET_WRITE_BLOCK_SIZE:
>     -      err = rtems_flashdev_ioctl_get_write_block_size( flash, arg );
>     +    case RTEMS_FLASHDEV_IOCTL_GET_MIN_WRITE_SIZE:
>     +      err = rtems_flashdev_ioctl_get_min_write_size( flash, arg );
>            break;
>          default:
>            err = EINVAL;
>     @@ -486,6 +515,18 @@ int rtems_flashdev_register(
>        return rv;
>      }
>
>     +int rtems_flashdev_deregister(
>     +  const char *flash_path
>     +)
>     +{
>     +  rtems_filesystem_eval_path_context_t ctx;
>     +  int eval_flags = RTEMS_FS_FOLLOW_LINK;
>     +  const rtems_filesystem_location_info_t *currentloc =
>     +    rtems_filesystem_eval_path_start( &ctx , flash_path,
>     eval_flags );
>     +
>     +  return IMFS_rmnod(NULL, currentloc);
>     +}
>     +
>      static int rtems_flashdev_do_init(
>        rtems_flashdev *flash,
>        void ( *destroy )( rtems_flashdev *flash )
>     @@ -503,7 +544,7 @@ static int rtems_flashdev_do_init(
>        flash->get_page_info_by_offset = NULL;
>        flash->get_page_info_by_index = NULL;
>        flash->get_page_count = NULL;
>     -  flash->get_write_block_size = NULL;
>     +  flash->get_min_write_size = NULL;
>        flash->region_table = NULL;
>        return 0;
>      }
>     @@ -520,7 +561,6 @@ void rtems_flashdev_destroy_and_free(
>     rtems_flashdev *flash )
>        }
>        rtems_recursive_mutex_destroy( &( flash->mutex ) );
>        free( flash );
>     -  flash = NULL;
>
>
> Unrelated change?

Ouch, yes


>        return;
>      }
>
>     @@ -602,13 +642,12 @@ static int rtems_flashdev_get_abs_addr(
>      static int rtems_flashdev_update_and_return(
>        rtems_libio_t *iop,
>        int status,
>     -  size_t count,
>     -  off_t new_offset
>     +  size_t count
>      )
>      {
>        /* Update offset and return */
>        if ( status == 0 ) {
>     -    iop->offset = new_offset;
>     +    iop->offset += count;
>          return count;
>        } else {
>          rtems_set_errno_and_return_minus_one( status );
>     @@ -847,7 +886,7 @@ static int
>     rtems_flashdev_ioctl_get_page_count( rtems_flashdev *flash, void *arg
>        }
>      }
>
>     -static int rtems_flashdev_ioctl_get_write_block_size(
>     +static int rtems_flashdev_ioctl_get_min_write_size(
>        rtems_flashdev *flash,
>        void *arg
>      )
>     @@ -855,10 +894,10 @@ static int
>     rtems_flashdev_ioctl_get_write_block_size(
>        if ( arg == NULL ) {
>          rtems_set_errno_and_return_minus_one( EINVAL );
>        }
>     -  if ( flash->get_write_block_size == NULL ) {
>     +  if ( flash->get_min_write_size == NULL ) {
>          return 0;
>        } else {
>     -    return ( *flash->get_write_block_size )( flash, ( (size_t *)
>     arg ) );
>     +    return ( *flash->get_min_write_size )( flash, ( (size_t *)
>     arg ) );
>        }
>      }
>
>     diff --git a/cpukit/include/dev/flash/flashdev.h
>     b/cpukit/include/dev/flash/flashdev.h
>     index 6244d38e3a..f6973df2a3 100644
>     --- a/cpukit/include/dev/flash/flashdev.h
>     +++ b/cpukit/include/dev/flash/flashdev.h
>     @@ -142,7 +142,7 @@ typedef struct rtems_flashdev rtems_flashdev;
>       *
>       * @param[out] count Integer containing the minimum write size.
>       */
>     -#define RTEMS_FLASHDEV_IOCTL_GET_WRITE_BLOCK_SIZE 10
>     +#define RTEMS_FLASHDEV_IOCTL_GET_MIN_WRITE_SIZE 10
>
>      /**
>       * @brief The maximum number of region limited file descriptors
>     @@ -354,14 +354,14 @@ struct rtems_flashdev {
>         * @brief Call to device driver to return the minimum write
>     size of the
>         * flash device.
>         *
>     -   * @param[out] write_block_size The minimum write size of the
>     flash device.
>     +   * @param[out] min_write_size The minimum write size of the
>     flash device.
>         *
>         * @retval 0 Success.
>         * @retval non-zero Failed.
>         */
>     -  int ( *get_write_block_size )(
>     +  int ( *get_min_write_size )(
>          rtems_flashdev *flashdev,
>     -    size_t *write_block_size
>     +    size_t *min_write_size
>        );
>
>        /**
>     @@ -441,6 +441,20 @@ int rtems_flashdev_register(
>        const char *flash_path
>      );
>
>     +/**
>     + * @brief Deregister the flash device.
>     + *
>     + * This function removes the node allocated for the flash device.
>     + *
>     + * @param[in] flash_path The path to the flash device file.
>     + *
>     + * @retval 0 Successful operation.
>     + * @retval non-zero Failed operation.
>     + */
>     +int rtems_flashdev_deregister(
>     +  const char *flash_path
>     +);
>     +
>      /**
>       * @brief Destroys the flash device.
>       *
>     diff --git a/cpukit/libmisc/shell/main_flashdev.c
>     b/cpukit/libmisc/shell/main_flashdev.c
>     index 516c77ae27..5851adfeef 100644
>     --- a/cpukit/libmisc/shell/main_flashdev.c
>     +++ b/cpukit/libmisc/shell/main_flashdev.c
>     @@ -40,7 +40,7 @@ static int flashdev_shell_get_jedec_id(char
>     *dev_path);
>      static int flashdev_shell_get_page_by_off(char *dev_path, int
>     argc, char *argv[]);
>      static int flashdev_shell_get_page_by_idx(char *dev_path, int
>     argc, char *argv[]);
>      static int flashdev_shell_get_pg_count(char *dev_path);
>     -static int flashdev_shell_get_wb_size(char *dev_path);
>     +static int flashdev_shell_get_min_write_size(char *dev_path);
>
>      static int flashdev_shell_ioctl_value(
>        char *dev_path,
>     @@ -67,7 +67,7 @@ static const char rtems_flashdev_shell_usage [] =
>        "   -o <address>          Print the page information of page at
>     address\n"
>        "   -i <index>            Print the page information of page at
>     index\n"
>        "   -p                    Print the number of pages\n"
>     -  "   -b                    Print the write block size\n"
>     +  "   -b                    Print the min. write size\n"
>        "   -h                    Print this help\n";
>
>
>     @@ -98,23 +98,23 @@ static int rtems_flashdev_shell_main( int
>     argc, char *argv[] ) {
>              /* Erase */
>              return flashdev_shell_erase(dev_path, argc, &argv[i]);
>            case ('t'):
>     -        /* Flash Type */
>     +        /* Get flash Type */
>              return flashdev_shell_get_type(dev_path);
>            case ('d'):
>     -        /* JEDEC Id */
>     +        /* Get JEDEC Id */
>              return flashdev_shell_get_jedec_id(dev_path);
>            case ('o'):
>     -        /* Page info by offset */
>     +        /* Get page info by offset */
>              return flashdev_shell_get_page_by_off(dev_path, argc,
>     &argv[i]);
>            case ('i'):
>     -        /* Page info by index */
>     +        /* Get page info by index */
>              return flashdev_shell_get_page_by_idx(dev_path, argc,
>     &argv[i]);
>            case ('p'):
>     -        /* Page count */
>     +        /* Get page count */
>              return flashdev_shell_get_pg_count(dev_path);
>            case ('b'):
>     -        /* Write block size */
>     -        return flashdev_shell_get_wb_size(dev_path);
>     +        /* Get min write size */
>     +        return flashdev_shell_get_min_write_size(dev_path);
>            case ('h'):
>            default:
>              /* Help */
>     @@ -480,7 +480,7 @@ static int flashdev_shell_get_pg_count( char
>     *dev_path )
>        return 0;
>      }
>
>     -static int flashdev_shell_get_wb_size( char *dev_path )
>     +static int flashdev_shell_get_min_write_size( char *dev_path )
>      {
>        size_t ret;
>        int status;
>     @@ -488,16 +488,16 @@ static int flashdev_shell_get_wb_size( char
>     *dev_path )
>        /* Get Write Block Size */
>        status = flashdev_shell_ioctl_value(
>          dev_path,
>     -    RTEMS_FLASHDEV_IOCTL_GET_WRITE_BLOCK_SIZE,
>     +    RTEMS_FLASHDEV_IOCTL_GET_MIN_WRITE_SIZE,
>          &ret
>        );
>
>        /* Print Write Block Size */
>        if (status) {
>     -    printf("Failed to get write block size\n");
>     +    printf("Failed to get min write size\n");
>          return status;
>        } else {
>     -    printf("Write block size: 0x%zx\n", ret);
>     +    printf("Min. Write size: 0x%zx\n", ret);
>        }
>        return 0;
>      }
>     diff --git a/testsuites/libtests/flashdev01/init.c
>     b/testsuites/libtests/flashdev01/init.c
>     index 30af3f33c1..dc174daa62 100644
>     --- a/testsuites/libtests/flashdev01/init.c
>     +++ b/testsuites/libtests/flashdev01/init.c
>     @@ -34,14 +34,15 @@
>      #include <fcntl.h>
>      #include <sys/ioctl.h>
>
>     -#define TEST_NAME_LENGTH 10
>     +
>
>      #define TEST_DATA_SIZE (PAGE_SIZE * PAGE_COUNT)
>      #define PAGE_COUNT 16
>      #define PAGE_SIZE 128
>     -#define WB_SIZE 1
>     +#define MIN_WRITE_SIZE 1
>
>      const char rtems_test_name[] = "FLASHDEV 1";
>     +const char test_string[] = "My test string!";
>
>      static void run_test(void);
>
>     @@ -53,89 +54,134 @@ static void run_test(void) {
>        rtems_flashdev* flash;
>        int status;
>        char* read_data;
>     +  size_t bytes_read;
>        rtems_flashdev_region e_args;
>        rtems_flashdev_ioctl_page_info pg_info;
>        rtems_flashdev_region region;
>        uint32_t jedec;
>        int page_count;
>        int type;
>     -  size_t wb_size;
>     +  size_t min_write_size_in[] = {1,8,16};
>     +  size_t min_write_size_out;
>     +  const char flash_path[] = "/dev/flashdev0";
>     +
>     +  for ( int loop = 0; loop <= 2; loop++)
>     +  {
>     +    /* Initalize the flash device driver and flashdev */
>     +    flash = test_flashdev_init(min_write_size_in[loop]);
>     +    rtems_test_assert(flash != NULL);
>     +
>     +    /* Register the flashdev as a device */
>     +    status = rtems_flashdev_register(flash, flash_path);
>     +    rtems_test_assert(!status);
>     +
>     +    /* Open the flashdev */
>     +    file = fopen(flash_path, "r+");
>     +    rtems_test_assert(file != NULL);
>     +
>     +    /* Adjust the file buffering */
>     +    status = setvbuf(file, NULL, _IOFBF, min_write_size_in[loop]);
>     +    rtems_test_assert(!status);
>     +
>     +    fd = fileno(file);
>     +
>     +    /* Read data from flash */
>     +    read_data = fgets(buff, TEST_DATA_SIZE, file);
>     +    rtems_test_assert(read_data != NULL);
>     +
>     +    /* Fseek to start of flash and read again */
>     +    status = fseek(file, 0x0, SEEK_SET);
>     +    rtems_test_assert(!status);
>     +    bytes_read = fread(buff, 1, TEST_DATA_SIZE, file);
>     +    rtems_test_assert(bytes_read == TEST_DATA_SIZE);
>     +
>     +    /* Fseek to start of flash */
>     +    status = fseek(file, 0x0, SEEK_SET);
>     +    rtems_test_assert(!status);
>     +
>     +    /* Write the test name to the flash */
>     +    status = fwrite(test_string, 1, sizeof(test_string), file);
>     +    rtems_test_assert(status == sizeof(test_string));
>     +
>     +    /* Fseek to start of flash and read again */
>     +    status = fseek(file, 0x0, SEEK_SET);
>     +    rtems_test_assert(!status);
>     +    fgets(buff, TEST_DATA_SIZE, file);
>     +    rtems_test_assert(!strncmp(buff, test_string,
>     sizeof(test_string)));
>     +
>     +    /* Test Erasing */
>     +    e_args.offset = 0x0;
>     +    e_args.size = PAGE_SIZE;
>     +    status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_ERASE, &e_args);
>     +    rtems_test_assert(!status);
>     +
>     +    fseek(file, 0x0, SEEK_SET);
>     +    fgets(buff, TEST_DATA_SIZE, file);
>     +    rtems_test_assert(buff[0] == 0);
>     +
>     +    /* Test getting JEDEC ID */
>     +    status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_GET_JEDEC_ID, &jedec);
>     +    rtems_test_assert(!status);
>     +    rtems_test_assert(jedec == 0x00ABCDEF);
>     +
>     +    /* Test getting flash type */
>     +    status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_GET_TYPE, &type);
>     +    rtems_test_assert(!status);
>     +    rtems_test_assert(type == RTEMS_FLASHDEV_NOR);
>     +
>     +    /* Test getting page info from offset */
>     +    pg_info.location = PAGE_SIZE + PAGE_SIZE/2;
>     +
>     +    status = ioctl(fd,
>     RTEMS_FLASHDEV_IOCTL_GET_PAGEINFO_BY_OFFSET, &pg_info);
>     +    rtems_test_assert(!status);
>     +    rtems_test_assert(pg_info.page_info.offset == PAGE_SIZE);
>     +    rtems_test_assert(pg_info.page_info.size == PAGE_SIZE);
>     +
>     +    /* Test getting page info from index */
>     +    pg_info.location = 2;
>     +    status = ioctl(fd,
>     RTEMS_FLASHDEV_IOCTL_GET_PAGEINFO_BY_INDEX, &pg_info);
>     +    rtems_test_assert(!status);
>     +    rtems_test_assert(pg_info.page_info.offset == 2*PAGE_SIZE);
>     +    rtems_test_assert(pg_info.page_info.size == PAGE_SIZE);
>     +
>     +    /* Test getting page count */
>     +    status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_GET_PAGE_COUNT,
>     &page_count);
>     +    rtems_test_assert(!status);
>     +    rtems_test_assert(page_count == PAGE_COUNT);
>     +
>     +    /* Test getting min write size */
>     +    status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_GET_MIN_WRITE_SIZE,
>     &min_write_size_out);
>     +    rtems_test_assert(!status);
>     +    rtems_test_assert(0 == memcmp(&min_write_size_out,
>     &min_write_size_in[loop] , sizeof(size_t)));
>     +
>     +    /* Close the file handle */
>     +    status = fclose(file);
>     +    rtems_test_assert(!status);
>     +
>     +    /* Deregister path */
>     +    status = rtems_flashdev_deregister(flash_path);
>     +    rtems_test_assert(!status);
>     +
>     +    test_flashdev_deinit(flash);
>     +  }
>
>        /* Initalize the flash device driver and flashdev */
>     -  flash = test_flashdev_init();
>     +  flash = test_flashdev_init(min_write_size_in[1]);
>        rtems_test_assert(flash != NULL);
>
>        /* Register the flashdev as a device */
>     -  status = rtems_flashdev_register(flash, "dev/flashdev0");
>     +  status = rtems_flashdev_register(flash, flash_path);
>        rtems_test_assert(!status);
>
>        /* Open the flashdev */
>     -  file = fopen("dev/flashdev0", "r+");
>     +  file = fopen(flash_path, "r+");
>        rtems_test_assert(file != NULL);
>     -  fd = fileno(file);
>     -
>     -  /* Read data from flash */
>     -  read_data = fgets(buff, TEST_DATA_SIZE, file);
>     -  rtems_test_assert(read_data != NULL);
>     -
>     -  /* Fseek to start of flash */
>     -  status = fseek(file, 0x0, SEEK_SET);
>     -  rtems_test_assert(!status);
>     -
>     -  /* Write the test name to the flash */
>     -  status = fwrite(rtems_test_name, TEST_NAME_LENGTH, 1, file);
>     -  rtems_test_assert(status == 1);
>     -
>     -  /* Fseek to start of flash and read again */
>     -  status = fseek(file, 0x0, SEEK_SET);
>     -  rtems_test_assert(!status);
>     -  fgets(buff, TEST_DATA_SIZE, file);
>     -  rtems_test_assert(!strncmp(buff, rtems_test_name,
>     TEST_NAME_LENGTH));
>
>     -  /* Test Erasing */
>     -  e_args.offset = 0x0;
>     -  e_args.size = PAGE_SIZE;
>     -  status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_ERASE, &e_args);
>     +  /* Adjust the file buffering */
>     +  status = setvbuf(file, NULL, _IOFBF, min_write_size_in[1]);
>        rtems_test_assert(!status);
>
>     -  fseek(file, 0x0, SEEK_SET);
>     -  fgets(buff, TEST_DATA_SIZE, file);
>     -  rtems_test_assert(buff[0] == 0);
>     -
>     -  /* Test getting JEDEC ID */
>     -  status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_GET_JEDEC_ID, &jedec);
>     -  rtems_test_assert(!status);
>     -  rtems_test_assert(jedec == 0x00ABCDEF);
>     -
>     -  /* Test getting flash type */
>     -  status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_GET_TYPE, &type);
>     -  rtems_test_assert(!status);
>     -  rtems_test_assert(type == RTEMS_FLASHDEV_NOR);
>     -
>     -  /* Test getting page info from offset */
>     -  pg_info.location = PAGE_SIZE + PAGE_SIZE/2;
>     -
>     -  status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_GET_PAGEINFO_BY_OFFSET,
>     &pg_info);
>     -  rtems_test_assert(!status);
>     -  rtems_test_assert(pg_info.page_info.offset == PAGE_SIZE);
>     -  rtems_test_assert(pg_info.page_info.size == PAGE_SIZE);
>     -
>     -  /* Test getting page info from index */
>     -  pg_info.location = 2;
>     -  status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_GET_PAGEINFO_BY_INDEX,
>     &pg_info);
>     -  rtems_test_assert(!status);
>     -  rtems_test_assert(pg_info.page_info.offset == 2*PAGE_SIZE);
>     -  rtems_test_assert(pg_info.page_info.size == PAGE_SIZE);
>     -
>     -  /* Test getting page count */
>     -  status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_GET_PAGE_COUNT,
>     &page_count);
>     -  rtems_test_assert(!status);
>     -  rtems_test_assert(page_count == PAGE_COUNT);
>     -
>     -  /* Test getting write block size */
>     -  status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_GET_WRITE_BLOCK_SIZE,
>     &wb_size);
>     -  rtems_test_assert(!status);
>     -  rtems_test_assert(wb_size == WB_SIZE);
>     +  fd = fileno(file);
>
>        /* Test Regions */
>        region.offset = 0x400;
>     @@ -143,10 +189,16 @@ static void run_test(void) {
>        status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_SET_REGION, &region);
>        rtems_test_assert(!status);
>
>     +  /* Test read within then region */
>     +  status = fseek(file, 0x0, SEEK_SET);
>     +  rtems_test_assert(!status);
>     +  bytes_read = fread(buff, 1, 0x200, file);
>     +  rtems_test_assert(bytes_read == 0x200);
>     +
>        /* Test read to larger then region */
>        fseek(file, 0x0, SEEK_SET);
>        read_data = fgets(buff, 2048, file);
>     -  rtems_test_assert(read_data == NULL);
>     +  rtems_test_assert(buff[0] == 0);
>
>        /* Test fseek outside of region */
>        status = fseek(file, 0x201, SEEK_SET);
>     @@ -154,11 +206,21 @@ static void run_test(void) {
>
>        /* Write to base unset region and check the writes location */
>        fseek(file, 0x0, SEEK_SET);
>     -  fwrite("HELLO WORLD", 11, 1, file);
>     +  fwrite("HELLO WORLD!!!!!", 1, 16, file);
>        ioctl(fd, RTEMS_FLASHDEV_IOCTL_UNSET_REGION, NULL);
>        fseek(file, 0x400, SEEK_SET);
>     -  fgets(buff, 11, file);
>     -  rtems_test_assert(strncmp(buff, "HELLO WORLD", 11));
>     +  fgets(buff, 16, file);
>     +  rtems_test_assert(strncmp(buff, "HELLO WORLD!!!!!", 16));
>     +
>     +  /* Close the file handle */
>     +  status = fclose(file);
>     +  rtems_test_assert(!status);
>     +
>     +  /* Deregister path */
>     +  status = rtems_flashdev_deregister(flash_path);
>     +  rtems_test_assert(!status);
>     +
>     +  test_flashdev_deinit(flash);
>      }
>
>      static void Init(rtems_task_argument arg)
>     diff --git a/testsuites/libtests/flashdev01/test_flashdev.c
>     b/testsuites/libtests/flashdev01/test_flashdev.c
>     index d97f5d8145..0022210668 100644
>     --- a/testsuites/libtests/flashdev01/test_flashdev.c
>     +++ b/testsuites/libtests/flashdev01/test_flashdev.c
>     @@ -33,11 +33,12 @@
>      #define TEST_DATA_SIZE (PAGE_SIZE * PAGE_COUNT)
>      #define PAGE_COUNT 16
>      #define PAGE_SIZE 128
>     -#define WB_SIZE 1
>      #define MAX_NUM_REGIONS 48
>      #define BITALLOC_SIZE 32
>      #define NUM_BITALLOC ((MAX_NUM_REGIONS + BITALLOC_SIZE - 1) /
>     BITALLOC_SIZE)
>
>     +static size_t g_min_write_size = 0;
>     +
>      /**
>       * This flash device driver is for testing flashdev
>       * API calls.
>     @@ -68,9 +69,9 @@ int test_flashdev_get_page_count(
>        int *page_count
>      );
>
>     -int test_flashdev_get_wb_size(
>     +int test_flashdev_get_min_write_size(
>        rtems_flashdev *flash,
>     -  size_t *write_block_size
>     +  size_t *min_write_size
>      );
>
>      uint32_t test_flashdev_get_jedec_id(
>     @@ -102,7 +103,7 @@ int test_flashdev_erase(
>        size_t count
>      );
>
>     -/* Find page info by offset handler */
>     +/* Get page info by offset handler */
>      int test_flashdev_get_page_by_off(
>        rtems_flashdev *flash,
>        off_t search_offset,
>     @@ -115,7 +116,7 @@ int test_flashdev_get_page_by_off(
>        return 0;
>      }
>
>     -/* Find page by index handler */
>     +/* Get page info by index handler */
>      int test_flashdev_get_page_by_index(
>        rtems_flashdev *flash,
>        off_t search_index,
>     @@ -128,7 +129,7 @@ int test_flashdev_get_page_by_index(
>        return 0;
>      }
>
>     -/* Page count handler */
>     +/* Get page count handler */
>      int test_flashdev_get_page_count(
>        rtems_flashdev *flash,
>        int *page_count
>     @@ -138,13 +139,13 @@ int test_flashdev_get_page_count(
>        return 0;
>      }
>
>     -/* Write block size handler */
>     -int test_flashdev_get_wb_size(
>     +/* Get min. write size handler */
>     +int test_flashdev_get_min_write_size(
>        rtems_flashdev *flash,
>     -  size_t *write_block_size
>     +  size_t *min_write_size
>      )
>      {
>     -  *write_block_size = WB_SIZE;
>     +  *min_write_size = g_min_write_size;
>        return 0;
>      }
>
>     @@ -230,8 +231,13 @@ int test_flashdev_erase(
>      }
>
>      /* Initialize Flashdev and underlying driver. */
>     -rtems_flashdev* test_flashdev_init(void)
>     +rtems_flashdev* test_flashdev_init(size_t min_write_size)
>      {
>     +  if (0 == min_write_size) {
>     +    return NULL;
>     +  }
>     +
>     +  g_min_write_size = min_write_size;
>        rtems_flashdev *flash =
>     rtems_flashdev_alloc_and_init(sizeof(rtems_flashdev));
>
>        if (flash == NULL) {
>     @@ -268,8 +274,32 @@ rtems_flashdev* test_flashdev_init(void)
>        flash->get_page_info_by_offset = &test_flashdev_get_page_by_off;
>        flash->get_page_info_by_index = &test_flashdev_get_page_by_index;
>        flash->get_page_count = &test_flashdev_get_page_count;
>     -  flash->get_write_block_size = &test_flashdev_get_wb_size;
>     +  flash->get_min_write_size = &test_flashdev_get_min_write_size;
>        flash->region_table = ftable;
>
>        return flash;
>      }
>     +
>     +/* Free Flashdev and underlying driver. */
>     +void test_flashdev_deinit(
>     +  rtems_flashdev* flash
>     +)
>     +{
>     +  if (NULL != flash)
>     +  {
>     +    if (NULL != flash->driver)
>     +    {
>     +      free(flash->region_table);
>     +    }
>     +    if (NULL != flash->driver)
>     +    {
>     +      test_flashdev* flash_driver = (test_flashdev*) flash->driver;
>     +      if (NULL != flash_driver->data)
>     +      {
>     +        free( flash_driver->data);
>     +      }
>     +      free(flash->driver);
>     +    }
>     +    rtems_flashdev_destroy_and_free(flash);
>     +  }
>     +}
>     diff --git a/testsuites/libtests/flashdev01/test_flashdev.h
>     b/testsuites/libtests/flashdev01/test_flashdev.h
>     index 8b03959c42..ad995854ea 100644
>     --- a/testsuites/libtests/flashdev01/test_flashdev.h
>     +++ b/testsuites/libtests/flashdev01/test_flashdev.h
>     @@ -30,6 +30,8 @@
>
>      #include <dev/flash/flashdev.h>
>
>     -rtems_flashdev* test_flashdev_init(void);
>     +rtems_flashdev* test_flashdev_init(size_t min_write_size);
>     +
>     +void test_flashdev_deinit(rtems_flashdev* flash);
>
>      #endif /* __TEST_FLASHDEV_H */
>     -- 
>     2.34.1
>
>     _______________________________________________
>     devel mailing list
>     devel at rtems.org
>     http://lists.rtems.org/mailman/listinfo/devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20240104/773fd8ea/attachment-0001.htm>


More information about the devel mailing list