From f60b4349e39f6789c0336a1f2a161ffd51d7226f Mon Sep 17 00:00:00 2001 From: seteiro Date: Tue, 3 Nov 2026 10:11:27 +0800 Subject: [PATCH 1/6] drivers/spi: add QEMU virtual SPI loopback bus for utest (#11972) Register a pure-software SPI bus (default name spi2) with memcpy loopback xfer so components.drivers.spi.loopback passes on qemu-vexpress-a9 without a PL022 model. Fix utest include/CPPPATH and align Kconfig/rtconfig bus name. Verified: scons + qemu utest_run components.drivers.spi.loopback PASSED. Fixes #11972 (SPI/QEMU checklist item). --- bsp/qemu-vexpress-a9/.config | 12 ++- bsp/qemu-vexpress-a9/rtconfig.h | 15 ++++ components/drivers/spi/utest/Kconfig | 3 + components/drivers/spi/utest/SConscript | 5 +- components/drivers/spi/utest/spi_virt_bus.c | 93 +++++++++++++++++++++ 5 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 components/drivers/spi/utest/spi_virt_bus.c diff --git a/bsp/qemu-vexpress-a9/.config b/bsp/qemu-vexpress-a9/.config index 018ef71802ad..651d89915ce2 100644 --- a/bsp/qemu-vexpress-a9/.config +++ b/bsp/qemu-vexpress-a9/.config @@ -436,7 +436,7 @@ CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE=y # # CONFIG_RT_USING_RYM is not set # CONFIG_RT_USING_ULOG is not set -# CONFIG_RT_USING_UTEST is not set +CONFIG_RT_USING_UTEST=y # CONFIG_RT_USING_VAR_EXPORT is not set CONFIG_RT_USING_RESOURCE_ID=y CONFIG_RT_USING_ADT=y @@ -478,7 +478,15 @@ CONFIG_RT_PAGE_MAX_ORDER=11 # # RT-Thread Utestcases # -# CONFIG_RT_USING_UTESTCASES is not set +CONFIG_RT_USING_UTESTCASES=y + CONFIG_RT_UTEST_SPI_LOOPBACK=y + CONFIG_RT_UTEST_SPI_LOOPBACK_BUS_NAME="spi2" + CONFIG_RT_UTEST_SPI_LOOPBACK_DEV_NAME="spi_loop" + CONFIG_RT_UTEST_SPI_LOOPBACK_DATA_SIZE=512 + CONFIG_RT_UTEST_SPI_LOOPBACK_MAX_HZ=10000000 + # CONFIG_RT_UTEST_SPI_LOOPBACK_API_SMOKE is not set + CONFIG_RT_UTEST_SPI_LOOPBACK_TIMEOUT=60 + # CONFIG_RT_UTEST_SPI_FLASH is not set # end of RT-Thread Utestcases # diff --git a/bsp/qemu-vexpress-a9/rtconfig.h b/bsp/qemu-vexpress-a9/rtconfig.h index 3ca7223f4078..6c132276fc31 100644 --- a/bsp/qemu-vexpress-a9/rtconfig.h +++ b/bsp/qemu-vexpress-a9/rtconfig.h @@ -225,6 +225,21 @@ #define RT_USING_PIN /* end of Device Drivers */ +/* Utilities */ + +#define RT_USING_UTESTCASES +#define RT_USING_UTEST +#define UTEST_THR_STACK_SIZE 8192 +#define UTEST_THR_PRIORITY 20 +#define RT_UTEST_MAX_OPTIONS 64 +#define RT_UTEST_SPI_LOOPBACK +#define RT_UTEST_SPI_LOOPBACK_BUS_NAME "spi2" +#define RT_UTEST_SPI_LOOPBACK_DEV_NAME "spi_loop" +#define RT_UTEST_SPI_LOOPBACK_DATA_SIZE 512 +#define RT_UTEST_SPI_LOOPBACK_MAX_HZ 10000000 +#define RT_UTEST_SPI_LOOPBACK_TIMEOUT 60 +/* end of Utilities */ + /* C/C++ and POSIX layer */ /* ISO-ANSI C layer */ diff --git a/components/drivers/spi/utest/Kconfig b/components/drivers/spi/utest/Kconfig index 1638916ab5b7..d16a0e4e987e 100644 --- a/components/drivers/spi/utest/Kconfig +++ b/components/drivers/spi/utest/Kconfig @@ -15,6 +15,9 @@ if RT_UTEST_SPI_LOOPBACK config RT_UTEST_SPI_LOOPBACK_BUS_NAME string "SPI bus name for loopback test" default "spi2" + help + On BSPs without a real SPI controller (e.g. qemu-vexpress-a9) the + virtual loopback bus "spi2" is registered by spi_virt_bus.c. config RT_UTEST_SPI_LOOPBACK_DEV_NAME string "Temporary SPI device name for loopback test" diff --git a/components/drivers/spi/utest/SConscript b/components/drivers/spi/utest/SConscript index 8b7a049e5e2e..05b1196c1382 100644 --- a/components/drivers/spi/utest/SConscript +++ b/components/drivers/spi/utest/SConscript @@ -3,10 +3,11 @@ from building import * cwd = GetCurrentDir() src = [] -CPPPATH = [cwd, cwd + '/..', cwd + '/../sfud/inc'] +CPPPATH = [cwd, cwd + '/..', cwd + '/../../include', cwd + '/../sfud/inc', + cwd + '/../../../utilities/utest'] if GetDepend(['RT_UTEST_SPI_LOOPBACK']): - src += ['spi_loopback_tc.c'] + src += ['spi_loopback_tc.c', 'spi_virt_bus.c'] if GetDepend(['RT_UTEST_SPI_FLASH']): src += ['spi_flash_tc.c'] diff --git a/components/drivers/spi/utest/spi_virt_bus.c b/components/drivers/spi/utest/spi_virt_bus.c new file mode 100644 index 000000000000..a603880eb563 --- /dev/null +++ b/components/drivers/spi/utest/spi_virt_bus.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-11-02 add SPI virtual loopback bus for utest + * + * A pure-software SPI bus that feeds MOSI data back to MISO. It lets the + * SPI loopback utest run on BSPs (such as qemu-vexpress-a9) which have no + * real SPI controller wired to external pins. + */ + +#include +#include +#include +#include + +#ifdef RT_UTEST_SPI_LOOPBACK + +#ifndef RT_UTEST_SPI_LOOPBACK_BUS_NAME +#define RT_UTEST_SPI_LOOPBACK_BUS_NAME "spi2" +#endif + +#define SPI_VIRT_BUS_NAME RT_UTEST_SPI_LOOPBACK_BUS_NAME +#define SPI_VIRT_BUS_MAX_HZ 10000000 +#define SPI_VIRT_BUS_DEFAULT_HZ 1000000 + +static struct rt_spi_bus spi_virt_bus; + +static rt_err_t spi_virt_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration) +{ + if (configuration->max_hz == 0) + { + configuration->max_hz = SPI_VIRT_BUS_DEFAULT_HZ; + } + + if (configuration->max_hz > SPI_VIRT_BUS_MAX_HZ) + { + configuration->max_hz = SPI_VIRT_BUS_MAX_HZ; + } + + device->config = *configuration; + device->config.usage_freq = configuration->max_hz; + + return RT_EOK; +} + +static rt_ssize_t spi_virt_xfer(struct rt_spi_device *device, struct rt_spi_message *message) +{ + rt_size_t i; + + if (message == RT_NULL) + { + return 0; + } + + if (message->send_buf != RT_NULL && message->recv_buf != RT_NULL) + { + rt_memcpy(message->recv_buf, message->send_buf, message->length); + } + else if (message->send_buf != RT_NULL) + { + /* TX-only: drop the data, nothing to verify. */ + } + else if (message->recv_buf != RT_NULL) + { + /* RX-only: fill with a deterministic pattern. */ + rt_uint8_t *rx = (rt_uint8_t *)message->recv_buf; + + for (i = 0; i < message->length; i++) + { + rx[i] = (rt_uint8_t)(0xA5 + i); + } + } + + return (rt_ssize_t)message->length; +} + +static const struct rt_spi_ops spi_virt_ops = +{ + .configure = spi_virt_configure, + .xfer = spi_virt_xfer, +}; + +static int spi_virt_bus_init(void) +{ + return rt_spi_bus_register(&spi_virt_bus, SPI_VIRT_BUS_NAME, &spi_virt_ops); +} +INIT_BOARD_EXPORT(spi_virt_bus_init); + +#endif /* RT_UTEST_SPI_LOOPBACK */ \ No newline at end of file From 674309bb6b3ebaf30155c41cf213a14eeebea3d6 Mon Sep 17 00:00:00 2001 From: seteiro Date: Tue, 3 Nov 2026 10:18:22 +0800 Subject: [PATCH 2/6] drivers/spi: fix clang-format violations in spi_virt_bus.c Fix the 'Check File Format and License' CI job failure: - put the spi_virt_ops initializer brace on the assignment line - add the missing newline at end of file No functional change. --- components/drivers/spi/utest/spi_virt_bus.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/drivers/spi/utest/spi_virt_bus.c b/components/drivers/spi/utest/spi_virt_bus.c index a603880eb563..82097f5c642d 100644 --- a/components/drivers/spi/utest/spi_virt_bus.c +++ b/components/drivers/spi/utest/spi_virt_bus.c @@ -78,8 +78,7 @@ static rt_ssize_t spi_virt_xfer(struct rt_spi_device *device, struct rt_spi_mess return (rt_ssize_t)message->length; } -static const struct rt_spi_ops spi_virt_ops = -{ +static const struct rt_spi_ops spi_virt_ops = { .configure = spi_virt_configure, .xfer = spi_virt_xfer, }; @@ -90,4 +89,4 @@ static int spi_virt_bus_init(void) } INIT_BOARD_EXPORT(spi_virt_bus_init); -#endif /* RT_UTEST_SPI_LOOPBACK */ \ No newline at end of file +#endif /* RT_UTEST_SPI_LOOPBACK */ From 70d9d878e335651056000e510e1bb5bf5e707558 Mon Sep 17 00:00:00 2001 From: seteiro Date: Thu, 5 Nov 2026 12:01:48 +0800 Subject: [PATCH 3/6] drivers/spi: separate virt bus Kconfig from loopback utest (#11972) Add a dedicated, default-off RT_UTEST_SPI_VIRT_BUS switch (default name spi_virt) so enabling RT_UTEST_SPI_LOOPBACK no longer compiles or registers a software SPI bus. Hardware loopback now always runs on the real controller named by RT_UTEST_SPI_LOOPBACK_BUS_NAME, while QEMU/CI targets opt in to the virtual bus explicitly. Also move the utest enablement out of the qemu-vexpress-a9 BSP defaults and into ci.attachconfig as peripheral.SPI_VIRT_LOOPBACK. --- .../.ci/attachconfig/ci.attachconfig.yml | 8 +++++ bsp/qemu-vexpress-a9/.config | 12 ++------ bsp/qemu-vexpress-a9/rtconfig.h | 15 ---------- components/drivers/spi/utest/Kconfig | 30 +++++++++++++++++-- components/drivers/spi/utest/SConscript | 5 +++- components/drivers/spi/utest/spi_virt_bus.c | 10 +++---- 6 files changed, 47 insertions(+), 33 deletions(-) diff --git a/bsp/qemu-vexpress-a9/.ci/attachconfig/ci.attachconfig.yml b/bsp/qemu-vexpress-a9/.ci/attachconfig/ci.attachconfig.yml index ee74be04f3f6..376174432001 100644 --- a/bsp/qemu-vexpress-a9/.ci/attachconfig/ci.attachconfig.yml +++ b/bsp/qemu-vexpress-a9/.ci/attachconfig/ci.attachconfig.yml @@ -24,6 +24,14 @@ peripheral.LVGL: - CONFIG_RT_USING_POSIX_SOCKET=y - ONFIG_RT_USING_LWIP=y - CONFIG_BSP_USING_LVGL=y +peripheral.SPI_VIRT_LOOPBACK: + kconfig: + - CONFIG_RT_USING_UTEST=y + - CONFIG_RT_USING_UTESTCASES=y + - CONFIG_RT_UTEST_SPI_LOOPBACK=y + - CONFIG_RT_UTEST_SPI_LOOPBACK_BUS_NAME="spi_virt" + - CONFIG_RT_UTEST_SPI_VIRT_BUS=y + - CONFIG_RT_UTEST_SPI_VIRT_BUS_NAME="spi_virt" # ------ online-packages CI ------ online-packages.tools.coremark: diff --git a/bsp/qemu-vexpress-a9/.config b/bsp/qemu-vexpress-a9/.config index 651d89915ce2..018ef71802ad 100644 --- a/bsp/qemu-vexpress-a9/.config +++ b/bsp/qemu-vexpress-a9/.config @@ -436,7 +436,7 @@ CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE=y # # CONFIG_RT_USING_RYM is not set # CONFIG_RT_USING_ULOG is not set -CONFIG_RT_USING_UTEST=y +# CONFIG_RT_USING_UTEST is not set # CONFIG_RT_USING_VAR_EXPORT is not set CONFIG_RT_USING_RESOURCE_ID=y CONFIG_RT_USING_ADT=y @@ -478,15 +478,7 @@ CONFIG_RT_PAGE_MAX_ORDER=11 # # RT-Thread Utestcases # -CONFIG_RT_USING_UTESTCASES=y - CONFIG_RT_UTEST_SPI_LOOPBACK=y - CONFIG_RT_UTEST_SPI_LOOPBACK_BUS_NAME="spi2" - CONFIG_RT_UTEST_SPI_LOOPBACK_DEV_NAME="spi_loop" - CONFIG_RT_UTEST_SPI_LOOPBACK_DATA_SIZE=512 - CONFIG_RT_UTEST_SPI_LOOPBACK_MAX_HZ=10000000 - # CONFIG_RT_UTEST_SPI_LOOPBACK_API_SMOKE is not set - CONFIG_RT_UTEST_SPI_LOOPBACK_TIMEOUT=60 - # CONFIG_RT_UTEST_SPI_FLASH is not set +# CONFIG_RT_USING_UTESTCASES is not set # end of RT-Thread Utestcases # diff --git a/bsp/qemu-vexpress-a9/rtconfig.h b/bsp/qemu-vexpress-a9/rtconfig.h index 6c132276fc31..3ca7223f4078 100644 --- a/bsp/qemu-vexpress-a9/rtconfig.h +++ b/bsp/qemu-vexpress-a9/rtconfig.h @@ -225,21 +225,6 @@ #define RT_USING_PIN /* end of Device Drivers */ -/* Utilities */ - -#define RT_USING_UTESTCASES -#define RT_USING_UTEST -#define UTEST_THR_STACK_SIZE 8192 -#define UTEST_THR_PRIORITY 20 -#define RT_UTEST_MAX_OPTIONS 64 -#define RT_UTEST_SPI_LOOPBACK -#define RT_UTEST_SPI_LOOPBACK_BUS_NAME "spi2" -#define RT_UTEST_SPI_LOOPBACK_DEV_NAME "spi_loop" -#define RT_UTEST_SPI_LOOPBACK_DATA_SIZE 512 -#define RT_UTEST_SPI_LOOPBACK_MAX_HZ 10000000 -#define RT_UTEST_SPI_LOOPBACK_TIMEOUT 60 -/* end of Utilities */ - /* C/C++ and POSIX layer */ /* ISO-ANSI C layer */ diff --git a/components/drivers/spi/utest/Kconfig b/components/drivers/spi/utest/Kconfig index d16a0e4e987e..725410558a86 100644 --- a/components/drivers/spi/utest/Kconfig +++ b/components/drivers/spi/utest/Kconfig @@ -16,8 +16,10 @@ config RT_UTEST_SPI_LOOPBACK_BUS_NAME string "SPI bus name for loopback test" default "spi2" help - On BSPs without a real SPI controller (e.g. qemu-vexpress-a9) the - virtual loopback bus "spi2" is registered by spi_virt_bus.c. + The real SPI bus the loopback test attaches to. On boards with a + wired MOSI/MISO loopback this must be the hardware controller name. + BSPs without a real SPI controller can instead enable + RT_UTEST_SPI_VIRT_BUS and point this name at the virtual bus. config RT_UTEST_SPI_LOOPBACK_DEV_NAME string "Temporary SPI device name for loopback test" @@ -51,6 +53,30 @@ config RT_UTEST_SPI_LOOPBACK_TIMEOUT endif +config RT_UTEST_SPI_VIRT_BUS + bool "SPI virtual loopback bus (software)" + select RT_USING_SPI + default n + help + Compile and register a pure software SPI bus that feeds MOSI data + back to MISO. It is meant for BSPs without a real SPI controller, + such as QEMU targets, or for CI runs that have no wired loopback. + Keep it disabled on boards with a hardware SPI controller: enabling + it would add a second bus next to the real one. + +if RT_UTEST_SPI_VIRT_BUS + +config RT_UTEST_SPI_VIRT_BUS_NAME + string "SPI virtual bus device name" + default "spi_virt" + help + Name of the software loopback bus registered by spi_virt_bus.c. + Use a dedicated name that does not collide with any real SPI + controller of the board, and set RT_UTEST_SPI_LOOPBACK_BUS_NAME + to the same value so the test attaches to it. + +endif + config RT_UTEST_SPI_FLASH bool "SPI Flash SFUD Read/Write Test" select RT_USING_SPI diff --git a/components/drivers/spi/utest/SConscript b/components/drivers/spi/utest/SConscript index 05b1196c1382..45cc98014162 100644 --- a/components/drivers/spi/utest/SConscript +++ b/components/drivers/spi/utest/SConscript @@ -7,7 +7,10 @@ CPPPATH = [cwd, cwd + '/..', cwd + '/../../include', cwd + '/../sfud/inc', cwd + '/../../../utilities/utest'] if GetDepend(['RT_UTEST_SPI_LOOPBACK']): - src += ['spi_loopback_tc.c', 'spi_virt_bus.c'] + src += ['spi_loopback_tc.c'] + +if GetDepend(['RT_UTEST_SPI_VIRT_BUS']): + src += ['spi_virt_bus.c'] if GetDepend(['RT_UTEST_SPI_FLASH']): src += ['spi_flash_tc.c'] diff --git a/components/drivers/spi/utest/spi_virt_bus.c b/components/drivers/spi/utest/spi_virt_bus.c index 82097f5c642d..39796095a308 100644 --- a/components/drivers/spi/utest/spi_virt_bus.c +++ b/components/drivers/spi/utest/spi_virt_bus.c @@ -17,13 +17,13 @@ #include #include -#ifdef RT_UTEST_SPI_LOOPBACK +#ifdef RT_UTEST_SPI_VIRT_BUS -#ifndef RT_UTEST_SPI_LOOPBACK_BUS_NAME -#define RT_UTEST_SPI_LOOPBACK_BUS_NAME "spi2" +#ifndef RT_UTEST_SPI_VIRT_BUS_NAME +#define RT_UTEST_SPI_VIRT_BUS_NAME "spi_virt" #endif -#define SPI_VIRT_BUS_NAME RT_UTEST_SPI_LOOPBACK_BUS_NAME +#define SPI_VIRT_BUS_NAME RT_UTEST_SPI_VIRT_BUS_NAME #define SPI_VIRT_BUS_MAX_HZ 10000000 #define SPI_VIRT_BUS_DEFAULT_HZ 1000000 @@ -89,4 +89,4 @@ static int spi_virt_bus_init(void) } INIT_BOARD_EXPORT(spi_virt_bus_init); -#endif /* RT_UTEST_SPI_LOOPBACK */ +#endif /* RT_UTEST_SPI_VIRT_BUS */ From f2c821a84add9a59154ff9c4fecdd3018e566c63 Mon Sep 17 00:00:00 2001 From: seteiro Date: Thu, 5 Nov 2026 13:54:37 +0800 Subject: [PATCH 4/6] cla: empty commit to retrigger license/cla check (#11979) From a96b49bba92d8a72450ba592dec48e3cab0bc12b Mon Sep 17 00:00:00 2001 From: seteiro Date: Thu, 5 Nov 2026 19:34:54 +0800 Subject: [PATCH 5/6] ci(utest): add A9 SPI loopback virt bus config (#11979) --- .github/utest/configs/components/spi.cfg | 10 ++++++++++ .github/workflows/utest_auto_run.yml | 2 ++ 2 files changed, 12 insertions(+) create mode 100644 .github/utest/configs/components/spi.cfg diff --git a/.github/utest/configs/components/spi.cfg b/.github/utest/configs/components/spi.cfg new file mode 100644 index 000000000000..f974f39afd72 --- /dev/null +++ b/.github/utest/configs/components/spi.cfg @@ -0,0 +1,10 @@ +# dependencies +CONFIG_RT_CONSOLEBUF_SIZE=1024 +CONFIG_RT_USING_CI_ACTION=y +CONFIG_RT_USING_UTEST=y +CONFIG_RT_USING_UTESTCASES=y + +CONFIG_RT_UTEST_SPI_LOOPBACK=y +CONFIG_RT_UTEST_SPI_LOOPBACK_BUS_NAME="spi_virt" +CONFIG_RT_UTEST_SPI_VIRT_BUS=y +CONFIG_RT_UTEST_SPI_VIRT_BUS_NAME="spi_virt" diff --git a/.github/workflows/utest_auto_run.yml b/.github/workflows/utest_auto_run.yml index e05a26f1a963..e2dbb82878d2 100644 --- a/.github/workflows/utest_auto_run.yml +++ b/.github/workflows/utest_auto_run.yml @@ -152,6 +152,8 @@ jobs: config_file: "components/dfs.cfg" - platform: { UTEST: "A9", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", SD_FILE: "sd.bin", KERNEL: "standard", "SMP_RUN":"" } config_file: "components/libc.cfg" + - platform: { UTEST: "A9", RTT_BSP: "bsp/qemu-vexpress-a9", QEMU_ARCH: "arm", QEMU_MACHINE: "vexpress-a9", SD_FILE: "sd.bin", KERNEL: "standard", "SMP_RUN":"" } + config_file: "components/spi.cfg" env: TEST_QEMU_ARCH: ${{ matrix.platform.QEMU_ARCH }} From c8f1188f674946d7320b6596e3232e6b3b86bdb4 Mon Sep 17 00:00:00 2001 From: seteiro Date: Fri, 6 Nov 2026 14:30:35 +0800 Subject: [PATCH 6/6] [drivers][spi] gate virtual SPI bus utest on !RT_USING_DM RT_UTEST_SPI_VIRT_BUS compiles spi_virt_bus.c, which registers a software loopback bus with rt_spi_bus_register(). That path needs no device tree node, so on a BSP that enables RT_USING_DM and RT_USING_OFW the registration fails with -RT_EINVAL when no matching DT node exists. Add "depends on !RT_USING_DM" to the option and document in help that it is only available without the device model and must stay disabled on DM based BSPs. spi_virt_bus.c is already fully wrapped in #ifdef RT_UTEST_SPI_VIRT_BUS, so no C change is needed. The A9 utest config (bsp/qemu-vexpress-a9) has RT_USING_DM disabled, and .github/utest/configs/components/spi.cfg still enables both the virt bus and the loopback test with bus name "spi_virt", so CI coverage is kept. Refs #11972 --- components/drivers/spi/utest/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/drivers/spi/utest/Kconfig b/components/drivers/spi/utest/Kconfig index 725410558a86..c4653c7e4cf7 100644 --- a/components/drivers/spi/utest/Kconfig +++ b/components/drivers/spi/utest/Kconfig @@ -55,6 +55,7 @@ endif config RT_UTEST_SPI_VIRT_BUS bool "SPI virtual loopback bus (software)" + depends on !RT_USING_DM select RT_USING_SPI default n help @@ -64,6 +65,13 @@ config RT_UTEST_SPI_VIRT_BUS Keep it disabled on boards with a hardware SPI controller: enabling it would add a second bus next to the real one. + This option is only available without the device model + (RT_USING_DM). spi_virt_bus.c registers the bus with + rt_spi_bus_register(), which needs no device tree node; on a DM + and OFW based BSP without a matching DT node that registration + fails with -RT_EINVAL. Do not enable this option on BSPs that + enable RT_USING_DM. + if RT_UTEST_SPI_VIRT_BUS config RT_UTEST_SPI_VIRT_BUS_NAME