diff --git a/tests/arch/common/semihost/CMakeLists.txt b/tests/arch/common/semihost/CMakeLists.txt new file mode 100644 index 00000000000..9ff54202b0c --- /dev/null +++ b/tests/arch/common/semihost/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(semihost) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/arch/common/semihost/prj.conf b/tests/arch/common/semihost/prj.conf new file mode 100644 index 00000000000..071acb7c66f --- /dev/null +++ b/tests/arch/common/semihost/prj.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_SEMIHOST=y diff --git a/tests/arch/common/semihost/src/main.c b/tests/arch/common/semihost/src/main.c new file mode 100644 index 00000000000..34e6f06ab7b --- /dev/null +++ b/tests/arch/common/semihost/src/main.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022, Commonwealth Scientific and Industrial Research + * Organisation (CSIRO) ABN 41 687 119 230. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +static void test_file_ops(void) +{ + const char *test_file = "./test.bin"; + uint8_t w_buffer[16] = { 1, 2, 3, 4, 5 }; + uint8_t r_buffer[16]; + long read, fd; + + /* Open in write mode */ + fd = semihost_open(test_file, SEMIHOST_OPEN_WB); + zassert_true(fd > 0, "Bad handle (%d)", fd); + zassert_equal(semihost_flen(fd), 0, "File not empty"); + + /* Write some data */ + zassert_equal(semihost_write(fd, w_buffer, sizeof(w_buffer)), 0, "Write failed"); + zassert_equal(semihost_flen(fd), sizeof(w_buffer), "Size not updated"); + zassert_equal(semihost_write(fd, w_buffer, sizeof(w_buffer)), 0, "Write failed"); + zassert_equal(semihost_flen(fd), 2 * sizeof(w_buffer), "Size not updated"); + + /* Reading should fail in this mode */ + read = semihost_read(fd, r_buffer, sizeof(r_buffer)); + zassert_equal(read, -EIO, "Read from write-only file"); + + /* Close the file */ + zassert_equal(semihost_close(fd), 0, "Close failed"); + + /* Open the same file again for reading */ + fd = semihost_open(test_file, SEMIHOST_OPEN_RB); + zassert_true(fd > 0, "Bad handle (%d)", fd); + zassert_equal(semihost_flen(fd), 2 * sizeof(w_buffer), "Data not preserved"); + + /* Check reading data */ + read = semihost_read(fd, r_buffer, sizeof(r_buffer)); + zassert_equal(read, sizeof(r_buffer), "Read failed %d", read); + zassert_mem_equal(r_buffer, w_buffer, sizeof(r_buffer), "Data not read"); + read = semihost_read(fd, r_buffer, sizeof(r_buffer)); + zassert_equal(read, sizeof(r_buffer), "Read failed"); + zassert_mem_equal(r_buffer, w_buffer, sizeof(r_buffer), "Data not read"); + + /* Read past end of file */ + read = semihost_read(fd, r_buffer, sizeof(r_buffer)); + zassert_equal(read, -EIO, "Read past end of file"); + + /* Seek to file offset */ + zassert_equal(semihost_seek(fd, 1), 0, "Seek failed"); + + /* Read from offset */ + read = semihost_read(fd, r_buffer, sizeof(r_buffer) - 1); + zassert_equal(read, sizeof(r_buffer) - 1, "Read failed"); + zassert_mem_equal(r_buffer, w_buffer + 1, sizeof(r_buffer) - 1, "Data not read"); + + /* Close the file */ + zassert_equal(semihost_close(fd), 0, "Close failed"); + + /* Opening again in write mode should erase the file */ + fd = semihost_open(test_file, SEMIHOST_OPEN_WB); + zassert_true(fd > 0, "Bad handle (%d)", fd); + zassert_equal(semihost_flen(fd), 0, "File not empty"); + zassert_equal(semihost_close(fd), 0, "Close failed"); +} + +void test_main(void) +{ + ztest_test_suite(semihost, + ztest_unit_test(test_file_ops)); + ztest_run_test_suite(semihost); +} diff --git a/tests/arch/common/semihost/testcase.yaml b/tests/arch/common/semihost/testcase.yaml new file mode 100644 index 00000000000..93ac528a282 --- /dev/null +++ b/tests/arch/common/semihost/testcase.yaml @@ -0,0 +1,4 @@ +tests: + arch.common.semihost: + arch_allow: arm arm64 riscv32 riscv64 + filter: CONFIG_QEMU_TARGET