1 /*
2 * Copyright (c) 2017 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_os.h>
10
11 struct sample_data {
12 int data1;
13 unsigned char data2;
14 unsigned int data3;
15 };
16
17 #define MAIL1_DATA1 75663
18 #define MAIL1_DATA2 156
19 #define MAIL1_DATA3 1000001
20
21 #define MAIL2_DATA1 93567
22 #define MAIL2_DATA2 255
23 #define MAIL2_DATA3 1234567
24
25 #define TIMEOUT 500
26 #define Q_LEN 5
27
28 osMailQDef(mail, Q_LEN, struct sample_data);
29 osMailQId mail_id;
30
send_thread(void const * argument)31 void send_thread(void const *argument)
32 {
33 int i;
34 struct sample_data *tx_ptr;
35 struct sample_data zeroblock;
36 osStatus status;
37
38 /* This is used for comparison later in the function */
39 memset(&zeroblock, 0, sizeof(struct sample_data));
40
41 status = osMailPut(mail_id, NULL);
42 zassert_true(status == osErrorValue,
43 "Something's wrong with osMailPut. It is passing for NULL mail!");
44
45 /* Wait for mail_recv to complete initial checks */
46 osDelay(TIMEOUT);
47
48 /* Prepare and send 1st mail */
49 tx_ptr = osMailAlloc(mail_id, osWaitForever);
50 zassert_true(tx_ptr != NULL, "Mail1 alloc failed");
51 tx_ptr->data1 = MAIL1_DATA1;
52 tx_ptr->data2 = MAIL1_DATA2;
53 tx_ptr->data3 = MAIL1_DATA3;
54 status = osMailPut(mail_id, tx_ptr);
55 zassert_true(status == osOK, "osMailPut failure for mail1");
56
57 /* Fill the queue with blocks of mails */
58 for (i = 0; i < Q_LEN; i++) {
59
60 /* Alternately use osMailAlloc and osMailCAlloc to ensure
61 * both the APIs are tested.
62 */
63 if (i & 1) {
64 tx_ptr = osMailCAlloc(mail_id, osWaitForever);
65 } else {
66 tx_ptr = osMailAlloc(mail_id, osWaitForever);
67 }
68 zassert_true(tx_ptr != NULL, "Mail alloc failed");
69
70 tx_ptr->data1 = i;
71 tx_ptr->data2 = i+1;
72 tx_ptr->data3 = i+2;
73
74 status = osMailPut(mail_id, tx_ptr);
75 zassert_true(status == osOK,
76 "osMailPut failure for mail!");
77 }
78
79 /* Try allocating mail to a full queue immediately
80 * before it is emptied out and assert failure
81 */
82 tx_ptr = osMailAlloc(mail_id, 0);
83 zassert_true(tx_ptr == NULL, "MailAlloc passed. Something's wrong");
84 tx_ptr = osMailCAlloc(mail_id, 0);
85 zassert_true(tx_ptr == NULL, "MailCAlloc passed. Something's wrong");
86
87 /* Try allocating mail to a full queue within a duration
88 * less than TIMEOUT, before the queue is emptied out
89 */
90 tx_ptr = osMailAlloc(mail_id, TIMEOUT/3);
91 zassert_true(tx_ptr == NULL, "MailAlloc passed. Something's wrong");
92 tx_ptr = osMailCAlloc(mail_id, TIMEOUT/3);
93 zassert_true(tx_ptr == NULL, "MailCAlloc passed. Something's wrong");
94
95 /* Send another mail after the queue is emptied */
96 tx_ptr = osMailCAlloc(mail_id, TIMEOUT*2);
97 zassert_true(tx_ptr != NULL, "Mail alloc failed");
98 zassert_equal(memcmp(tx_ptr, &zeroblock, sizeof(struct sample_data)), 0,
99 "osMailCAlloc returned memory not initialized to 0");
100
101 tx_ptr->data1 = MAIL2_DATA1;
102 tx_ptr->data2 = MAIL2_DATA2;
103 tx_ptr->data3 = MAIL2_DATA3;
104 status = osMailPut(mail_id, tx_ptr);
105 zassert_true(status == osOK, "osMailPut failure for mail");
106 }
107
mail_recv(void)108 void mail_recv(void)
109 {
110 int i;
111 struct sample_data *rx_ptr;
112 osEvent evt;
113 osStatus status;
114
115 /* Try getting mail immediately before the queue is populated */
116 evt = osMailGet(mail_id, 0);
117 zassert_true(evt.status == osOK,
118 "Something's wrong with osMailGet!");
119
120 /* Try receiving mail within a duration of TIMEOUT */
121 evt = osMailGet(mail_id, TIMEOUT);
122 zassert_true(evt.status == osEventTimeout,
123 "Something's wrong with osMailGet!");
124
125 /* Receive 1st mail */
126 evt = osMailGet(mail_id, osWaitForever);
127 zassert_true(evt.status == osEventMail, "osMailGet failure");
128
129 rx_ptr = evt.value.p;
130 zassert_equal(rx_ptr->data1, MAIL1_DATA1);
131 zassert_equal(rx_ptr->data2, MAIL1_DATA2);
132 zassert_equal(rx_ptr->data3, MAIL1_DATA3);
133
134 status = osMailFree(mail_id, rx_ptr);
135 zassert_true(status == osOK, "osMailFree failure");
136
137 /* Wait for queue to get filled */
138 osDelay(TIMEOUT);
139
140 /* Empty the queue */
141 for (i = 0; i < Q_LEN; i++) {
142 evt = osMailGet(mail_id, osWaitForever);
143 zassert_true(evt.status == osEventMail, "osMailGet failure");
144
145 rx_ptr = evt.value.p;
146 zassert_equal(rx_ptr->data1, i);
147 zassert_equal(rx_ptr->data2, i + 1);
148 zassert_equal(rx_ptr->data3, i + 2);
149
150 status = osMailFree(mail_id, rx_ptr);
151 zassert_true(status == osOK, "osMailFree failure");
152 }
153
154 /* Receive the next mail */
155 evt = osMailGet(mail_id, osWaitForever);
156 zassert_true(evt.status == osEventMail, "osMailGet failure");
157
158 rx_ptr = evt.value.p;
159 zassert_equal(rx_ptr->data1, MAIL2_DATA1);
160 zassert_equal(rx_ptr->data2, MAIL2_DATA2);
161 zassert_equal(rx_ptr->data3, MAIL2_DATA3);
162
163 status = osMailFree(mail_id, rx_ptr);
164 zassert_true(status == osOK, "osMailFree failure");
165 }
166
167 osThreadDef(send_thread, osPriorityNormal, 1, 0);
168
ZTEST(cmsis_mailq,test_mailq)169 ZTEST(cmsis_mailq, test_mailq)
170 {
171 osThreadId tid;
172
173 mail_id = osMailCreate(osMailQ(mail), NULL);
174 zassert_true(mail_id != NULL, "Mail creation failed");
175
176 tid = osThreadCreate(osThread(send_thread), NULL);
177 zassert_true(tid != NULL, "Thread creation failed");
178
179 mail_recv();
180 }
181 ZTEST_SUITE(cmsis_mailq, NULL, NULL, NULL, NULL, NULL);
182