diff options
author | Aaron Nyholm <aaron.nyholm@southerninnovation.com> | 2023-03-30 16:56:29 +1100 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2023-05-16 12:48:23 +1000 |
commit | 8e3ab340518b9297fdb4a968f748ba25a509d740 (patch) | |
tree | f8eeadb5de735e6e8bb06c9140767b9259eead7a | |
parent | libmisc/shell: Add flashdev command (diff) | |
download | rtems-8e3ab340518b9297fdb4a968f748ba25a509d740.tar.bz2 |
testsuites/libtests: Add test for flashdev
-rw-r--r-- | spec/build/testsuites/libtests/flashdev01.yml | 20 | ||||
-rw-r--r-- | spec/build/testsuites/libtests/grp.yml | 2 | ||||
-rw-r--r-- | testsuites/libtests/flashdev01/flashdev01.doc | 11 | ||||
-rw-r--r-- | testsuites/libtests/flashdev01/flashdev01.scn | 2 | ||||
-rw-r--r-- | testsuites/libtests/flashdev01/init.c | 190 | ||||
-rw-r--r-- | testsuites/libtests/flashdev01/test_flashdev.c | 275 | ||||
-rw-r--r-- | testsuites/libtests/flashdev01/test_flashdev.h | 35 |
7 files changed, 535 insertions, 0 deletions
diff --git a/spec/build/testsuites/libtests/flashdev01.yml b/spec/build/testsuites/libtests/flashdev01.yml new file mode 100644 index 0000000000..c943caa2e7 --- /dev/null +++ b/spec/build/testsuites/libtests/flashdev01.yml @@ -0,0 +1,20 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +build-type: test-program +cflags: [] +copyrights: +- Copyright (C) 2023 Aaron Nyholm (Southern Innovation) +cppflags: [] +cxxflags: [] +enabled-by: true +features: c cprogram +includes: [] +ldflags: [] +links: [] +source: +- testsuites/libtests/flashdev01/init.c +- testsuites/libtests/flashdev01/test_flashdev.c +stlib: [] +target: testsuites/libtests/flashdev01.exe +type: build +use-after: [] +use-before: [] diff --git a/spec/build/testsuites/libtests/grp.yml b/spec/build/testsuites/libtests/grp.yml index 8f2cadb890..30965e5b2c 100644 --- a/spec/build/testsuites/libtests/grp.yml +++ b/spec/build/testsuites/libtests/grp.yml @@ -125,6 +125,8 @@ links: - role: build-dependency uid: fcntl - role: build-dependency + uid: flashdev01 +- role: build-dependency uid: flashdisk01 - role: build-dependency uid: flockfile diff --git a/testsuites/libtests/flashdev01/flashdev01.doc b/testsuites/libtests/flashdev01/flashdev01.doc new file mode 100644 index 0000000000..0638a5a842 --- /dev/null +++ b/testsuites/libtests/flashdev01/flashdev01.doc @@ -0,0 +1,11 @@ +This file describes the directives and concepts testd by this test set. + +test set name: flashdev01 + +directives: + + TBD + +concepts: + + - Ensure that the flashdev driver API works. diff --git a/testsuites/libtests/flashdev01/flashdev01.scn b/testsuites/libtests/flashdev01/flashdev01.scn new file mode 100644 index 0000000000..809ff3cd80 --- /dev/null +++ b/testsuites/libtests/flashdev01/flashdev01.scn @@ -0,0 +1,2 @@ +*** BEGIN OF TEST FLASHDEV 1 *** +*** END OF TEST FLASHDEV 1 *** diff --git a/testsuites/libtests/flashdev01/init.c b/testsuites/libtests/flashdev01/init.c new file mode 100644 index 0000000000..8896ad796c --- /dev/null +++ b/testsuites/libtests/flashdev01/init.c @@ -0,0 +1,190 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (C) 2023 Aaron Nyholm + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "tmacros.h" + +#include "test_flashdev.h" + +#include <stdio.h> +#include <stdlib.h> +#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 + +const char rtems_test_name[] = "FLASHDEV 1"; + +static void run_test(void); + +static void run_test(void) { + + char buff[TEST_DATA_SIZE] = {0}; + FILE *file; + int fd; + rtems_flashdev* flash; + int status; + char* read_data; + rtems_flashdev_region e_args; + rtems_flashdev_ioctl_page_info pg_info; + rtems_flashdev_region region; + uint32_t jedec; + size_t page_count; + int type; + size_t wb_size; + + /* Initalize the flash device driver and flashdev */ + flash = test_flashdev_init(); + rtems_test_assert(flash != NULL); + + /* Register the flashdev as a device */ + status = rtems_flashdev_register(flash, "dev/flashdev0"); + rtems_test_assert(!status); + + /* Open the flashdev */ + file = fopen("dev/flashdev0", "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); + 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_JEDEC_ID, &jedec); + rtems_test_assert(!status); + rtems_test_assert(jedec == 0x00ABCDEF); + + /* Test getting flash type */ + status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_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_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_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_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_WRITE_BLOCK_SIZE, &wb_size); + rtems_test_assert(!status); + rtems_test_assert(wb_size == WB_SIZE); + + /* Test Regions */ + region.offset = 0x400; + region.size = 0x200; + status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_REGION_SET, ®ion); + rtems_test_assert(!status); + + /* Test read to larger then region */ + fseek(file, 0x0, SEEK_SET); + read_data = fgets(buff, 2048, file); + rtems_test_assert(read_data == NULL); + + /* Test fseek outside of region */ + status = fseek(file, 0x201, SEEK_SET); + rtems_test_assert(status); + + /* Write to base unset region and check the writes location */ + fseek(file, 0x0, SEEK_SET); + fwrite("HELLO WORLD", 11, 1, file); + ioctl(fd, RTEMS_FLASHDEV_IOCTL_REGION_UNSET, NULL); + fseek(file, 0x400, SEEK_SET); + fgets(buff, 11, file); + rtems_test_assert(strncmp(buff, "HELLO WORLD", 11)); +} + +static void Init(rtems_task_argument arg) +{ + TEST_BEGIN(); + + run_test(); + + TEST_END(); + rtems_test_exit(0); +} + +#define CONFIGURE_MICROSECONDS_PER_TICK 2000 + +#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER + +#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 7 + +#define CONFIGURE_MAXIMUM_TASKS 2 + +#define CONFIGURE_MAXIMUM_SEMAPHORES 1 + +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_INIT + +#include <rtems/confdefs.h> diff --git a/testsuites/libtests/flashdev01/test_flashdev.c b/testsuites/libtests/flashdev01/test_flashdev.c new file mode 100644 index 0000000000..708d708977 --- /dev/null +++ b/testsuites/libtests/flashdev01/test_flashdev.c @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2023 Aaron Nyholm + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "test_flashdev.h" + +#include <stdlib.h> +#include <string.h> + +#include <rtems/seterr.h> + +#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) + +/** + * This flash device driver is for testing flashdev + * API calls. + */ +typedef struct test_flashdev { + char* data; + uint32_t jedec_id; + uint32_t bit_allocator[NUM_BITALLOC]; + rtems_flashdev_region regions[MAX_NUM_REGIONS]; +} test_flashdev; + +int test_flashdev_page_by_off( + rtems_flashdev *flash, + off_t search_offset, + off_t *page_offset, + size_t *page_size +); + +int test_flashdev_page_by_index( + rtems_flashdev *flash, + off_t search_index, + off_t *page_offset, + size_t *page_size +); + +int test_flashdev_page_count( + rtems_flashdev *flash, + int *page_count +); + +int test_flashdev_wb_size( + rtems_flashdev *flash, + size_t *write_block_size +); + +uint32_t test_flashdev_jedec_id( + rtems_flashdev* flash +); + +int test_flashdev_type( + rtems_flashdev* flash, + rtems_flashdev_flash_type* type +); + +int test_flashdev_read( + rtems_flashdev* flash, + uintptr_t offset, + size_t count, + void* buffer +); + +int test_flashdev_write( + rtems_flashdev* flash, + uintptr_t offset, + size_t count, + const void* buffer +); + +int test_flashdev_erase( + rtems_flashdev* flash, + uintptr_t offset, + size_t count +); + +/* Find page info by offset handler */ +int test_flashdev_page_by_off( + rtems_flashdev *flash, + off_t search_offset, + off_t *page_offset, + size_t *page_size +) +{ + *page_offset = search_offset - (search_offset%PAGE_SIZE); + *page_size = PAGE_SIZE; + return 0; +} + +/* Find page by index handler */ +int test_flashdev_page_by_index( + rtems_flashdev *flash, + off_t search_index, + off_t *page_offset, + size_t *page_size +) +{ + *page_offset = search_index * PAGE_SIZE; + *page_size = PAGE_SIZE; + return 0; +} + +/* Page count handler */ +int test_flashdev_page_count( + rtems_flashdev *flash, + int *page_count +) +{ + *page_count = PAGE_COUNT; + return 0; +} + +/* Write block size handler */ +int test_flashdev_wb_size( + rtems_flashdev *flash, + size_t *write_block_size +) +{ + *write_block_size = WB_SIZE; + return 0; +} + +/* JEDEC ID handler, this would normally require a READID + * call to the physical flash device. + */ +uint32_t test_flashdev_jedec_id( + rtems_flashdev* flash +) +{ + test_flashdev* driver = flash->driver; + return driver->jedec_id; +} + +/* Function to identify what kind of flash is attached. */ +int test_flashdev_type( + rtems_flashdev *flash, + rtems_flashdev_flash_type *type +) +{ + *type = RTEMS_FLASHDEV_NOR; + return 0; +} + +/* Read flash call. Any offset or count protections are + * required to be done in the driver function. */ +int test_flashdev_read( + rtems_flashdev* flash, + uintptr_t offset, + size_t count, + void* buffer +) +{ + test_flashdev* driver = flash->driver; + + if (offset + count > TEST_DATA_SIZE) { + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + memcpy(buffer, &driver->data[offset], count); + return 0; +} + +/* Write Flash call. Any offset or count protections are + * required to be done in the driver function. */ +int test_flashdev_write( + rtems_flashdev* flash, + uintptr_t offset, + size_t count, + const void* buffer +) +{ + test_flashdev* driver = flash->driver; + + if (offset + count > TEST_DATA_SIZE) { + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + memcpy(&driver->data[offset], buffer, count); + return 0; +} + +/* Erase Flash call. Any offset or count protections are + * required to be done in the driver function. */ +int test_flashdev_erase( + rtems_flashdev* flash, + uintptr_t offset, + size_t count +) +{ + test_flashdev* driver = flash->driver; + + if (offset + count > TEST_DATA_SIZE) { + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + if (offset%PAGE_SIZE || count%PAGE_SIZE) { + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + memset(&driver->data[offset], 0, count); + return 0; +} + +/* Initialize Flashdev and underlying driver. */ +rtems_flashdev* test_flashdev_init(void) +{ + rtems_flashdev *flash = rtems_flashdev_alloc_and_init(sizeof(rtems_flashdev)); + + if (flash == NULL) { + return NULL; + } + + test_flashdev* flash_driver = calloc(1, sizeof(test_flashdev)); + + if (flash_driver == NULL) { + rtems_flashdev_destroy_and_free(flash); + return NULL; + } + + flash_driver->data = calloc(1, TEST_DATA_SIZE); + if (flash_driver->data == NULL) { + free(flash_driver); + rtems_flashdev_destroy_and_free(flash); + return NULL; + } + + flash_driver->jedec_id = 0x00ABCDEF; + + rtems_flashdev_region_table *ftable = calloc(1, sizeof(rtems_flashdev_region_table)); + ftable->max_regions = MAX_NUM_REGIONS; + ftable->regions = flash_driver->regions; + ftable->bit_allocator = flash_driver->bit_allocator; + + flash->driver = flash_driver; + flash->read = &test_flashdev_read; + flash->write = &test_flashdev_write; + flash->erase = &test_flashdev_erase; + flash->jedec_id = &test_flashdev_jedec_id; + flash->flash_type = &test_flashdev_type; + flash->page_info_by_offset = &test_flashdev_page_by_off; + flash->page_info_by_index = &test_flashdev_page_by_index; + flash->page_count = &test_flashdev_page_count; + flash->write_block_size = &test_flashdev_wb_size; + flash->region_table = ftable; + + return flash; +} diff --git a/testsuites/libtests/flashdev01/test_flashdev.h b/testsuites/libtests/flashdev01/test_flashdev.h new file mode 100644 index 0000000000..8b03959c42 --- /dev/null +++ b/testsuites/libtests/flashdev01/test_flashdev.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2023 Aaron Nyholm + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __TEST_FLASHDEV_H +#define __TEST_FLASHDEV_H + +#include <dev/flash/flashdev.h> + +rtems_flashdev* test_flashdev_init(void); + +#endif /* __TEST_FLASHDEV_H */ |