| /* |
| * Copyright (c) 2018 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <kernel.h> |
| #include <cmsis_os.h> |
| #include <string.h> |
| |
| /** |
| * @brief Create and Initialize mail queue. |
| */ |
| osMailQId osMailCreate(const osMailQDef_t *queue_def, osThreadId thread_id) |
| { |
| if (queue_def == NULL) { |
| return NULL; |
| } |
| |
| if (k_is_in_isr()) { |
| return NULL; |
| } |
| |
| k_mbox_init(queue_def->mbox); |
| return (osMailQId)(queue_def); |
| } |
| |
| /** |
| * @brief Allocate a memory block from a mail. |
| */ |
| void *osMailAlloc(osMailQId queue_id, uint32_t millisec) |
| { |
| osMailQDef_t *queue_def = (osMailQDef_t *)queue_id; |
| char *ptr; |
| int retval; |
| |
| if (queue_def == NULL) { |
| return NULL; |
| } |
| |
| if (millisec == 0U) { |
| retval = k_mem_slab_alloc( |
| (struct k_mem_slab *)(queue_def->pool), |
| (void **)&ptr, K_NO_WAIT); |
| } else if (millisec == osWaitForever) { |
| retval = k_mem_slab_alloc( |
| (struct k_mem_slab *)(queue_def->pool), |
| (void **)&ptr, K_FOREVER); |
| } else { |
| retval = k_mem_slab_alloc( |
| (struct k_mem_slab *)(queue_def->pool), |
| (void **)&ptr, K_MSEC(millisec)); |
| } |
| |
| if (retval == 0) { |
| return ptr; |
| } else { |
| return NULL; |
| } |
| } |
| |
| /** |
| * @brief Allocate a memory block from a mail and set memory block to zero. |
| */ |
| void *osMailCAlloc(osMailQId queue_id, uint32_t millisec) |
| { |
| osMailQDef_t *queue_def = (osMailQDef_t *)queue_id; |
| char *ptr; |
| int retval; |
| |
| if (queue_def == NULL) { |
| return NULL; |
| } |
| |
| if (millisec == 0U) { |
| retval = k_mem_slab_alloc( |
| (struct k_mem_slab *)(queue_def->pool), |
| (void **)&ptr, K_NO_WAIT); |
| } else if (millisec == osWaitForever) { |
| retval = k_mem_slab_alloc( |
| (struct k_mem_slab *)(queue_def->pool), |
| (void **)&ptr, K_FOREVER); |
| } else { |
| retval = k_mem_slab_alloc( |
| (struct k_mem_slab *)(queue_def->pool), |
| (void **)&ptr, K_MSEC(millisec)); |
| } |
| |
| if (retval == 0) { |
| (void)memset(ptr, 0, queue_def->item_sz); |
| return ptr; |
| } else { |
| return NULL; |
| } |
| } |
| |
| /** |
| * @brief Put a mail to a queue. |
| */ |
| osStatus osMailPut(osMailQId queue_id, void *mail) |
| { |
| osMailQDef_t *queue_def = (osMailQDef_t *)queue_id; |
| struct k_mbox_msg mmsg; |
| |
| if (queue_def == NULL) { |
| return osErrorParameter; |
| } |
| |
| if (mail == NULL) { |
| return osErrorValue; |
| } |
| |
| (void)memset(&mmsg, 0, sizeof(mmsg)); |
| mmsg.tx_data = mail; |
| mmsg.rx_source_thread = K_ANY; |
| mmsg.tx_target_thread = K_ANY; |
| |
| k_mbox_async_put(queue_def->mbox, &mmsg, NULL); |
| return osOK; |
| } |
| |
| /** |
| * @brief Get a mail from a queue. |
| */ |
| osEvent osMailGet(osMailQId queue_id, uint32_t millisec) |
| { |
| osMailQDef_t *queue_def = (osMailQDef_t *)queue_id; |
| struct k_mbox_msg mmsg; |
| osEvent evt = {0}; |
| int retval; |
| |
| if (queue_def == NULL) { |
| evt.status = osErrorParameter; |
| return evt; |
| } |
| |
| (void)memset(&mmsg, 0, sizeof(mmsg)); |
| mmsg.rx_source_thread = K_ANY; |
| mmsg.tx_target_thread = K_ANY; |
| |
| if (millisec == 0U) { |
| retval = k_mbox_get(queue_def->mbox, &mmsg, NULL, K_NO_WAIT); |
| } else if (millisec == osWaitForever) { |
| retval = k_mbox_get(queue_def->mbox, &mmsg, NULL, K_FOREVER); |
| } else { |
| retval = k_mbox_get(queue_def->mbox, &mmsg, NULL, |
| K_MSEC(millisec)); |
| } |
| |
| if (retval == 0) { |
| evt.status = osEventMail; |
| evt.value.p = mmsg.tx_data; |
| } else if (retval == -EAGAIN) { |
| evt.status = osEventTimeout; |
| } else if (retval == -ENOMSG) { |
| evt.status = osOK; |
| } else { |
| evt.status = osErrorValue; |
| } |
| |
| evt.def.mail_id = queue_id; |
| |
| return evt; |
| } |
| |
| /** |
| * @brief Free a memory block from a mail. |
| */ |
| osStatus osMailFree(osMailQId queue_id, void *mail) |
| { |
| osMailQDef_t *queue_def = (osMailQDef_t *)queue_id; |
| |
| k_mem_slab_free((struct k_mem_slab *)(queue_def->pool), (void *) &mail); |
| |
| return osOK; |
| } |