diff --git a/include/kernel.h b/include/kernel.h index a2720a6a873..ba4111a6617 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -2865,6 +2865,12 @@ struct k_msgq { #define K_MSGQ_INITIALIZER DEPRECATED_MACRO _K_MSGQ_INITIALIZER +struct k_msgq_attrs { + size_t msg_size; + u32_t max_msgs; + u32_t used_msgs; +}; + /** * INTERNAL_HIDDEN @endcond */ @@ -2985,6 +2991,19 @@ __syscall void k_msgq_purge(struct k_msgq *q); */ __syscall u32_t k_msgq_num_free_get(struct k_msgq *q); +/** + * @brief Get basic attributes of a message queue. + * + * This routine fetches basic attributes of message queue into attr argument. + * + * @param q Address of the message queue. + * @param attrs pointer to message queue attribute structure. + * + * @return N/A + */ +__syscall void k_msgq_get_attrs(struct k_msgq *q, struct k_msgq_attrs *attrs); + + static inline u32_t _impl_k_msgq_num_free_get(struct k_msgq *q) { return q->max_msgs - q->used_msgs; diff --git a/kernel/msg_q.c b/kernel/msg_q.c index 9e8f7e2c607..90867d0a29f 100644 --- a/kernel/msg_q.c +++ b/kernel/msg_q.c @@ -136,6 +136,25 @@ _SYSCALL_HANDLER(k_msgq_put, msgq_p, data, timeout) } #endif +void _impl_k_msgq_get_attrs(struct k_msgq *q, struct k_msgq_attrs *attrs) +{ + attrs->msg_size = q->msg_size; + attrs->max_msgs = q->max_msgs; + attrs->used_msgs = q->used_msgs; +} + +#ifdef CONFIG_USERSPACE +_SYSCALL_HANDLER(k_msgq_get_attrs, msgq_p, attrs) +{ + struct k_msgq *q = (struct k_msgq *)msgq_p; + + _SYSCALL_OBJ(q, K_OBJ_MSGQ); + _SYSCALL_MEMORY_WRITE(attrs, sizeof(struct k_msgq_attrs)); + _impl_k_msgq_get_attrs(q, (struct k_msgq_attrs *) attrs); + return 0; +} +#endif + int _impl_k_msgq_get(struct k_msgq *q, void *data, s32_t timeout) { __ASSERT(!_is_in_isr() || timeout == K_NO_WAIT, ""); diff --git a/tests/kernel/msgq/msgq_api/src/main.c b/tests/kernel/msgq/msgq_api/src/main.c index 87453c6d2ee..8842d23a9b9 100644 --- a/tests/kernel/msgq/msgq_api/src/main.c +++ b/tests/kernel/msgq/msgq_api/src/main.c @@ -18,6 +18,7 @@ extern void test_msgq_isr(void); extern void test_msgq_put_fail(void); extern void test_msgq_get_fail(void); extern void test_msgq_purge_when_put(void); +extern void test_msgq_attrs_get(void); extern struct k_msgq kmsgq; extern struct k_msgq msgq; @@ -37,6 +38,7 @@ void test_main(void) ztest_unit_test(test_msgq_isr), ztest_user_unit_test(test_msgq_put_fail), ztest_user_unit_test(test_msgq_get_fail), + ztest_user_unit_test(test_msgq_attrs_get), ztest_user_unit_test(test_msgq_purge_when_put)); ztest_run_test_suite(test_msgq_api); } diff --git a/tests/kernel/msgq/msgq_api/src/test_msgq_attrs.c b/tests/kernel/msgq/msgq_api/src/test_msgq_attrs.c new file mode 100644 index 00000000000..6a5dba34b73 --- /dev/null +++ b/tests/kernel/msgq/msgq_api/src/test_msgq_attrs.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @addtogroup t_msgq_api + * @{ + * @defgroup t_msgq_attrs test_msgq_attrs + * @brief TestPurpose: verify zephyr msgq get attributes API. + * @} + */ + +#include "test_msgq.h" +extern struct k_msgq msgq; +static char __aligned(4) tbuffer[MSG_SIZE * MSGQ_LEN]; +static u32_t send_buf[MSGQ_LEN] = { MSG0, MSG1 }; +static u32_t rec_buf[MSGQ_LEN] = { MSG0, MSG1 }; + +void test_msgq_attrs_get(void) +{ + int ret; + struct k_msgq_attrs attrs; + + k_msgq_init(&msgq, tbuffer, MSG_SIZE, MSGQ_LEN); + + k_msgq_get_attrs(&msgq, &attrs); + zassert_equal(attrs.used_msgs, 0, NULL); + + /*fill the queue to full*/ + for (int i = 0; i < MSGQ_LEN; i++) { + ret = k_msgq_put(&msgq, (void *)&send_buf[i], K_NO_WAIT); + zassert_equal(ret, 0, NULL); + } + + k_msgq_get_attrs(&msgq, &attrs); + zassert_equal(attrs.used_msgs, MSGQ_LEN, NULL); + + for (int i = 0; i < MSGQ_LEN; i++) { + ret = k_msgq_get(&msgq, (void *)&rec_buf[i], K_NO_WAIT); + zassert_equal(ret, 0, NULL); + } + + k_msgq_get_attrs(&msgq, &attrs); + zassert_equal(attrs.used_msgs, 0, NULL); +}