1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <kernel.h>
8 #include <cmsis_os.h>
9 #include <string.h>
10
11 /**
12 * @brief Create and Initialize mail queue.
13 */
osMailCreate(const osMailQDef_t * queue_def,osThreadId thread_id)14 osMailQId osMailCreate(const osMailQDef_t *queue_def, osThreadId thread_id)
15 {
16 if (queue_def == NULL) {
17 return NULL;
18 }
19
20 if (k_is_in_isr()) {
21 return NULL;
22 }
23
24 k_mbox_init(queue_def->mbox);
25 return (osMailQId)(queue_def);
26 }
27
28 /**
29 * @brief Allocate a memory block from a mail.
30 */
osMailAlloc(osMailQId queue_id,uint32_t millisec)31 void *osMailAlloc(osMailQId queue_id, uint32_t millisec)
32 {
33 osMailQDef_t *queue_def = (osMailQDef_t *)queue_id;
34 char *ptr;
35 int retval;
36
37 if (queue_def == NULL) {
38 return NULL;
39 }
40
41 if (millisec == 0U) {
42 retval = k_mem_slab_alloc(
43 (struct k_mem_slab *)(queue_def->pool),
44 (void **)&ptr, K_NO_WAIT);
45 } else if (millisec == osWaitForever) {
46 retval = k_mem_slab_alloc(
47 (struct k_mem_slab *)(queue_def->pool),
48 (void **)&ptr, K_FOREVER);
49 } else {
50 retval = k_mem_slab_alloc(
51 (struct k_mem_slab *)(queue_def->pool),
52 (void **)&ptr, K_MSEC(millisec));
53 }
54
55 if (retval == 0) {
56 return ptr;
57 } else {
58 return NULL;
59 }
60 }
61
62 /**
63 * @brief Allocate a memory block from a mail and set memory block to zero.
64 */
osMailCAlloc(osMailQId queue_id,uint32_t millisec)65 void *osMailCAlloc(osMailQId queue_id, uint32_t millisec)
66 {
67 osMailQDef_t *queue_def = (osMailQDef_t *)queue_id;
68 char *ptr;
69 int retval;
70
71 if (queue_def == NULL) {
72 return NULL;
73 }
74
75 if (millisec == 0U) {
76 retval = k_mem_slab_alloc(
77 (struct k_mem_slab *)(queue_def->pool),
78 (void **)&ptr, K_NO_WAIT);
79 } else if (millisec == osWaitForever) {
80 retval = k_mem_slab_alloc(
81 (struct k_mem_slab *)(queue_def->pool),
82 (void **)&ptr, K_FOREVER);
83 } else {
84 retval = k_mem_slab_alloc(
85 (struct k_mem_slab *)(queue_def->pool),
86 (void **)&ptr, K_MSEC(millisec));
87 }
88
89 if (retval == 0) {
90 (void)memset(ptr, 0, queue_def->item_sz);
91 return ptr;
92 } else {
93 return NULL;
94 }
95 }
96
97 /**
98 * @brief Put a mail to a queue.
99 */
osMailPut(osMailQId queue_id,void * mail)100 osStatus osMailPut(osMailQId queue_id, void *mail)
101 {
102 osMailQDef_t *queue_def = (osMailQDef_t *)queue_id;
103 struct k_mbox_msg mmsg;
104
105 if (queue_def == NULL) {
106 return osErrorParameter;
107 }
108
109 if (mail == NULL) {
110 return osErrorValue;
111 }
112
113 (void)memset(&mmsg, 0, sizeof(mmsg));
114 mmsg.tx_data = mail;
115 mmsg.rx_source_thread = K_ANY;
116 mmsg.tx_target_thread = K_ANY;
117
118 k_mbox_async_put(queue_def->mbox, &mmsg, NULL);
119 return osOK;
120 }
121
122 /**
123 * @brief Get a mail from a queue.
124 */
osMailGet(osMailQId queue_id,uint32_t millisec)125 osEvent osMailGet(osMailQId queue_id, uint32_t millisec)
126 {
127 osMailQDef_t *queue_def = (osMailQDef_t *)queue_id;
128 struct k_mbox_msg mmsg;
129 osEvent evt = {0};
130 int retval;
131
132 if (queue_def == NULL) {
133 evt.status = osErrorParameter;
134 return evt;
135 }
136
137 (void)memset(&mmsg, 0, sizeof(mmsg));
138 mmsg.rx_source_thread = K_ANY;
139 mmsg.tx_target_thread = K_ANY;
140
141 if (millisec == 0U) {
142 retval = k_mbox_get(queue_def->mbox, &mmsg, NULL, K_NO_WAIT);
143 } else if (millisec == osWaitForever) {
144 retval = k_mbox_get(queue_def->mbox, &mmsg, NULL, K_FOREVER);
145 } else {
146 retval = k_mbox_get(queue_def->mbox, &mmsg, NULL,
147 K_MSEC(millisec));
148 }
149
150 if (retval == 0) {
151 evt.status = osEventMail;
152 evt.value.p = mmsg.tx_data;
153 } else if (retval == -EAGAIN) {
154 evt.status = osEventTimeout;
155 } else if (retval == -ENOMSG) {
156 evt.status = osOK;
157 } else {
158 evt.status = osErrorValue;
159 }
160
161 evt.def.mail_id = queue_id;
162
163 return evt;
164 }
165
166 /**
167 * @brief Free a memory block from a mail.
168 */
osMailFree(osMailQId queue_id,void * mail)169 osStatus osMailFree(osMailQId queue_id, void *mail)
170 {
171 osMailQDef_t *queue_def = (osMailQDef_t *)queue_id;
172
173 k_mem_slab_free((struct k_mem_slab *)(queue_def->pool), (void *) &mail);
174
175 return osOK;
176 }
177