From f29203d575ecaf693ebe17212e2cbb40fa1bfd6d Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 24 Apr 2024 14:43:45 +0200 Subject: [PATCH] tests: kernel: device: Add API sections tests Add tests for the subsystem_api to validate runtime API section checks. Signed-off-by: Pieter De Gendt --- tests/kernel/device/prj.conf | 1 + tests/kernel/device/src/abstract_driver.c | 18 +++++----- tests/kernel/device/src/abstract_driver.h | 44 +++++++++++++---------- tests/kernel/device/src/main.c | 22 +++++++++--- 4 files changed, 52 insertions(+), 33 deletions(-) diff --git a/tests/kernel/device/prj.conf b/tests/kernel/device/prj.conf index 4818bf0f5f9..8ad433f3dd0 100644 --- a/tests/kernel/device/prj.conf +++ b/tests/kernel/device/prj.conf @@ -2,3 +2,4 @@ CONFIG_ZTEST=y CONFIG_TEST_USERSPACE=y CONFIG_PM_DEVICE=y CONFIG_PM_DEVICE_RUNTIME=y +CONFIG_APPLICATION_DEFINED_SYSCALL=y diff --git a/tests/kernel/device/src/abstract_driver.c b/tests/kernel/device/src/abstract_driver.c index 1fccec62b88..5086fbaf24f 100644 --- a/tests/kernel/device/src/abstract_driver.c +++ b/tests/kernel/device/src/abstract_driver.c @@ -12,20 +12,19 @@ #define MY_DRIVER_B "my_driver_B" /* define individual driver A */ -static int my_driver_A_do_this(const struct device *device, int foo, int bar) +static int my_driver_A_do_this(const struct device *dev, int foo, int bar) { return foo + bar; } -static void my_driver_A_do_that(const struct device *device, - unsigned int *baz) +static void my_driver_A_do_that(const struct device *dev, unsigned int *baz) { *baz = 1; } -static struct subsystem_api my_driver_A_api_funcs = { +static DEVICE_API(abstract, my_driver_A_api_funcs) = { .do_this = my_driver_A_do_this, - .do_that = my_driver_A_do_that + .do_that = my_driver_A_do_that, }; int common_driver_init(const struct device *dev) @@ -34,20 +33,19 @@ int common_driver_init(const struct device *dev) } /* define individual driver B */ -static int my_driver_B_do_this(const struct device *device, int foo, int bar) +static int my_driver_B_do_this(const struct device *dev, int foo, int bar) { return foo - bar; } -static void my_driver_B_do_that(const struct device *device, - unsigned int *baz) +static void my_driver_B_do_that(const struct device *dev, unsigned int *baz) { *baz = 2; } -static struct subsystem_api my_driver_B_api_funcs = { +static DEVICE_API(abstract, my_driver_B_api_funcs) = { .do_this = my_driver_B_do_this, - .do_that = my_driver_B_do_that + .do_that = my_driver_B_do_that, }; /** diff --git a/tests/kernel/device/src/abstract_driver.h b/tests/kernel/device/src/abstract_driver.h index f14b3bb4da0..fc06b1db970 100644 --- a/tests/kernel/device/src/abstract_driver.h +++ b/tests/kernel/device/src/abstract_driver.h @@ -4,34 +4,40 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef _ABSTRACT_DRIVER_H_ +#define _ABSTRACT_DRIVER_H_ + #include #include +#include /* define subsystem common API for drivers */ -typedef int (*subsystem_do_this_t)(const struct device *device, int foo, - int bar); -typedef void (*subsystem_do_that_t)(const struct device *device, - unsigned int *baz); +typedef int (*abstract_do_this_t)(const struct device *dev, int foo, int bar); +typedef void (*abstract_do_that_t)(const struct device *dev, unsigned int *baz); -struct subsystem_api { - subsystem_do_this_t do_this; - subsystem_do_that_t do_that; +__subsystem struct abstract_driver_api { + abstract_do_this_t do_this; + abstract_do_that_t do_that; }; -static inline int subsystem_do_this(const struct device *device, int foo, - int bar) -{ - struct subsystem_api *api; +__syscall int abstract_do_this(const struct device *dev, int foo, int bar); - api = (struct subsystem_api *)device->api; - return api->do_this(device, foo, bar); +static inline int z_impl_abstract_do_this(const struct device *dev, int foo, int bar) +{ + __ASSERT_NO_MSG(DEVICE_API_IS(abstract, dev)); + + return DEVICE_API_GET(abstract, dev)->do_this(dev, foo, bar); } -static inline void subsystem_do_that(const struct device *device, - unsigned int *baz) -{ - struct subsystem_api *api; +__syscall void abstract_do_that(const struct device *dev, unsigned int *baz); - api = (struct subsystem_api *)device->api; - api->do_that(device, baz); +static inline void z_impl_abstract_do_that(const struct device *dev, unsigned int *baz) +{ + __ASSERT_NO_MSG(DEVICE_API_IS(abstract, dev)); + + DEVICE_API_GET(abstract, dev)->do_that(dev, baz); } + +#include + +#endif /* _ABSTRACT_DRIVER_H_ */ diff --git a/tests/kernel/device/src/main.c b/tests/kernel/device/src/main.c index 437f2ae056c..c70d2e2cd87 100644 --- a/tests/kernel/device/src/main.c +++ b/tests/kernel/device/src/main.c @@ -384,20 +384,20 @@ ZTEST(device, test_abstraction_driver_common) dev = device_get_binding(MY_DRIVER_A); zassert_false((dev == NULL)); - ret = subsystem_do_this(dev, foo, bar); + ret = abstract_do_this(dev, foo, bar); zassert_true(ret == (foo + bar), "common API do_this fail"); - subsystem_do_that(dev, &baz); + abstract_do_that(dev, &baz); zassert_true(baz == 1, "common API do_that fail"); /* verify driver B API has called */ dev = device_get_binding(MY_DRIVER_B); zassert_false((dev == NULL)); - ret = subsystem_do_this(dev, foo, bar); + ret = abstract_do_this(dev, foo, bar); zassert_true(ret == (foo - bar), "common API do_this fail"); - subsystem_do_that(dev, &baz); + abstract_do_that(dev, &baz); zassert_true(baz == 2, "common API do_that fail"); } @@ -413,6 +413,20 @@ ZTEST(device, test_deferred_init) zassert_true(device_is_ready(FAKEDEFERDRIVER0)); } +ZTEST(device, test_device_api) +{ + const struct device *dev; + + dev = device_get_binding(MY_DRIVER_A); + zexpect_true(DEVICE_API_IS(abstract, dev)); + + dev = device_get_binding(MY_DRIVER_B); + zexpect_true(DEVICE_API_IS(abstract, dev)); + + dev = device_get_binding(DUMMY_NOINIT); + zexpect_false(DEVICE_API_IS(abstract, dev)); +} + ZTEST_USER(device, test_deferred_init_user) { int ret;