1 /* This test is designed to test the simple dpump host/device class operation. */
2
3 #include <stdio.h>
4 #include "tx_api.h"
5 #include "ux_api.h"
6 #include "ux_system.h"
7 #include "ux_utility.h"
8
9 #include "fx_api.h"
10
11 #include "ux_device_class_cdc_acm.h"
12 #include "ux_device_stack.h"
13 #include "ux_host_class_cdc_acm.h"
14
15 #include "ux_test_dcd_sim_slave.h"
16 #include "ux_test_hcd_sim_host.h"
17 #include "ux_test_utility_sim.h"
18
19 /* Define constants. */
20 #define UX_DEMO_DEBUG_SIZE (4096*8)
21 #define UX_DEMO_STACK_SIZE 1024
22 #define UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
23 #define UX_DEMO_XMIT_BUFFER_SIZE 512
24 #define UX_DEMO_RECEPTION_BUFFER_SIZE 512
25 #define UX_DEMO_FILE_BUFFER_SIZE 512
26 #define UX_DEMO_RECEPTION_BLOCK_SIZE 64
27 #define UX_DEMO_MEMORY_SIZE (64*1024)
28 #define UX_DEMO_FILE_SIZE (128 * 1024)
29 #define UX_RAM_DISK_MEMORY (256 * 1024)
30
31 /* Define local/extern function prototypes. */
32 static TX_THREAD ux_test_thread_host_simulation;
33 static TX_THREAD ux_test_thread_slave_simulation;
34 static void ux_test_thread_host_simulation_entry(ULONG);
35 static void ux_test_thread_slave_simulation_entry(ULONG);
36
37 static VOID test_cdc_instance_activate(VOID *cdc_instance);
38 static VOID test_cdc_instance_deactivate(VOID *cdc_instance);
39 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance);
40
41 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
42
43 /* Define global data structures. */
44 static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
45 static UX_HOST_CLASS *class_driver;
46 static UX_HOST_CLASS_CDC_ACM *cdc_acm_host_control;
47 static UX_HOST_CLASS_CDC_ACM *cdc_acm_host_data;
48
49 static UX_SLAVE_CLASS_CDC_ACM *cdc_acm_slave;
50 static UCHAR cdc_acm_slave_change;
51 static UX_SLAVE_CLASS_CDC_ACM_PARAMETER parameter;
52
53 static ULONG set_cfg_counter;
54
55 static ULONG rsc_mem_alloc_cnt_on_set_cfg;
56 static ULONG rsc_sem_on_set_cfg;
57 static ULONG rsc_sem_get_on_set_cfg;
58 static ULONG rsc_mutex_on_set_cfg;
59
60 static ULONG rsc_enum_sem_usage;
61 static ULONG rsc_enum_sem_get_count;
62 static ULONG rsc_enum_mutex_usage;
63 static ULONG rsc_enum_mem_alloc_count;
64
65 static ULONG rsc_cdc_sem_usage;
66 static ULONG rsc_cdc_sem_get_count;
67 static ULONG rsc_cdc_mutex_usage;
68 static ULONG rsc_cdc_mem_alloc_count;
69
70 static ULONG interaction_count;
71
72 static UCHAR error_callback_ignore = UX_TRUE;
73 static ULONG error_callback_counter;
74
75 /* Define device framework. */
76
77 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 93
78 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 103
79 #define STRING_FRAMEWORK_LENGTH 47
80 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
81
82 static unsigned char device_framework_full_speed[] = {
83
84 /* Device descriptor 18 bytes
85 0x02 bDeviceClass: CDC class code
86 0x00 bDeviceSubclass: CDC class sub code
87 0x00 bDeviceProtocol: CDC Device protocol
88
89 idVendor & idProduct - http://www.linux-usb.org/usb.ids
90 */
91 0x12, 0x01, 0x10, 0x01,
92 0xEF, 0x02, 0x01,
93 0x08,
94 0x84, 0x84, 0x00, 0x00,
95 0x00, 0x01,
96 0x01, 0x02, 03,
97 0x01,
98
99 /* Configuration 1 descriptor 9 bytes */
100 0x09, 0x02, 0x4b, 0x00,
101 0x02, 0x01, 0x00,
102 0x40, 0x00,
103
104 /* Interface association descriptor. 8 bytes. */
105 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
106
107 /* Communication Class Interface Descriptor Requirement. 9 bytes. */
108 0x09, 0x04, 0x00,
109 0x00,
110 0x01,
111 0x02, 0x02, 0x01,
112 0x00,
113
114 /* Header Functional Descriptor 5 bytes */
115 0x05, 0x24, 0x00,
116 0x10, 0x01,
117
118 /* ACM Functional Descriptor 4 bytes */
119 0x04, 0x24, 0x02,
120 0x0f,
121
122 /* Union Functional Descriptor 5 bytes */
123 0x05, 0x24, 0x06,
124 0x00, /* Master interface */
125 0x01, /* Slave interface */
126
127 /* Call Management Functional Descriptor 5 bytes */
128 0x05, 0x24, 0x01,
129 0x03,
130 0x01, /* Data interface */
131
132 /* Endpoint 0x83 descriptor 7 bytes */
133 0x07, 0x05, 0x83,
134 0x03,
135 0x08, 0x00,
136 0xFF,
137
138 /* Data Class Interface Descriptor Requirement 9 bytes */
139 0x09, 0x04, 0x01,
140 0x00,
141 0x02,
142 0x0A, 0x00, 0x00,
143 0x00,
144
145 /* Endpoint 0x02 descriptor 7 bytes */
146 0x07, 0x05, 0x02, /* @ 93 - 14 + 2 = 81 */
147 0x02,
148 0x40, 0x00,
149 0x00,
150
151 /* Endpoint 0x81 descriptor 7 bytes */
152 0x07, 0x05, 0x81, /* @ 93 - 7 + 2 = 88 */
153 0x02,
154 0x40, 0x00,
155 0x00,
156
157 };
158
159 #define DEVICE_FRAMEWORK_EPA_POS_1_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 14 + 2)
160 #define DEVICE_FRAMEWORK_EPA_POS_2_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 7 + 2)
161
162 static unsigned char device_framework_high_speed[] = {
163
164 /* Device descriptor
165 0x02 bDeviceClass: CDC class code
166 0x00 bDeviceSubclass: CDC class sub code
167 0x00 bDeviceProtocol: CDC Device protocol
168
169 idVendor & idProduct - http://www.linux-usb.org/usb.ids
170 */
171 0x12, 0x01, 0x00, 0x02,
172 0xEF, 0x02, 0x01,
173 0x40,
174 0x84, 0x84, 0x00, 0x00,
175 0x00, 0x01,
176 0x01, 0x02, 03,
177 0x01,
178
179 /* Device qualifier descriptor */
180 0x0a, 0x06, 0x00, 0x02,
181 0x02, 0x00, 0x00,
182 0x40,
183 0x01,
184 0x00,
185
186 /* Configuration 1 descriptor */
187 0x09, 0x02, 0x4b, 0x00,
188 0x02, 0x01, 0x00,
189 0x40, 0x00,
190
191 /* Interface association descriptor. */
192 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
193
194 /* Communication Class Interface Descriptor Requirement */
195 0x09, 0x04, 0x00,
196 0x00,
197 0x01,
198 0x02, 0x02, 0x01,
199 0x00,
200
201 /* Header Functional Descriptor */
202 0x05, 0x24, 0x00,
203 0x10, 0x01,
204
205 /* ACM Functional Descriptor */
206 0x04, 0x24, 0x02,
207 0x0f,
208
209 /* Union Functional Descriptor */
210 0x05, 0x24, 0x06,
211 0x00,
212 0x01,
213
214 /* Call Management Functional Descriptor */
215 0x05, 0x24, 0x01,
216 0x00,
217 0x01,
218
219 /* Endpoint 0x83 descriptor */
220 0x07, 0x05, 0x83,
221 0x03,
222 0x08, 0x00,
223 0xFF,
224
225 /* Data Class Interface Descriptor Requirement */
226 0x09, 0x04, 0x01,
227 0x00,
228 0x02,
229 0x0A, 0x00, 0x00,
230 0x00,
231
232 /* Endpoint 0x02 descriptor */
233 0x07, 0x05, 0x02, /* @ 103 - 14 + 2 = 91 */
234 0x02,
235 0x40, 0x00,
236 0x00,
237
238 /* Endpoint 0x81 descriptor */
239 0x07, 0x05, 0x81, /* @ 103 - 7 + 2 = 98 */
240 0x02,
241 0x40, 0x00,
242 0x00,
243
244 };
245
246 #define DEVICE_FRAMEWORK_EPA_POS_1_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 14 + 2)
247 #define DEVICE_FRAMEWORK_EPA_POS_2_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 7 + 2)
248
249 static unsigned char string_framework[] = {
250
251 /* Manufacturer string descriptor : Index 1 - "Express Logic" */
252 0x09, 0x04, 0x01, 0x0c,
253 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
254 0x6f, 0x67, 0x69, 0x63,
255
256 /* Product string descriptor : Index 2 - "EL Composite device" */
257 0x09, 0x04, 0x02, 0x13,
258 0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
259 0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
260 0x69, 0x63, 0x65,
261
262 /* Serial Number string descriptor : Index 3 - "0001" */
263 0x09, 0x04, 0x03, 0x04,
264 0x30, 0x30, 0x30, 0x31
265 };
266
267
268 /* Multiple languages are supported on the device, to add
269 a language besides english, the unicode language code must
270 be appended to the language_id_framework array and the length
271 adjusted accordingly. */
272 static unsigned char language_id_framework[] = {
273
274 /* English. */
275 0x09, 0x04
276 };
277
278 /* Setup requests */
279
280 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
281
282 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
283 /* function, request to match,
284 port action, port status,
285 request action, request EP, request data, request actual length, request status,
286 status, additional callback,
287 no_return */
288 { UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
289 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
290 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
291 UX_SUCCESS, ux_test_hcd_entry_set_cfg,
292 UX_TRUE}, /* Invoke callback & continue */
293 { 0 }
294 };
295
296 /* Define the ISR dispatch. */
297
298 extern VOID (*test_isr_dispatch)(void);
299
300
301 /* Prototype for test control return. */
302
303 void test_control_return(UINT status);
304
305
306 /* Define the ISR dispatch routine. */
307
test_isr(void)308 static void test_isr(void)
309 {
310
311 /* For further expansion of interrupt-level testing. */
312 }
313
error_callback(UINT system_level,UINT system_context,UINT error_code)314 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
315 {
316
317 error_callback_counter ++;
318
319 if (!error_callback_ignore)
320 {
321 {
322 /* Failed test. */
323 printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
324 test_control_return(1);
325 }
326 }
327 }
328
sleep_break_on_error(VOID)329 static UINT sleep_break_on_error(VOID)
330 {
331
332 if (error_callback_counter >= 3)
333 return error_callback_counter;
334
335 return UX_SUCCESS;
336 }
337
demo_class_cdc_acm_get(void)338 static UINT demo_class_cdc_acm_get(void)
339 {
340
341 UINT status;
342 UX_HOST_CLASS *class;
343 UX_HOST_CLASS_CDC_ACM *cdc_acm_host;
344
345
346 /* Find the main cdc_acm container */
347 status = ux_host_stack_class_get(_ux_system_host_class_cdc_acm_name, &class);
348 if (status != UX_SUCCESS)
349 return(status);
350
351 /* We get the first instance of the cdc_acm device */
352 do
353 {
354
355 status = ux_host_stack_class_instance_get(class, 0, (void **) &cdc_acm_host);
356 #if defined(UX_HOST_STANDALONE)
357 ux_system_tasks_run();
358 #else
359 tx_thread_sleep(10);
360 #endif
361 } while (status != UX_SUCCESS);
362
363 /* We still need to wait for the cdc_acm status to be live */
364 while (cdc_acm_host -> ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
365 {
366 #if defined(UX_HOST_STANDALONE)
367 ux_system_tasks_run();
368 #else
369 tx_thread_sleep(10);
370 #endif
371 }
372
373 /* Isolate both the control and data interfaces. */
374 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
375 {
376 /* This is the data interface. */
377 cdc_acm_host_data = cdc_acm_host;
378
379 /* In that case, the second one should be the control interface. */
380 status = ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
381
382 /* Check error. */
383 if (status != UX_SUCCESS)
384 return(status);
385
386 /* Check for the control interfaces. */
387 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
388 {
389
390 /* This is the control interface. */
391 cdc_acm_host_control = cdc_acm_host;
392
393 return(UX_SUCCESS);
394
395 }
396 }
397 else
398 {
399 /* Check for the control interfaces. */
400 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
401 {
402
403 /* This is the control interface. */
404 cdc_acm_host_control = cdc_acm_host;
405
406 /* In that case, the second one should be the data interface. */
407 status = ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
408
409 /* Check error. */
410 if (status != UX_SUCCESS)
411 return(status);
412
413 /* Check for the data interface. */
414 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
415 {
416
417 /* This is the data interface. */
418 cdc_acm_host_data = cdc_acm_host;
419
420 return(UX_SUCCESS);
421
422 }
423 }
424 }
425
426 /* Return ERROR. */
427 return(UX_ERROR);
428 }
429
demo_system_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)430 static UINT demo_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
431 {
432
433 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
434
435 switch(event)
436 {
437
438 case UX_DEVICE_INSERTION:
439
440 if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
441 cdc_acm_host_control = cdc_acm;
442 else
443 cdc_acm_host_data = cdc_acm;
444 break;
445
446 case UX_DEVICE_REMOVAL:
447
448 if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
449 cdc_acm_host_control = UX_NULL;
450 else
451 cdc_acm_host_data = UX_NULL;
452 break;
453
454 #if defined(UX_HOST_STANDALONE)
455 case UX_STANDALONE_WAIT_BACKGROUND_TASK:
456 tx_thread_relinquish();
457 break;
458 #endif
459
460 default:
461 break;
462 }
463 return 0;
464 }
465
test_cdc_instance_activate(VOID * cdc_instance)466 static VOID test_cdc_instance_activate(VOID *cdc_instance)
467 {
468
469 /* Save the CDC instance. */
470 cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
471 }
test_cdc_instance_deactivate(VOID * cdc_instance)472 static VOID test_cdc_instance_deactivate(VOID *cdc_instance)
473 {
474
475 /* Reset the CDC instance. */
476 cdc_acm_slave = UX_NULL;
477 }
478
test_cdc_instance_parameter_change(VOID * cdc_instance)479 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
480 {
481
482 /* Set CDC parameter change flag. */
483 cdc_acm_slave_change = UX_TRUE;
484 }
485
test_swap_framework_bulk_ep_descriptors(VOID)486 static VOID test_swap_framework_bulk_ep_descriptors(VOID)
487 {
488 UCHAR tmp;
489
490 tmp = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS];
491 device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS] = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS];
492 device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS] = tmp;
493
494 tmp = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS];
495 device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS] = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS];
496 device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS] = tmp;
497 }
498
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * _params)499 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *_params)
500 {
501
502 set_cfg_counter ++;
503
504 rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
505
506 rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
507 rsc_sem_get_on_set_cfg = ux_test_utility_sim_sem_get_count();
508 rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
509 }
510
511 /* Define what the initial system looks like. */
512
513 #ifdef CTEST
test_application_define(void * first_unused_memory)514 void test_application_define(void *first_unused_memory)
515 #else
516 void usbx_standalone_cdc_acm_basic_memory_test_application_define(void *first_unused_memory)
517 #endif
518 {
519
520 UINT status;
521 CHAR * stack_pointer;
522 CHAR * memory_pointer;
523
524 /* Inform user. */
525 printf("Running STANDALONE CDC ACM Basic Memory Test........................ ");
526
527 /* Reset testing counts. */
528 ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
529 ux_test_utility_sim_mem_alloc_count_reset();
530 ux_test_utility_sim_mutex_create_count_reset();
531 ux_test_utility_sim_sem_create_count_reset();
532 ux_test_utility_sim_sem_get_count_reset();
533 /* Reset error generations */
534 ux_test_utility_sim_sem_error_generation_stop();
535 ux_test_utility_sim_mutex_error_generation_stop();
536 ux_test_utility_sim_sem_get_error_generation_stop();
537
538 /* Initialize the free memory pointer */
539 stack_pointer = (CHAR *) usbx_memory;
540 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
541
542 /* Initialize USBX Memory */
543 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
544
545 /* Check for error. */
546 if (status != UX_SUCCESS)
547 {
548
549 printf("ERROR #1\n");
550 test_control_return(1);
551 }
552
553 /* Register the error callback. */
554 _ux_utility_error_callback_register(error_callback);
555
556 /* The code below is required for installing the host portion of USBX */
557 status = ux_host_stack_initialize(demo_system_host_change_function);
558 if (status != UX_SUCCESS)
559 {
560
561 printf("ERROR #2\n");
562 test_control_return(1);
563 }
564
565 /* Register CDC-ACM class. */
566 status = ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
567 if (status != UX_SUCCESS)
568 {
569
570 printf("ERROR #3\n");
571 test_control_return(1);
572 }
573
574 /* The code below is required for installing the device portion of USBX. No call back for
575 device status change in this example. */
576 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
577 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
578 string_framework, STRING_FRAMEWORK_LENGTH,
579 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
580 if(status!=UX_SUCCESS)
581 {
582
583 printf("ERROR #5\n");
584 test_control_return(1);
585 }
586
587 /* Set the parameters for callback when insertion/extraction of a CDC device. */
588 parameter.ux_slave_class_cdc_acm_instance_activate = test_cdc_instance_activate;
589 parameter.ux_slave_class_cdc_acm_instance_deactivate = test_cdc_instance_deactivate;
590 parameter.ux_slave_class_cdc_acm_parameter_change = test_cdc_instance_parameter_change;
591
592 /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
593 status = ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
594 1,0, ¶meter);
595
596 if(status!=UX_SUCCESS)
597 {
598
599 printf("ERROR #6\n");
600 test_control_return(1);
601 }
602
603 /* Initialize the simulated device controller. */
604 status = _ux_dcd_sim_slave_initialize();
605
606 /* Check for error. */
607 if (status != TX_SUCCESS)
608 {
609
610 printf("ERROR #7\n");
611 test_control_return(1);
612 }
613
614 /* Register all the USB host controllers available in this system */
615 status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
616 if (status != UX_SUCCESS)
617 {
618
619 printf("ERROR #4\n");
620 test_control_return(1);
621 }
622
623 /* Create the main host simulation thread. */
624 status = tx_thread_create(&ux_test_thread_host_simulation, "tx demo host simulation", ux_test_thread_host_simulation_entry, 0,
625 stack_pointer, UX_DEMO_STACK_SIZE,
626 20, 20, 1, TX_AUTO_START);
627
628 /* Check for error. */
629 if (status != TX_SUCCESS)
630 {
631
632 printf("ERROR #8\n");
633 test_control_return(1);
634 }
635
636 /* Create the main slave simulation thread. */
637 status = tx_thread_create(&ux_test_thread_slave_simulation, "tx demo slave simulation", ux_test_thread_slave_simulation_entry, 0,
638 stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
639 20, 20, 1, TX_AUTO_START);
640
641 /* Check for error. */
642 if (status != TX_SUCCESS)
643 {
644
645 printf("ERROR #9\n");
646 test_control_return(1);
647 }
648 }
649
ux_test_thread_host_simulation_entry(ULONG arg)650 void ux_test_thread_host_simulation_entry(ULONG arg)
651 {
652
653 UINT status;
654 UX_SLAVE_CLASS_CDC_ACM * cdc_acm_slave_bak;
655 UX_HOST_CLASS_CDC_ACM * cdc_acm_host_ctrl_bak;
656 UX_HOST_CLASS_CDC_ACM * cdc_acm_host_data_bak;
657 ULONG test_n;
658 ULONG mem_free;
659 ULONG retry;
660
661 stepinfo("\n");
662
663 /* Find the cdc_acm class and wait for the link to be up. */
664 status = demo_class_cdc_acm_get();
665 if (status != UX_SUCCESS)
666 {
667
668 /* CDC ACM basic test error. */
669 printf("ERROR #10\n");
670 test_control_return(1);
671 }
672
673 /* Save slave instance for later tests. */
674 cdc_acm_slave_bak = cdc_acm_slave;
675 /* Save host instances for later tests. */
676 cdc_acm_host_ctrl_bak = cdc_acm_host_control;
677 cdc_acm_host_data_bak = cdc_acm_host_data;
678
679 /* Test disconnect. */
680 ux_test_dcd_sim_slave_disconnect();
681 ux_test_hcd_sim_host_disconnect();
682
683 /* Reset testing counts. */
684 ux_test_utility_sim_mem_alloc_count_reset();
685 ux_test_utility_sim_mutex_create_count_reset();
686 ux_test_utility_sim_sem_create_count_reset();
687 ux_test_utility_sim_sem_get_count_reset();
688 ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
689
690 /* Save free memory usage. */
691 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
692 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
693 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
694 for (retry = 0; (retry < 10) && (cdc_acm_host_control == UX_NULL || cdc_acm_host_data == UX_NULL); retry ++)
695 tx_thread_sleep(10);
696
697 /* Log create counts for further tests. */
698 rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
699 rsc_enum_sem_usage = rsc_sem_on_set_cfg;
700 rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
701 /* Log create counts when instances active for further tests. */
702 rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
703 rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
704 rsc_cdc_mem_alloc_count = ux_test_utility_sim_mem_alloc_count() - rsc_enum_mem_alloc_count;
705
706 /* Lock log base for tests. */
707 ux_test_utility_sim_mem_alloc_log_lock();
708
709 stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
710 stepinfo("cdc mem : %ld\n", rsc_cdc_mem_alloc_count);
711 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);
712
713 /* Simulate detach and attach for FS enumeration,
714 and check if there is memory error in normal enumeration.
715 */
716 stepinfo(">>>>>>>>>>>> Enumeration test\n");
717 mem_free = (~0);
718 for (test_n = 0; test_n < 3; test_n++)
719 {
720 stepinfo("%4ld / 2\n", test_n);
721
722 /* Disconnect. */
723 ux_test_dcd_sim_slave_disconnect();
724 ux_test_hcd_sim_host_disconnect();
725
726 /* Update memory free level (disconnect) */
727 if (mem_free == (~0))
728 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
729 else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
730 {
731
732 printf("ERROR #11.%ld: Memory level different after re-enumerations %ld <> %ld\n", test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
733 test_control_return(1);
734 }
735
736 /* Connect. */
737 error_callback_counter = 0;
738 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
739 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
740
741 /* Wait and break on error. */
742 ux_test_breakable_sleep(100, sleep_break_on_error);
743
744 /* Check */
745 if (!cdc_acm_host_control || !cdc_acm_host_data)
746 {
747
748 printf("ERROR #12.%ld: Enumeration fail\n", test_n);
749 test_control_return(1);
750 }
751 }
752
753 /* Simulate detach and attach for FS enumeration,
754 and test possible memory allocation error handlings.
755 */
756 if (rsc_cdc_mem_alloc_count) stepinfo(">>>>>>>>>>>> Memory errors enumeration test\n");
757 mem_free = (~0);
758 for (test_n = 0; test_n < rsc_cdc_mem_alloc_count; test_n ++)
759 {
760
761 stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_mem_alloc_count - 1);
762
763 /* Disconnect. */
764 ux_test_dcd_sim_slave_disconnect();
765 ux_test_hcd_sim_host_disconnect();
766
767 /* Update memory free level (disconnect) */
768 if (mem_free == (~0))
769 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
770 else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
771 {
772
773 printf("ERROR #11.%ld: Memory level different after re-enumerations %ld <> %ld\n", test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
774 test_control_return(1);
775 }
776
777 /* Set memory error generation */
778 ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
779
780 /* Connect. */
781 error_callback_counter = 0;
782 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
783 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
784
785 /* Wait and break on errors. */
786 ux_test_breakable_sleep(100, sleep_break_on_error);
787
788 /* Check error */
789 if (cdc_acm_host_control && cdc_acm_host_data)
790 {
791
792 printf("ERROR #12.%ld: device detected when there is memory error\n", test_n);
793 test_control_return(1);
794 }
795 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
796 }
797 ux_test_utility_sim_mem_alloc_error_generation_stop();
798 if (rsc_cdc_mem_alloc_count) stepinfo("\n");
799
800 /* Finally disconnect the device. */
801 ux_device_stack_disconnect();
802
803 /* And deinitialize the class. */
804 status = ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
805
806 /* Deinitialize the device side of usbx. */
807 _ux_device_stack_uninitialize();
808
809 /* And finally the usbx system resources. */
810 _ux_system_uninitialize();
811
812 /* Successful test. */
813 printf("SUCCESS!\n");
814 test_control_return(0);
815
816 }
817
ux_test_thread_slave_simulation_entry(ULONG arg)818 void ux_test_thread_slave_simulation_entry(ULONG arg)
819 {
820
821 while(1)
822 {
823
824 /* Keep running device stack tasks. */
825 ux_system_tasks_run();
826 tx_thread_relinquish();
827 }
828 }
829