1 /*
2  * Copyright (c) 2018 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/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