1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/kernel.h>
9 #include <cmsis_os2.h>
10
11 struct sample_data {
12 int data1;
13 unsigned char data2;
14 unsigned int data3;
15 };
16
17 #define MESSAGE1 512
18 #define MESSAGE2 123456
19 #define TIMEOUT_TICKS 50
20 #define Q_LEN 5
21 #define STACKSZ CONFIG_CMSIS_V2_THREAD_MAX_STACK_SIZE
22
23 osMessageQueueId_t message_id;
24
send_msg_thread(void * argument)25 void send_msg_thread(void *argument)
26 {
27 int i;
28 osStatus_t status;
29 struct sample_data sample;
30 struct sample_data data[Q_LEN] = { { 0 } };
31
32 /* Wait for message_recv to complete initial checks */
33 osDelay(TIMEOUT_TICKS);
34
35 /* Prepare and send the 1st message (a simple integer data) */
36 sample.data1 = MESSAGE1;
37 status = osMessageQueuePut(message_id, &sample, 0, osWaitForever);
38 zassert_true(status == osOK, "osMessageQueuePut failure for Message1");
39
40 /* The Queue should be empty at this point */
41 zassert_equal(osMessageQueueGetCount(message_id), 0,
42 "Something's wrong with osMessageQueueGetCount!");
43 zassert_equal(osMessageQueueGetSpace(message_id), Q_LEN,
44 "Something's wrong with osMessageQueueGetSpace!");
45
46 /* Fill the queue with blocks of messages */
47 for (i = 0; i < Q_LEN; i++) {
48 data[i].data1 = i * 3;
49 data[i].data2 = i * 3 + 1;
50 data[i].data3 = i * 3 + 2;
51 status = osMessageQueuePut(message_id, data + i,
52 0, osWaitForever);
53 zassert_true(status == osOK,
54 "osMessageQueuePut failure for message!");
55 }
56
57 /* The Queue should be full at this point */
58 zassert_equal(osMessageQueueGetCount(message_id), Q_LEN,
59 "Something's wrong with osMessageQueueGetCount!");
60 zassert_equal(osMessageQueueGetSpace(message_id), 0,
61 "Something's wrong with osMessageQueueGetSpace!");
62
63 /* Try putting message to a full queue immediately
64 * before it is emptied out and assert failure
65 */
66 sample.data1 = MESSAGE2;
67 status = osMessageQueuePut(message_id, &sample, 0, 0);
68 zassert_true(status == osErrorResource,
69 "Something's wrong with osMessageQueuePut!");
70
71 /* Try putting message to a full queue within a duration
72 * less than TIMEOUT_TICKS, before the queue is emptied out
73 */
74 sample.data1 = MESSAGE2;
75 status = osMessageQueuePut(message_id, &sample, 0, TIMEOUT_TICKS / 2);
76 zassert_true(status == osErrorTimeout,
77 "Something's wrong with osMessageQueuePut!");
78
79 /* Send another message after the queue is emptied */
80 sample.data1 = MESSAGE2;
81 status = osMessageQueuePut(message_id, &sample, 0, TIMEOUT_TICKS * 2);
82 zassert_true(status == osOK,
83 "osMessageQueuePut failure for message!");
84 }
85
message_recv(void)86 void message_recv(void)
87 {
88 int i;
89 osStatus_t status;
90 struct sample_data recv_data;
91
92 /* Try getting message immediately before the queue is populated */
93 status = osMessageQueueGet(message_id, (void *)&recv_data, NULL, 0);
94 zassert_true(status == osErrorResource,
95 "Something's wrong with osMessageQueueGet!");
96
97 /* Try receiving message within a duration of TIMEOUT */
98 status = osMessageQueueGet(message_id, (void *)&recv_data,
99 NULL, TIMEOUT_TICKS);
100 zassert_true(status == osErrorTimeout,
101 "Something's wrong with osMessageQueueGet!");
102
103 zassert_equal(osMessageQueueGetCapacity(message_id), Q_LEN,
104 "Something's wrong with osMessageQueueGetCapacity!");
105
106 zassert_equal(osMessageQueueGetMsgSize(message_id),
107 sizeof(struct sample_data),
108 "Something's wrong with osMessageQueueGetMsgSize!");
109
110 /* Receive 1st message */
111 status = osMessageQueueGet(message_id, (void *)&recv_data,
112 NULL, osWaitForever);
113 zassert_true(status == osOK, "osMessageQueueGet failure");
114 zassert_equal(recv_data.data1, MESSAGE1);
115
116 /* Wait for queue to get filled */
117 osDelay(TIMEOUT_TICKS);
118
119 /* Empty the queue */
120 for (i = 0; i < Q_LEN; i++) {
121 status = osMessageQueueGet(message_id, (void *)&recv_data, NULL,
122 osWaitForever);
123 zassert_true(status == osOK, "osMessageQueueGet failure");
124
125 zassert_equal(recv_data.data1, i * 3);
126 zassert_equal(recv_data.data2, i * 3 + 1);
127 zassert_equal(recv_data.data3, i * 3 + 2);
128 }
129
130 /* Receive the next message */
131 status = osMessageQueueGet(message_id, (void *)&recv_data,
132 NULL, osWaitForever);
133 zassert_true(status == osOK, "osMessageQueueGet failure");
134 zassert_equal(recv_data.data1, MESSAGE2);
135 }
136
137 static K_THREAD_STACK_DEFINE(test_stack, STACKSZ);
138 osThreadAttr_t thread_attr = {
139 .name = "send_thread",
140 .stack_mem = &test_stack,
141 .stack_size = STACKSZ,
142 .priority = osPriorityNormal,
143 };
144
145 static char __aligned(4) sample_mem[sizeof(struct sample_data) * Q_LEN];
146 static const osMessageQueueAttr_t init_mem_attrs = {
147 .name = "TestMsgQ",
148 .attr_bits = 0,
149 .cb_mem = NULL,
150 .cb_size = 0,
151 .mq_mem = sample_mem,
152 .mq_size = sizeof(struct sample_data) * Q_LEN,
153 };
154
ZTEST(cmsis_msgq,test_messageq)155 ZTEST(cmsis_msgq, test_messageq)
156 {
157 osStatus_t status;
158 struct sample_data sample;
159 osThreadId_t tid;
160
161 message_id = osMessageQueueNew(Q_LEN, sizeof(struct sample_data),
162 &init_mem_attrs);
163 zassert_true(message_id != NULL, "Message creation failed");
164
165 tid = osThreadNew(send_msg_thread, NULL, &thread_attr);
166 zassert_true(tid != NULL, "Thread creation failed");
167
168 message_recv();
169
170 /* Wait for the send_msg_thread to terminate before this thread
171 * terminates.
172 */
173 osDelay(TIMEOUT_TICKS / 10);
174
175 /* Make sure msgq is empty */
176 zassert_equal(osMessageQueueGetCount(message_id), 0,
177 "Something's wrong with osMessageQueueGetCount!");
178
179 sample.data1 = MESSAGE1;
180 status = osMessageQueuePut(message_id, &sample, 0, osWaitForever);
181 zassert_true(status == osOK, "osMessageQueuePut failure for Message1");
182
183 zassert_equal(osMessageQueueGetCount(message_id), 1,
184 "Something's wrong with osMessageQueueGetCount!");
185
186 status = osMessageQueueReset(message_id);
187 zassert_true(status == osOK, "osMessageQueueReset failure");
188
189 /* After reset msgq must be empty */
190 zassert_equal(osMessageQueueGetCount(message_id), 0,
191 "Something's wrong with osMessageQueueGetCount!");
192
193 status = osMessageQueueDelete(message_id);
194 zassert_true(status == osOK, "osMessageQueueDelete failure");
195 }
196 ZTEST_SUITE(cmsis_msgq, NULL, NULL, NULL, NULL, NULL);
197