lib/cmsis_rtos_v2: Implement support for Message Queue APIs
These APIs provide message queue functionality like create, put and get. Signed-off-by: Rajavardhan Gundi <rajavardhan.gundi@intel.com>
This commit is contained in:
parent
00ffaed189
commit
27f4cd2356
4 changed files with 276 additions and 0 deletions
|
@ -12,6 +12,7 @@ zephyr_library_sources_ifdef(
|
|||
mutex.c
|
||||
semaphore.c
|
||||
mempool.c
|
||||
msgq.c
|
||||
)
|
||||
|
||||
zephyr_library_link_libraries(CMSIS)
|
||||
|
|
|
@ -59,4 +59,11 @@ config CMSIS_V2_MEM_SLAB_MAX_COUNT
|
|||
range 0 255
|
||||
help
|
||||
Mention maximum number of memory slabs in CMSIS RTOS V2 compliant application.
|
||||
|
||||
config CMSIS_V2_MSGQ_MAX_COUNT
|
||||
int "Maximum message queue count in CMSIS RTOS V2 application"
|
||||
default 5
|
||||
range 0 255
|
||||
help
|
||||
Mention maximum number of message queues in CMSIS RTOS V2 compliant application.
|
||||
endif
|
||||
|
|
261
lib/cmsis_rtos_v2/msgq.c
Normal file
261
lib/cmsis_rtos_v2/msgq.c
Normal file
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <kernel_structs.h>
|
||||
#include "wrapper.h"
|
||||
|
||||
K_MEM_SLAB_DEFINE(cv2_msgq_slab, sizeof(struct cv2_msgq),
|
||||
CONFIG_CMSIS_V2_MSGQ_MAX_COUNT, 4);
|
||||
|
||||
static const osMessageQueueAttr_t init_msgq_attrs = {
|
||||
.name = "ZephyrMsgQ",
|
||||
.attr_bits = 0,
|
||||
.cb_mem = NULL,
|
||||
.cb_size = 0,
|
||||
.mq_mem = NULL,
|
||||
.mq_size = 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create and Initialize Message queue.
|
||||
*/
|
||||
osMessageQueueId_t osMessageQueueNew(uint32_t msg_count, uint32_t msg_size,
|
||||
const osMessageQueueAttr_t *attr)
|
||||
{
|
||||
struct cv2_msgq *msgq;
|
||||
|
||||
if (k_is_in_isr()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (attr == NULL) {
|
||||
attr = &init_msgq_attrs;
|
||||
}
|
||||
|
||||
if (k_mem_slab_alloc(&cv2_msgq_slab, (void **)&msgq, 100) == 0) {
|
||||
(void)memset(msgq, 0, sizeof(struct cv2_msgq));
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (attr->mq_mem == NULL) {
|
||||
msgq->pool = k_calloc(msg_count, msg_size);
|
||||
if (msgq->pool == NULL) {
|
||||
k_mem_slab_free(&cv2_msgq_slab, (void *) &msgq);
|
||||
return NULL;
|
||||
}
|
||||
msgq->is_dynamic_allocation = TRUE;
|
||||
} else {
|
||||
msgq->pool = attr->mq_mem;
|
||||
msgq->is_dynamic_allocation = FALSE;
|
||||
}
|
||||
|
||||
k_msgq_init(&msgq->z_msgq, msgq->pool, msg_size, msg_count);
|
||||
memcpy(msgq->name, attr->name, 16);
|
||||
|
||||
return (osMessageQueueId_t)(msgq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Put a message to a Queue.
|
||||
*/
|
||||
osStatus_t osMessageQueuePut(osMessageQueueId_t msgq_id, const void *msg_ptr,
|
||||
uint8_t msg_prio, uint32_t timeout)
|
||||
{
|
||||
struct cv2_msgq *msgq = (struct cv2_msgq *)msgq_id;
|
||||
int retval;
|
||||
|
||||
ARG_UNUSED(msg_prio);
|
||||
|
||||
if (msgq == NULL) {
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
||||
/* Can be called from ISRs only if timeout is set to 0 */
|
||||
if (timeout > 0 && k_is_in_isr()) {
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
||||
if (timeout == 0) {
|
||||
retval = k_msgq_put(&msgq->z_msgq, (void *)msg_ptr, K_NO_WAIT);
|
||||
} else if (timeout == osWaitForever) {
|
||||
retval = k_msgq_put(&msgq->z_msgq, (void *)msg_ptr, K_FOREVER);
|
||||
} else {
|
||||
retval = k_msgq_put(&msgq->z_msgq, (void *)msg_ptr,
|
||||
__ticks_to_ms(timeout));
|
||||
}
|
||||
|
||||
if (retval == 0) {
|
||||
return osOK;
|
||||
} else if (retval == -EAGAIN) {
|
||||
return osErrorTimeout;
|
||||
} else {
|
||||
return osErrorResource;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a message or Wait for a Message from a Queue.
|
||||
*/
|
||||
osStatus_t osMessageQueueGet(osMessageQueueId_t msgq_id, void *msg_ptr,
|
||||
uint8_t *msg_prio, uint32_t timeout)
|
||||
{
|
||||
struct cv2_msgq *msgq = (struct cv2_msgq *)msgq_id;
|
||||
int retval;
|
||||
|
||||
ARG_UNUSED(msg_prio);
|
||||
|
||||
if (msgq == NULL) {
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
||||
/* Can be called from ISRs only if timeout is set to 0 */
|
||||
if (timeout > 0 && k_is_in_isr()) {
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
||||
if (timeout == 0) {
|
||||
retval = k_msgq_get(&msgq->z_msgq, msg_ptr, K_NO_WAIT);
|
||||
} else if (timeout == osWaitForever) {
|
||||
retval = k_msgq_get(&msgq->z_msgq, msg_ptr, K_FOREVER);
|
||||
} else {
|
||||
retval = k_msgq_get(&msgq->z_msgq, msg_ptr,
|
||||
__ticks_to_ms(timeout));
|
||||
}
|
||||
|
||||
if (retval == 0) {
|
||||
return osOK;
|
||||
} else if (retval == -EAGAIN) {
|
||||
return osErrorTimeout;
|
||||
} else if (retval == -ENOMSG) {
|
||||
return osErrorResource;
|
||||
}
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get maximum number of messages in a Message Queue.
|
||||
*/
|
||||
uint32_t osMessageQueueGetCapacity(osMessageQueueId_t msgq_id)
|
||||
{
|
||||
struct cv2_msgq *msgq = (struct cv2_msgq *)msgq_id;
|
||||
|
||||
if (msgq == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
return msgq->z_msgq.max_msgs;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get maximum message size in a Message Queue.
|
||||
*/
|
||||
uint32_t osMessageQueueGetMsgSize(osMessageQueueId_t msgq_id)
|
||||
{
|
||||
struct cv2_msgq *msgq = (struct cv2_msgq *)msgq_id;
|
||||
|
||||
if (msgq == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
return msgq->z_msgq.msg_size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of queued messages in a Message Queue.
|
||||
*/
|
||||
uint32_t osMessageQueueGetCount(osMessageQueueId_t msgq_id)
|
||||
{
|
||||
struct cv2_msgq *msgq = (struct cv2_msgq *)msgq_id;
|
||||
|
||||
if (msgq == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
return k_msgq_num_used_get(&msgq->z_msgq);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of available slots for messages in a Message Queue.
|
||||
*/
|
||||
uint32_t osMessageQueueGetSpace(osMessageQueueId_t msgq_id)
|
||||
{
|
||||
struct cv2_msgq *msgq = (struct cv2_msgq *)msgq_id;
|
||||
|
||||
if (msgq == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
return k_msgq_num_free_get(&msgq->z_msgq);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get name of a Message Queue object.
|
||||
*/
|
||||
const char *osMessageQueueGetName(osMessageQueueId_t msgq_id)
|
||||
{
|
||||
struct cv2_msgq *msgq = (struct cv2_msgq *)msgq_id;
|
||||
|
||||
if (!k_is_in_isr() && (msgq_id != NULL)) {
|
||||
return msgq->name;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset a Message Queue to initial empty state.
|
||||
*/
|
||||
osStatus_t osMessageQueueReset(osMessageQueueId_t msgq_id)
|
||||
{
|
||||
struct cv2_msgq *msgq = (struct cv2_msgq *)msgq_id;
|
||||
|
||||
if (msgq == NULL) {
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
||||
if (k_is_in_isr()) {
|
||||
return osErrorISR;
|
||||
}
|
||||
|
||||
/* The status code "osErrorResource" (the message queue specified by
|
||||
* parameter msgq_id is in an invalid message queue state) is not
|
||||
* supported in Zephyr.
|
||||
*/
|
||||
|
||||
k_msgq_purge(&msgq->z_msgq);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete a Message Queue object.
|
||||
*/
|
||||
osStatus_t osMessageQueueDelete(osMessageQueueId_t msgq_id)
|
||||
{
|
||||
struct cv2_msgq *msgq = (struct cv2_msgq *)msgq_id;
|
||||
|
||||
if (msgq == NULL) {
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
||||
if (k_is_in_isr()) {
|
||||
return osErrorISR;
|
||||
}
|
||||
|
||||
/* The status code "osErrorResource" (the message queue specified by
|
||||
* parameter msgq_id is in an invalid message queue state) is not
|
||||
* supported in Zephyr.
|
||||
*/
|
||||
|
||||
if (msgq->is_dynamic_allocation) {
|
||||
k_free(msgq->pool);
|
||||
}
|
||||
k_mem_slab_free(&cv2_msgq_slab, (void *)&msgq);
|
||||
|
||||
return osOK;
|
||||
}
|
|
@ -48,6 +48,13 @@ struct cv2_mslab {
|
|||
char name[16];
|
||||
};
|
||||
|
||||
struct cv2_msgq {
|
||||
struct k_msgq z_msgq;
|
||||
void *pool;
|
||||
char is_dynamic_allocation;
|
||||
char name[16];
|
||||
};
|
||||
|
||||
extern osThreadId_t get_cmsis_thread_id(k_tid_t tid);
|
||||
extern void *is_cmsis_rtos_v2_thread(void *thread_id);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue