diff --git a/sys/bhp/Kconfig b/sys/bhp/Kconfig index 2b9a5c7b599f..aa4403069cc6 100644 --- a/sys/bhp/Kconfig +++ b/sys/bhp/Kconfig @@ -22,4 +22,9 @@ config MODULE_BHP_EVENT depends on MODULE_EVENT depends on MODULE_BHP +config MODULE_BHP_MSG + bool "Enable message based Bottom Half Processor implementation" + depends on MODULE_CORE_MSG + depends on MODULE_BHP + endmenu diff --git a/sys/bhp/Makefile.dep b/sys/bhp/Makefile.dep new file mode 100644 index 000000000000..ba85a80fdeed --- /dev/null +++ b/sys/bhp/Makefile.dep @@ -0,0 +1,7 @@ +ifneq (,$(filter bhp_event,$(USEMODULE))) + USEMODULE += event +endif + +ifneq (,$(filter bhp_msg,$(USEMODULE))) + USEMODULE += core_msg +endif diff --git a/sys/bhp/Makefile.include b/sys/bhp/Makefile.include index 200c49238fba..da43c0c8e0a7 100644 --- a/sys/bhp/Makefile.include +++ b/sys/bhp/Makefile.include @@ -1 +1,2 @@ PSEUDOMODULES += bhp_event +PSEUDOMODULES += bhp_msg diff --git a/sys/bhp/msg.c b/sys/bhp/msg.c new file mode 100644 index 000000000000..fe5da25befd3 --- /dev/null +++ b/sys/bhp/msg.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2022 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup sys_bhp + * @{ + * + * @file + * @brief Message based Bottom Half Processor implementation + * + * @author José I. Alamos + * + * @} + */ +#include +#include "bhp/msg.h" + +void bhp_msg_init(bhp_msg_t *bhp_msg, bhp_cb_t cb, void *ctx) +{ + bhp_set_cb(&bhp_msg->bhp, cb, ctx); + bhp_msg->pid = KERNEL_PID_UNDEF; + bhp_msg->msg.type = BHP_MSG_BH_REQUEST; + bhp_msg->msg.content.ptr = &bhp_msg->bhp; +} + +void bhp_msg_isr_cb(void *bhp_msg_ctx) +{ + bhp_msg_t *bhp_msg = bhp_msg_ctx; + + assert(bhp_msg->pid != KERNEL_PID_UNDEF); + msg_send(&bhp_msg->msg, bhp_msg->pid); +} diff --git a/sys/include/bhp/msg.h b/sys/include/bhp/msg.h new file mode 100644 index 000000000000..e4acad17d2d0 --- /dev/null +++ b/sys/include/bhp/msg.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2022 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @defgroup sys_bhp_msg Message based implementation of Bottom Half Processor + * @ingroup sys_bhp + * + * @note Offloading ISRs with messages is in general a terrible idea, + * because messages can be lost. Use it with care or prefer + * alternatives such as @ref sys_bhp_event. + * + * @brief Bottom Half Processor module for generic IRQ offloading using + * messages. + * @{ + * + * @author José I. Alamos + */ + +#ifndef BHP_MSG_H +#define BHP_MSG_H + +#include "msg.h" +#include "thread.h" +#include "bhp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The message type to trigger Bottom Half Processing + */ +#define BHP_MSG_BH_REQUEST 0x1539 + +/** + * @brief Message based Bottom Half Processor descriptor + */ +typedef struct { + bhp_t bhp; /**< Bottom Half Processor descriptor */ + kernel_pid_t pid; /**< PID of the thread that process the Bottom Half Processor */ + msg_t msg; /**< Message containing the Bottom Half Processing request */ +} bhp_msg_t; + +/** + * @brief Init a Bottom Half Processor to be used with messages + * @post the target PID is set to @ref KERNEL_PID_UNDEF + * + * @param[in] bhp_msg The message based Bottom Half Processor descriptor + * @param[in] cb Bottom Half Processor callback + * @param[in] ctx Context of @p cb + */ +void bhp_msg_init(bhp_msg_t *bhp_msg, bhp_cb_t cb, void *ctx); + +/** + * @brief Message based Bottom Half Processor ISR callback + * To be called from ISR in order to trigger the Bottom Half Processor. + * This sends a message with type @ref BHP_MSG_BH_REQUEST to the + * target thread, which should process the event accordingly by calling + * @ref bhp_msg_handler. + * + * @note This function asserts that the target PID is valid. Therefore, make sure + * to call @ref bhp_msg_claim_thread beforehand. + * + * @param[in] bhp_msg_ctx Pointer to the message based Bottom Half Processor + * (@ref bhp_msg_t) + * Bottom Half Processor. + */ +void bhp_msg_isr_cb(void *bhp_msg_ctx); + +/** + * @brief Claim a thread with a message queue to be used as Bottom Half Processor. + * + * @param[in] bhp_msg The message based Bottom Half Processor descriptor + * @param[in] pid PID of the target thread + */ +static inline void bhp_msg_claim_thread(bhp_msg_t *bhp_msg, kernel_pid_t pid) +{ + bhp_msg->pid = pid; +} + +/** + * @brief Handle a Bottom Half Processor message with type @ref + * BHP_MSG_BH_REQUEST. + * This function will call @ref bhp_irq_handler internally. + * + * @note This function asserts that the message type is @ref BHP_MSG_BH_REQUEST. + * + * @param[in] msg Pointer to the Bottom Half Processor message. + */ +static inline void bhp_msg_handler(msg_t *msg) +{ + assert(msg->type == BHP_MSG_BH_REQUEST); + bhp_irq_handler(msg->content.ptr); +} + +#ifdef __cplusplus +} +#endif + +#endif /* BHP_MSG_H */ +/** @} */ diff --git a/tests/unittests/tests-bhp_msg/Makefile b/tests/unittests/tests-bhp_msg/Makefile new file mode 100644 index 000000000000..48422e909a47 --- /dev/null +++ b/tests/unittests/tests-bhp_msg/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/tests/unittests/tests-bhp_msg/Makefile.include b/tests/unittests/tests-bhp_msg/Makefile.include new file mode 100644 index 000000000000..c3828184f262 --- /dev/null +++ b/tests/unittests/tests-bhp_msg/Makefile.include @@ -0,0 +1 @@ +USEMODULE += bhp_msg diff --git a/tests/unittests/tests-bhp_msg/tests-bhp_msg.c b/tests/unittests/tests-bhp_msg/tests-bhp_msg.c new file mode 100644 index 000000000000..1efd70fb5c23 --- /dev/null +++ b/tests/unittests/tests-bhp_msg/tests-bhp_msg.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2022 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @{ + * + * @file + */ +#include +#include +#include + +#include "bhp/msg.h" +#include "embUnit.h" + +#include "unittests-constants.h" +#include "tests-bhp_msg.h" + +static bhp_msg_t bhp_msg; +static int canary; +static int *ctx; + +static char _stack[THREAD_STACKSIZE_DEFAULT]; + +static void bhp_handler(void *arg) +{ + TEST_ASSERT(arg == ctx); + canary = TEST_INT; +} + +static void set_up(void) +{ + memset(&bhp_msg, '\0', sizeof(bhp_msg)); + canary = 0; + bhp_msg_init(&bhp_msg, bhp_handler, ctx); +} + +static void test_bhp_msg__init(void) +{ + TEST_ASSERT(bhp_msg.pid == KERNEL_PID_UNDEF); + TEST_ASSERT(bhp_msg.msg.type == BHP_MSG_BH_REQUEST); + TEST_ASSERT(bhp_msg.bhp.irq_handler == bhp_handler); + TEST_ASSERT(bhp_msg.bhp.ctx == ctx); +} + +static void *_event_loop(void *arg) +{ + (void) arg; + while (1) { + msg_t msg; + msg_receive(&msg); + if (msg.type == BHP_MSG_BH_REQUEST) { + bhp_msg_handler(&msg); + } + } + + return NULL; +} + +static void test_bhp_msg__claim(void) +{ + TEST_ASSERT_EQUAL_INT(0, bhp_msg.pid); + bhp_msg_claim_thread(&bhp_msg, TEST_UINT8); + TEST_ASSERT_EQUAL_INT(TEST_UINT8, bhp_msg.pid); +} + +static void test_bhp_msg__cb(void) +{ + kernel_pid_t pid = thread_create(_stack, sizeof(_stack), THREAD_PRIORITY_MAIN - 1, + THREAD_CREATE_STACKTEST, _event_loop, NULL, + "bhp_msg"); + + bhp_msg_claim_thread(&bhp_msg, pid); + TEST_ASSERT_EQUAL_INT(0, canary); + bhp_msg_isr_cb(&bhp_msg); + TEST_ASSERT_EQUAL_INT(TEST_INT, canary); +} + +Test *tests_bhp_msg_tests(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(test_bhp_msg__init), + new_TestFixture(test_bhp_msg__claim), + new_TestFixture(test_bhp_msg__cb), + }; + + EMB_UNIT_TESTCALLER(bhp_msg_tests, set_up, NULL, fixtures); + + return (Test *)&bhp_msg_tests; +} + +void tests_bhp_msg(void) +{ + TESTS_RUN(tests_bhp_msg_tests()); +} +/** @} */ diff --git a/tests/unittests/tests-bhp_msg/tests-bhp_msg.h b/tests/unittests/tests-bhp_msg/tests-bhp_msg.h new file mode 100644 index 000000000000..481c24e36d0b --- /dev/null +++ b/tests/unittests/tests-bhp_msg/tests-bhp_msg.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2022 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @addtogroup unittests + * @{ + * + * @file + * @brief Unittests for the @ref bhp_msg module + * + * @author José I. Álamos + */ +#ifndef TESTS_BHP_MSG_H +#define TESTS_BHP_MSG_H + +#include "embUnit.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The entry point of this test suite. + */ +void tests_bhp_msg(void); + +#ifdef __cplusplus +} +#endif + +#endif /* TESTS_BHP_MSG_H */ +/** @} */