1 /* Include necessary system files. */
2
3 #include "usbx_ux_test_cdc_ecm.h"
4
5 /* Resource usage */
6
7 static ULONG set_cfg_counter;
8
9 static ULONG rsc_mem_alloc_cnt_on_set_cfg;
10 static ULONG rsc_sem_on_set_cfg;
11 static ULONG rsc_sem_get_on_set_cfg;
12 static ULONG rsc_mutex_on_set_cfg;
13
14 static ULONG rsc_enum_sem_usage;
15 static ULONG rsc_enum_sem_get_count;
16 static ULONG rsc_enum_mutex_usage;
17 static ULONG rsc_enum_mem_alloc_count;
18
19 static ULONG rsc_cdc_sem_usage;
20 static ULONG rsc_cdc_sem_get_count;
21 static ULONG rsc_cdc_mutex_usage;
22 static ULONG rsc_cdc_mem_alloc_count;
23 static ULONG rsc_cdc_mem_tx_rx_count;
24
25 static ULONG error_callback_counter;
26
27 /* Log resources usage on SetConfigure */
28
29 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
30
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * _params)31 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *_params)
32 {
33
34 set_cfg_counter ++;
35
36 rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
37
38 rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
39 rsc_sem_get_on_set_cfg = ux_test_utility_sim_sem_get_count();
40 rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
41 }
42
43 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
44 { .function = UX_HCD_TRANSFER_REQUEST,
45 .req_setup = &_SetConfigure,
46 .req_action = UX_TEST_SETUP_MATCH_REQ,
47 .action_func = ux_test_hcd_entry_set_cfg,
48 .no_return = UX_TRUE
49 }, /* Invoke callback & continue */
50 { 0 }
51 };
52
count_error_callback(struct UX_TEST_ACTION_STRUCT * action,VOID * params)53 static void count_error_callback(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
54 {
55 UX_TEST_ERROR_CALLBACK_PARAMS *error = (UX_TEST_ERROR_CALLBACK_PARAMS *)params;
56
57 // printf("error trap: 0x%x, 0x%x, 0x%x\n", error->system_level, error->system_context, error->error_code);
58 error_callback_counter ++;
59 }
60
61 static UX_TEST_HCD_SIM_ACTION count_on_error_trap[] = {
62 { .usbx_function = UX_TEST_OVERRIDE_ERROR_CALLBACK,
63 .action_func = count_error_callback,
64 },
65 { 0 }
66 };
67
sleep_break_on_error(VOID)68 static UINT sleep_break_on_error(VOID)
69 {
70
71 if (error_callback_counter >= 3)
72 return error_callback_counter;
73
74 return UX_SUCCESS;
75 }
76
sleep_break_on_host_tx_or_rx_buffer_allocated(VOID)77 static UINT sleep_break_on_host_tx_or_rx_buffer_allocated(VOID)
78 {
79 UINT buffer_count = 0;
80 if (cdc_ecm_host == UX_NULL)
81 return(UX_SUCCESS);
82 if (cdc_ecm_host -> ux_host_class_cdc_ecm_xmit_buffer)
83 buffer_count ++;
84 if (cdc_ecm_host -> ux_host_class_cdc_ecm_receive_buffer)
85 buffer_count ++;
86 return (buffer_count);
87 }
88
sleep_break_on_host_tx_and_rx_buffer_allocated(VOID)89 static UINT sleep_break_on_host_tx_and_rx_buffer_allocated(VOID)
90 {
91 UINT buffer_count = 0;
92 if (cdc_ecm_host == UX_NULL)
93 return(UX_SUCCESS);
94 if (cdc_ecm_host -> ux_host_class_cdc_ecm_xmit_buffer)
95 buffer_count ++;
96 if (cdc_ecm_host -> ux_host_class_cdc_ecm_receive_buffer)
97 buffer_count ++;
98 return ((buffer_count >=2) ? buffer_count : UX_SUCCESS);
99 }
100
101 /* Define what the initial system looks like. */
102 #ifdef CTEST
test_application_define(void * first_unused_memory)103 void test_application_define(void *first_unused_memory)
104 #else
105 void usbx_cdc_ecm_basic_memory_test_application_define(void *first_unused_memory)
106 #endif
107 {
108
109 /* Inform user. */
110 printf("Running CDC ECM Basic Memory Test................................... ");
111
112 stepinfo("\n");
113
114 /* Override error trap. */
115 ux_test_link_hooks_from_array(count_on_error_trap);
116
117 /* Reset testing counts. */
118 ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
119 ux_test_utility_sim_mem_alloc_count_reset();
120 ux_test_utility_sim_mutex_create_count_reset();
121 ux_test_utility_sim_sem_create_count_reset();
122 ux_test_utility_sim_sem_get_count_reset();
123 /* Reset error generations */
124 ux_test_utility_sim_sem_error_generation_stop();
125 ux_test_utility_sim_mutex_error_generation_stop();
126 ux_test_utility_sim_sem_get_error_generation_stop();
127
128 ux_test_cdc_ecm_initialize(first_unused_memory);
129 }
130
post_init_host()131 static void post_init_host()
132 {
133
134 UINT status;
135 ULONG mem_free;
136 ULONG test_n;
137
138
139 /* Test disconnect. */
140 stepinfo(">>>>>>>>>>>>>>>>>>> Test disconnect\n");
141 ux_test_disconnect_slave();
142 ux_test_disconnect_host_wait_for_enum_completion();
143
144 /* Reset testing counts. */
145 ux_test_utility_sim_mem_alloc_count_reset();
146 ux_test_utility_sim_mutex_create_count_reset();
147 ux_test_utility_sim_sem_create_count_reset();
148 ux_test_utility_sim_sem_get_count_reset();
149 ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
150
151 /* Save free memory usage. */
152 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
153
154 stepinfo(">>>>>>>>>>>>>>>>>>> Test connect\n");
155 /* Connect. */
156 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
157 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
158 class_cdc_ecm_get_host();
159
160 /* Log create counts for further tests. */
161 rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
162 rsc_enum_sem_usage = rsc_sem_on_set_cfg;
163 rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
164 /* Log create counts when instances active for further tests. */
165 rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
166 rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
167 rsc_cdc_mem_alloc_count = ux_test_utility_sim_mem_alloc_count() - rsc_enum_mem_alloc_count;
168 /* Some allocation does not affect enum. */
169 rsc_cdc_mem_tx_rx_count = 0;
170 if (cdc_ecm_host->ux_host_class_cdc_ecm_receive_buffer)
171 rsc_cdc_mem_tx_rx_count ++;
172 if (cdc_ecm_host->ux_host_class_cdc_ecm_xmit_buffer)
173 rsc_cdc_mem_tx_rx_count ++;
174 /* Lock log base for tests. */
175 ux_test_utility_sim_mem_alloc_log_lock();
176
177 stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
178 stepinfo("cdc mem : %ld\n", rsc_cdc_mem_alloc_count);
179 stepinfo("mem free: %ld, %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available);
180
181 /* Simulate detach and attach for FS enumeration,
182 and check if there is memory error in normal enumeration.
183 */
184 stepinfo(">>>>>>>>>>>>>>>>>>> Enumeration test\n");
185 mem_free = (~0);
186 for (test_n = 0; test_n < 3; test_n++)
187 {
188 stepinfo("%4ld / 2\n", test_n);
189
190 /* Disconnect. */
191 ux_test_dcd_sim_slave_disconnect();
192 ux_test_hcd_sim_host_disconnect();
193
194 /* Update memory free level (disconnect) */
195 if (mem_free == (~0))
196 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
197 else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
198 {
199
200 printf("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
201 test_control_return(1);
202 }
203
204 /* Connect. */
205 error_callback_counter = 0;
206 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
207 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
208
209 /* Wait and break on error. */
210 ux_test_breakable_sleep(200, sleep_break_on_error);
211
212 /* Check */
213 if (cdc_ecm_host_from_system_change_function == UX_NULL)
214 {
215
216 printf("ERROR #%d.%ld: Enumeration fail\n", __LINE__, test_n);
217 test_control_return(1);
218 }
219 }
220
221 /* Simulate detach and attach for FS enumeration,
222 and test possible memory allocation error handlings.
223 */
224 if (rsc_cdc_mem_alloc_count) stepinfo(">>>>>>>>>>>>>>>>>>> Memory errors enumeration test\n");
225 mem_free = (~0);
226 for (test_n = 0; test_n < rsc_cdc_mem_alloc_count; test_n ++)
227 {
228
229 stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_mem_alloc_count - 1);
230
231 /* Disconnect. */
232 ux_test_dcd_sim_slave_disconnect();
233 ux_test_hcd_sim_host_disconnect();
234
235 /* Update memory free level (disconnect) */
236 if (mem_free == (~0))
237 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
238 else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
239 {
240
241 printf("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
242 test_control_return(1);
243 }
244
245 /* Set memory error generation */
246 ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
247
248 /* Connect. */
249 error_callback_counter = 0;
250 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
251 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
252
253 if (test_n >= rsc_cdc_mem_alloc_count - rsc_cdc_mem_tx_rx_count)
254 {
255
256 /* Wait and break on errors. */
257 ux_test_breakable_sleep(200, sleep_break_on_error);
258 }
259 else
260 {
261
262 /* Wait and break on errors. */
263 ux_test_breakable_sleep(200, sleep_break_on_error);
264
265 /* Check error */
266 if (cdc_ecm_host_from_system_change_function != UX_NULL)
267 {
268
269 printf("ERROR #%d.%ld: device detected when there is memory error\n", __LINE__, test_n);
270 test_control_return(1);
271 }
272 }
273
274 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
275 }
276 ux_test_utility_sim_mem_alloc_error_generation_stop();
277 if (rsc_cdc_mem_alloc_count) stepinfo("\n");
278
279 /* Test device deinit. */
280 stepinfo(">>>>>>>>>>>>>>>>>>> Test class deinit\n");
281 ux_test_disconnect_slave();
282 ux_test_disconnect_host_wait_for_enum_completion();
283 ux_device_stack_class_unregister(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry);
284
285 /* Reset testing counts. */
286 ux_test_utility_sim_mem_alloc_count_reset();
287 ux_test_utility_sim_mutex_create_count_reset();
288 ux_test_utility_sim_sem_create_count_reset();
289 ux_test_utility_sim_sem_get_count_reset();
290
291 stepinfo(">>>>>>>>>>>>>>>>>>> Test class init\n");
292 UX_TEST_CHECK_SUCCESS(ux_device_stack_class_register(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry, 1, 0, &cdc_ecm_parameter));
293
294 /* Log create counts for further tests. */
295 rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count();
296 rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count();
297 rsc_cdc_mem_alloc_count = ux_test_utility_sim_mem_alloc_count();
298
299 /* Lock log base for tests. */
300 ux_test_utility_sim_mem_alloc_log_lock();
301
302 if (rsc_cdc_mem_alloc_count) stepinfo(">>>>>>>>>>>>>>>>>>> Memory errors class init test\n");
303 mem_free = (~0);
304 for (test_n = 0; test_n < rsc_cdc_mem_alloc_count; test_n ++)
305 {
306
307 stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_mem_alloc_count - 1);
308
309 /* Deinit. */
310 ux_device_stack_class_unregister(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry);
311
312 /* Update memory free level (disconnect) */
313 if (mem_free == (~0))
314 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
315 else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
316 {
317
318 printf("ERROR #%d.%ld: Memory level different after re-init %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
319 test_control_return(1);
320 }
321
322 /* Set memory error generation */
323 ux_test_utility_sim_mem_alloc_error_generation_start(test_n);
324
325 /* Init. */
326
327 status = ux_device_stack_class_register(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry, 1, 0, &cdc_ecm_parameter);
328
329 /* Check error */
330 if (status != UX_MEMORY_INSUFFICIENT)
331 {
332
333 printf("ERROR #%d.%ld: code 0x%x\n", __LINE__, test_n, status);
334 test_control_return(1);
335 }
336 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
337 }
338 ux_test_utility_sim_mem_alloc_error_generation_stop();
339 if (rsc_cdc_mem_alloc_count) stepinfo("\n");
340
341 stepinfo(">>>>>>>>>>>>>>>>>>> Test connect to avoid post post operation\n");
342 /* Connect. */
343 UX_TEST_CHECK_SUCCESS(ux_device_stack_class_register(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry, 1, 0, &cdc_ecm_parameter));
344 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
345 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
346 class_cdc_ecm_get_host();
347
348 stepinfo(">>>>>>>>>>>>>>>>>>> post_init_host done\n");
349 }
350
post_init_device()351 static void post_init_device()
352 {
353 stepinfo(">>>>>>>>>>>>>>>>>>> post_init_device empty\n");
354 }