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 <pieter.degendt@basalte.be>
This commit is contained in:
Pieter De Gendt 2024-04-24 14:43:45 +02:00 committed by Benjamin Cabé
commit f29203d575
4 changed files with 52 additions and 33 deletions

View file

@ -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

View file

@ -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,
};
/**

View file

@ -4,34 +4,40 @@
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ABSTRACT_DRIVER_H_
#define _ABSTRACT_DRIVER_H_
#include <zephyr/ztest.h>
#include <zephyr/device.h>
#include <zephyr/sys/check.h>
/* 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 <syscalls/abstract_driver.h>
#endif /* _ABSTRACT_DRIVER_H_ */

View file

@ -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;