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 
14 #include "ux_host_class_cdc_acm.h"
15 
16 #include "ux_test_dcd_sim_slave.h"
17 #include "ux_test_hcd_sim_host.h"
18 #include "ux_test_utility_sim.h"
19 
20 #include "ux_host_stack.h"
21 
22 /* Define constants.  */
23 #define                             UX_DEMO_DEBUG_SIZE  (4096*8)
24 #define                             UX_DEMO_STACK_SIZE  1024
25 #define                             UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
26 #define                             UX_DEMO_XMIT_BUFFER_SIZE 512
27 #define                             UX_DEMO_RECEPTION_BUFFER_SIZE 512
28 #define                             UX_DEMO_FILE_BUFFER_SIZE 512
29 #define                             UX_DEMO_RECEPTION_BLOCK_SIZE 64
30 #define                             UX_DEMO_MEMORY_SIZE     (64*1024)
31 #define                             UX_DEMO_FILE_SIZE       (128 * 1024)
32 #define                             UX_RAM_DISK_MEMORY      (256 * 1024)
33 
34 #define     LSB(x) ( (x) & 0x00ff)
35 #define     MSB(x) (((x) & 0xff00) >> 8)
36 
37 /* Configuration descriptor 9 bytes */
38 #define CFG_DESC(wTotalLength, bNumInterfaces, bmAttributes, bConfigurationValue)\
39     /* Configuration 1 descriptor 9 bytes */\
40     0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
41     (bNumInterfaces), (bConfigurationValue), 0x00,\
42     (bmAttributes), 0x00,
43 #define CFG_DESC_LEN 9
44 
45 #define IAD_DESC(bIfc) \
46     /* Interface association descriptor. 8 bytes.  */\
47     0x08, 0x0b, (bIfc), 0x02, 0x02, 0x02, 0x00, 0x00,
48 #define IAD_DESC_LEN 8
49 
50 #define CDC_IFC_DESC_ALL(bIfc, bIntIn, bBulkIn, bBulkOut)\
51     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */\
52     0x09, 0x04, (bIfc), 0x00, 0x01, 0x02, 0x02, 0x01, 0x00,\
53     /* Header Functional Descriptor 5 bytes */\
54     0x05, 0x24, 0x00, 0x10, 0x01,\
55     /* ACM Functional Descriptor 4 bytes */\
56     0x04, 0x24, 0x02, 0x0f,\
57     /* Union Functional Descriptor 5 bytes */\
58     0x05, 0x24, 0x06, (bIfc), (bIfc + 1),\
59     /* Call Management Functional Descriptor 5 bytes */\
60     0x05, 0x24, 0x01, 0x03, (bIfc + 1),\
61     /* Endpoint interrupt in descriptor 7 bytes */\
62     0x07, 0x05, (bIntIn), 0x03, 0x40, 0x00, 0x10,\
63     /* Data Class Interface Descriptor Requirement 9 bytes */\
64     0x09, 0x04, (bIfc + 1), 0x00, 0x02, 0x0A, 0x00, 0x00, 0x00,\
65     /* Endpoint bulk in descriptor 7 bytes */\
66     0x07, 0x05, (bBulkIn), 0x02, 0x40, 0x00, 0x01,\
67     /* Endpoint bulk out descriptor 7 bytes */\
68     0x07, 0x05, (bBulkOut), 0x02, 0x40, 0x00, 0x01,
69 #define CDC_IFC_DESC_ALL_LEN (9+5+4+5+5+7+ 9+7+7)
70 
71 /* Define local/extern function prototypes.  */
72 static VOID                                test_thread_entry(ULONG);
73 static TX_THREAD                           tx_test_thread_simulation_0;
74 static TX_THREAD                           tx_test_thread_simulation_1;
75 static VOID                                tx_test_thread_simulation_0_entry(ULONG);
76 static VOID                                tx_test_thread_simulation_1_entry(ULONG);
77 static VOID                                test_cdc_instance_activate(VOID  *cdc_instance);
78 static VOID                                test_cdc_instance_deactivate(VOID *cdc_instance);
79 static VOID                                test_cdc_instance_parameter_change(VOID *cdc_instance);
80 
81 /* Define global data structures.  */
82 static UCHAR                               usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
83 static UX_HOST_CLASS                       *class_driver;
84 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_control;
85 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_data;
86 
87 static UX_SLAVE_CLASS_CDC_ACM              *cdc_acm_slave;
88 static UCHAR                               cdc_acm_slave_change;
89 static UX_SLAVE_CLASS_CDC_ACM_PARAMETER    parameter;
90 
91 static ULONG                               error_counter;
92 
93 static ULONG                               error_callback_counter;
94 static UCHAR                               error_callback_ignore;
95 
96 static UCHAR                               buffer[UX_DEMO_BUFFER_SIZE];
97 
98 static ULONG                               test_thread_action;
99 
100 /* Define device framework.  */
101 
102 static unsigned char device_framework_full_speed[] = {
103 
104     /* Device descriptor     18 bytes
105        0x02 bDeviceClass:    CDC class code
106        0x00 bDeviceSubclass: CDC class sub code
107        0x00 bDeviceProtocol: CDC Device protocol
108 
109        idVendor & idProduct - http://www.linux-usb.org/usb.ids
110     */
111     0x12, 0x01, 0x10, 0x01,
112     0xEF, 0x02, 0x01,
113     0x08,
114     0x84, 0x84, 0x00, 0x00,
115     0x00, 0x01,
116     0x01, 0x02, 03,
117     0x01, /* bNumConfigurations */
118 
119     /* Configuration 1 descriptor 9 bytes, total 75 bytes */
120     CFG_DESC(CFG_DESC_LEN + IAD_DESC_LEN + CDC_IFC_DESC_ALL_LEN, 2, 0x40, 1)
121     /* IAD 8 bytes */
122     IAD_DESC(0)
123     /* CDC_ACM interfaces */
124     CDC_IFC_DESC_ALL(0, 0x83, 0x81, 0x02)
125 };
126 #define             DEVICE_FRAMEWORK_LENGTH_FULL_SPEED      sizeof(device_framework_full_speed)
127 
128 static unsigned char device_framework_high_speed[] = {
129 
130     /* Device descriptor     18 bytes
131        0x02 bDeviceClass:    CDC class code
132        0x00 bDeviceSubclass: CDC class sub code
133        0x00 bDeviceProtocol: CDC Device protocol
134 
135        idVendor & idProduct - http://www.linux-usb.org/usb.ids
136     */
137     0x12, 0x01, 0x00, 0x02,
138     0xEF, 0x02, 0x01,
139     0x40,
140     0x84, 0x84, 0x00, 0x00,
141     0x00, 0x01,
142     0x01, 0x02, 03,
143     0x01, /* bNumConfigurations */
144 
145     /* Device qualifier descriptor 10 bytes */
146     0x0a, 0x06, 0x00, 0x02,
147     0x02, 0x00, 0x00,
148     0x40,
149     0x01,
150     0x00,
151 
152     /* Configuration 1 descriptor 9 bytes, total 75-8=67 bytes */
153     CFG_DESC(CFG_DESC_LEN + CDC_IFC_DESC_ALL_LEN, 2, 0x60, 1)
154     CDC_IFC_DESC_ALL(0, 0x83, 0x81, 0x02)
155 };
156 #define             DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED      sizeof(device_framework_high_speed)
157 
158 static unsigned char string_framework[] = {
159 
160     /* Manufacturer string descriptor : Index 1 - "Express Logic" */
161     0x09, 0x04, 0x01, 0x0c,
162     0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
163     0x6f, 0x67, 0x69, 0x63,
164 
165     /* Product string descriptor : Index 2 - "EL Composite device" */
166     0x09, 0x04, 0x02, 0x13,
167     0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
168     0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
169     0x69, 0x63, 0x65,
170 
171     /* Serial Number string descriptor : Index 3 - "0001" */
172     0x09, 0x04, 0x03, 0x04,
173     0x30, 0x30, 0x30, 0x31
174 };
175 #define             STRING_FRAMEWORK_LENGTH                 sizeof(string_framework)
176 
177 /* Multiple languages are supported on the device, to add
178     a language besides english, the unicode language code must
179     be appended to the language_id_framework array and the length
180     adjusted accordingly. */
181 static unsigned char language_id_framework[] = {
182 
183     /* English. */
184     0x09, 0x04
185 };
186 #define             LANGUAGE_ID_FRAMEWORK_LENGTH            sizeof(language_id_framework)
187 
disconnect_after_mutex_on_action_func(struct UX_TEST_ACTION_STRUCT * action,VOID * params)188 static VOID disconnect_after_mutex_on_action_func(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
189 {
190     _ux_system_slave->ux_system_slave_device.ux_slave_device_state = UX_DEVICE_ADDRESSED;
191 }
192 
193 static UX_TEST_HCD_SIM_ACTION disconnect_after_mutex_on[] = {
194     {
195         .do_after = UX_TRUE,
196         .usbx_function = UX_TEST_OVERRIDE_TX_MUTEX_GET,
197         .wait_option = TX_WAIT_FOREVER,
198         .action_func = disconnect_after_mutex_on_action_func,
199     },
200     { 0 }
201 };
202 
203 /* Define the ISR dispatch.  */
204 
205 extern VOID    (*test_isr_dispatch)(void);
206 
207 
208 /* Prototype for test control return.  */
209 
210 void  test_control_return(UINT status);
211 
212 
213 /* Define the ISR dispatch routine.  */
214 
test_isr(void)215 static void    test_isr(void)
216 {
217 
218     /* For further expansion of interrupt-level testing.  */
219 }
220 
break_on_cdc_acm_all_ready(VOID)221 static UINT break_on_cdc_acm_all_ready(VOID)
222 {
223 UINT                                 status;
224 UINT                                 i;
225 UX_HOST_CLASS                       *class;
226 UX_HOST_CLASS_CDC_ACM               *cdc_acm;
227 
228     /* Find the main cdc_acm container */
229     status = ux_host_stack_class_get(_ux_system_host_class_cdc_acm_name, &class);
230     if (status != UX_SUCCESS)
231         /* Do not break. */
232         return 0;
233 
234     /* Find class instances. */
235     for (i = 0; i < 2; i ++)
236     {
237         status = ux_host_stack_class_instance_get(class, i, (void **) &cdc_acm);
238         if (status != UX_SUCCESS)
239             /* Do not break. */
240             return 0;
241 
242         switch(cdc_acm->ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass)
243         {
244 
245         case UX_HOST_CLASS_CDC_CONTROL_CLASS:
246             cdc_acm_host_control = cdc_acm;
247             break;
248 
249         case UX_HOST_CLASS_CDC_DATA_CLASS:
250             cdc_acm_host_data = cdc_acm;
251             break;
252 
253         default:
254             break;
255         }
256     }
257 
258     if (cdc_acm_host_control == UX_NULL || cdc_acm_host_data == UX_NULL)
259         /* Do not break. */
260         return 0;
261 
262     if (cdc_acm_host_control->ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
263         /* Do not break. */
264         return 0;
265 
266     if (cdc_acm_host_data->ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
267         /* Do not break. */
268         return 0;
269 
270     if (_ux_system_slave->ux_system_slave_class_array[0].ux_slave_class_instance == UX_NULL)
271         /* Do not break. */
272         return 0;
273 
274     cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *)_ux_system_slave->ux_system_slave_class_array[0].ux_slave_class_instance;
275 
276     /* All found, break. */
277     return 1;
278 }
279 
break_on_removal(VOID)280 static UINT break_on_removal(VOID)
281 {
282 
283 UINT                     status;
284 UX_DEVICE               *device;
285 
286     status = ux_host_stack_device_get(0, &device);
287     if (status == UX_SUCCESS)
288         /* Do not break. */
289         return UX_SUCCESS;
290 
291     if (_ux_system_slave->ux_system_slave_class_array[0].ux_slave_class_instance != UX_NULL)
292         /* Do not break. */
293         return 0;
294 
295     cdc_acm_host_data = UX_NULL;
296     cdc_acm_host_control = UX_NULL;
297     cdc_acm_slave = UX_NULL;
298 
299     return 1;
300 }
301 
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)302 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
303 {
304 
305 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
306 
307     switch(event)
308     {
309 
310         case UX_DEVICE_INSERTION:
311 
312             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
313                 cdc_acm_host_control = cdc_acm;
314             else
315                 cdc_acm_host_data = cdc_acm;
316             break;
317 
318         case UX_DEVICE_REMOVAL:
319 
320             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
321                 cdc_acm_host_control = UX_NULL;
322             else
323                 cdc_acm_host_data = UX_NULL;
324             break;
325 
326         default:
327             break;
328     }
329     return 0;
330 }
331 
test_cdc_instance_activate(VOID * cdc_instance)332 static VOID    test_cdc_instance_activate(VOID *cdc_instance)
333 {
334 
335     /* Save the CDC instance.  */
336     cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
337 }
test_cdc_instance_deactivate(VOID * cdc_instance)338 static VOID    test_cdc_instance_deactivate(VOID *cdc_instance)
339 {
340 
341     /* Reset the CDC instance.  */
342     cdc_acm_slave = UX_NULL;
343 }
344 
test_cdc_instance_parameter_change(VOID * cdc_instance)345 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
346 {
347 
348     /* Set CDC parameter change flag. */
349     cdc_acm_slave_change = UX_TRUE;
350 }
351 
test_ux_error_callback(UINT system_level,UINT system_context,UINT error_code)352 static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
353 {
354     error_callback_counter ++;
355 
356     if (!error_callback_ignore)
357     {
358         {
359             /* Failed test.  */
360             // printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
361             // test_control_return(1);
362         }
363     }
364 }
365 
366 /* Define what the initial system looks like.  */
367 
368 #ifdef CTEST
test_application_define(void * first_unused_memory)369 void test_application_define(void *first_unused_memory)
370 #else
371 void usbx_ux_device_class_cdc_acm_write_test_application_define(void *first_unused_memory)
372 #endif
373 {
374 
375 UINT                    status;
376 CHAR *                  stack_pointer;
377 CHAR *                  memory_pointer;
378 
379     printf("Running ux_device_class_cdc_acm_write Test.......................... ");
380     stepinfo("\n");
381 
382     /* Initialize the free memory pointer */
383     stack_pointer = (CHAR *) usbx_memory;
384     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
385 
386     /* Initialize USBX Memory */
387     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
388     /* Check for error.  */
389     if (status != UX_SUCCESS)
390     {
391 
392         printf("ERROR #%d\n", __LINE__);
393         test_control_return(1);
394     }
395 
396     /* Register the error callback. */
397     _ux_utility_error_callback_register(test_ux_error_callback);
398 
399     /* The code below is required for installing the host portion of USBX */
400     status =  ux_host_stack_initialize(UX_NULL);
401     if (status != UX_SUCCESS)
402     {
403 
404         printf("ERROR #%d\n", __LINE__);
405         test_control_return(1);
406     }
407 
408     /* Register CDC ACM class */
409     status =  ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
410     if (status != UX_SUCCESS)
411     {
412 
413         printf("ERROR #%d\n", __LINE__);
414         test_control_return(1);
415     }
416 
417     /* The code below is required for installing the device portion of USBX. No call back for
418        device status change in this example. */
419     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
420                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
421                                        string_framework, STRING_FRAMEWORK_LENGTH,
422                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
423     if(status!=UX_SUCCESS)
424     {
425 
426         printf("ERROR #%d\n", __LINE__);
427         test_control_return(1);
428     }
429 
430     /* Set the parameters for callback when insertion/extraction of a CDC device.  */
431     parameter.ux_slave_class_cdc_acm_instance_activate   =  UX_NULL;
432     parameter.ux_slave_class_cdc_acm_instance_deactivate =  UX_NULL;
433     parameter.ux_slave_class_cdc_acm_parameter_change    =  test_cdc_instance_parameter_change;
434 
435     /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
436     status  =  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
437                                              1,0,  &parameter);
438     status |= ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
439                                              2,0,  &parameter);
440     status |= ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
441                                              3,0,  &parameter);
442 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
443     if(status!=UX_SUCCESS)
444     {
445 
446         printf("ERROR #%d\n", __LINE__);
447         test_control_return(1);
448     }
449 #endif
450 
451     /* Initialize the simulated device controller.  */
452     status =  _ux_test_dcd_sim_slave_initialize();
453 
454     /* Check for error.  */
455     if (status != TX_SUCCESS)
456     {
457 
458         printf("ERROR #%d\n", __LINE__);
459         test_control_return(1);
460     }
461 
462     /* Register HCD for test */
463     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
464     if (status != UX_SUCCESS)
465     {
466 
467         printf("ERROR #%d\n", __LINE__);
468         test_control_return(1);
469     }
470 
471     /* Create the main host simulation thread.  */
472     status =  tx_thread_create(&tx_test_thread_simulation_0, "tx test host simulation", tx_test_thread_simulation_0_entry, 0,
473             stack_pointer, UX_DEMO_STACK_SIZE,
474             20, 20, 1, TX_AUTO_START);
475 
476     /* Check for error.  */
477     if (status != TX_SUCCESS)
478     {
479 
480         printf("ERROR #%d\n", __LINE__);
481         test_control_return(1);
482     }
483 
484     /* Create the main slave simulation  thread.  */
485     status =  tx_thread_create(&tx_test_thread_simulation_1, "tx test slave simulation", tx_test_thread_simulation_1_entry, 0,
486             stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
487             20, 20, 1, TX_NO_ACTIVATE);
488 
489     /* Check for error.  */
490     if (status != TX_SUCCESS)
491     {
492 
493         printf("ERROR #%d\n", __LINE__);
494         test_control_return(1);
495     }
496 }
497 
tx_test_thread_simulation_0_entry(ULONG arg)498 void  tx_test_thread_simulation_0_entry(ULONG arg)
499 {
500 
501 UINT                                                i;
502 
503     /* Test connect. */
504     stepinfo(">>>>>>>>>>>>>>>> Test connect (FS)\n");
505     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
506     ux_test_breakable_sleep(100, break_on_cdc_acm_all_ready);
507     if (!(cdc_acm_host_control && cdc_acm_host_data && cdc_acm_slave))
508     {
509 
510         printf("ERROR #%d: connect fail\n", __LINE__);
511         test_control_return(1);
512     }
513     if (_ux_system_slave->ux_system_slave_device.ux_slave_device_state != UX_DEVICE_CONFIGURED)
514     {
515 
516         printf("ERROR %d: device state fail 0x%lx\n", __LINE__, _ux_system_slave->ux_system_slave_device.ux_slave_device_state);
517         test_control_return(1);
518     }
519 
520     /* Test write. */
521     stepinfo(">>>>>>>>>>>>>>>> Test write disconnect after mutex_on\n");
522 
523     test_thread_action = 1;
524     tx_thread_resume(&tx_test_thread_simulation_1);
525 
526     for (i = 0; i < 10; i ++)
527     {
528         if (test_thread_action < 2)
529             _ux_utility_delay_ms(10);
530     }
531     if (test_thread_action < 2)
532     {
533         printf("ERROR %d: test no progress\n", __LINE__);
534         error_counter ++;
535     }
536 
537     /* Restore state. */
538     _ux_system_slave->ux_system_slave_device.ux_slave_device_state = UX_DEVICE_CONFIGURED;
539 
540     stepinfo(">>>>>>>>>>>>>>>> Deinitialize\n");
541 
542     /* Deinitialize the class.  */
543     ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
544     ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
545     ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
546 
547     /* Deinitialize the device side of usbx.  */
548     _ux_device_stack_uninitialize();
549 
550     /* And finally the usbx system resources.  */
551     _ux_system_uninitialize();
552 
553     stepinfo(">>>>>>>>>>>>>>>> Dump results\n");
554 
555     if (error_counter > 0)
556     {
557 
558         /* Test error.  */
559         printf("ERROR #%d: total %ld errors\n", __LINE__, error_counter);
560         test_control_return(1);
561     }
562 
563     /* Successful test.  */
564     printf("SUCCESS!\n");
565     test_control_return(0);
566 }
567 
tx_test_thread_simulation_1_entry(ULONG arg)568 void  tx_test_thread_simulation_1_entry(ULONG arg)
569 {
570 
571 UINT                                                status;
572 ULONG                                               actual_length;
573 
574     while(1)
575     {
576         if (test_thread_action == 1)
577         {
578             ux_test_set_main_action_list_from_array(disconnect_after_mutex_on);
579             status = ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, 128, &actual_length);
580             if (status == UX_SUCCESS)
581             {
582                 printf("ERROR %d: expect fail\n", __LINE__);
583                 error_counter ++;
584             }
585             test_thread_action ++;
586         }
587         tx_thread_suspend(&tx_test_thread_simulation_1);
588     }
589 }
590