test_usb_host_async.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdio.h>
  7. #include "freertos/FreeRTOS.h"
  8. #include "freertos/task.h"
  9. #include "freertos/semphr.h"
  10. #include "esp_err.h"
  11. #include "esp_intr_alloc.h"
  12. #include "test_usb_mock_classes.h"
  13. #include "msc_client.h"
  14. #include "ctrl_client.h"
  15. #include "usb/usb_host.h"
  16. #include "unity.h"
  17. #include "test_utils.h"
  18. #define TEST_MSC_NUM_SECTORS_TOTAL 10
  19. #define TEST_MSC_NUM_SECTORS_PER_XFER 2
  20. #define TEST_MSC_SCSI_TAG 0xDEADBEEF
  21. #define TEST_CTRL_NUM_TRANSFERS 30
  22. // --------------------------------------------------- Test Cases ------------------------------------------------------
  23. /*
  24. Test USB Host Asynchronous API single client
  25. Requires: This test requires an MSC SCSI device to be attached (see the MSC mock class)
  26. Purpose:
  27. - Test that USB Host Asynchronous API works correctly with a single client
  28. - Test that a client can be created
  29. - Test that client can operate concurrently in a separate thread
  30. - Test that the main thread is able to detect library events (such as USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS)
  31. Procedure:
  32. - Install USB Host Library
  33. - Create a task to run an MSC client
  34. - Start the MSC client task. It will execute a bunch of MSC SCSI sector reads
  35. - Wait for the host library event handler to report a USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS event
  36. - Free all devices
  37. - Uninstall USB Host Library
  38. */
  39. TEST_CASE("Test USB Host async (single client)", "[usb_host][ignore]")
  40. {
  41. //Install USB Host
  42. usb_host_config_t host_config = {
  43. .intr_flags = ESP_INTR_FLAG_LEVEL1,
  44. };
  45. ESP_ERROR_CHECK(usb_host_install(&host_config));
  46. printf("Installed\n");
  47. //Create task to run client that communicates with MSC SCSI interface
  48. msc_client_test_param_t params = {
  49. .num_sectors_to_read = TEST_MSC_NUM_SECTORS_TOTAL,
  50. .num_sectors_per_xfer = TEST_MSC_NUM_SECTORS_PER_XFER,
  51. .msc_scsi_xfer_tag = TEST_MSC_SCSI_TAG,
  52. .idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR,
  53. .idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT,
  54. };
  55. TaskHandle_t task_hdl;
  56. xTaskCreatePinnedToCore(msc_client_async_seq_task, "async", 4096, (void *)&params, 2, &task_hdl, 0);
  57. //Start the task
  58. xTaskNotifyGive(task_hdl);
  59. while (1) {
  60. //Start handling system events
  61. uint32_t event_flags;
  62. usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
  63. if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
  64. printf("No more clients\n");
  65. TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_device_free_all());
  66. }
  67. if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
  68. break;
  69. }
  70. }
  71. //Short delay to allow task to be cleaned up
  72. vTaskDelay(10);
  73. //Clean up USB Host
  74. ESP_ERROR_CHECK(usb_host_uninstall());
  75. }
  76. /*
  77. Test USB Host Asynchronous API with multiple clients
  78. Requires: This test requires an MSC SCSI device to be attached (see the MSC mock class)
  79. Purpose:
  80. - Test the USB Host Asynchronous API works correctly with multiple clients
  81. - Test that multiple clients can be created
  82. - Test that multiple clients can operate concurrently in separate threads
  83. - Test that the main thread is able to detect library events (such as USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS)
  84. Procedure:
  85. - Install USB Host Library
  86. - Create separate tasks to run an MSC client and Ctrl Client
  87. - MSC Client will execute a bunch of MSC SCSI sector reads
  88. - Ctrl Client will execute a bunch of control transfers
  89. - Wait for the host library event handler to report a USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS event
  90. - Free all devices
  91. - Uninstall USB Host Library
  92. */
  93. TEST_CASE("Test USB Host async (multi client)", "[usb_host][ignore]")
  94. {
  95. //Install USB Host
  96. usb_host_config_t host_config = {
  97. .intr_flags = ESP_INTR_FLAG_LEVEL1,
  98. };
  99. ESP_ERROR_CHECK(usb_host_install(&host_config));
  100. printf("Installed\n");
  101. //Create task to run the MSC client
  102. msc_client_test_param_t msc_params = {
  103. .num_sectors_to_read = TEST_MSC_NUM_SECTORS_TOTAL,
  104. .num_sectors_per_xfer = TEST_MSC_NUM_SECTORS_PER_XFER,
  105. .msc_scsi_xfer_tag = TEST_MSC_SCSI_TAG,
  106. .idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR,
  107. .idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT,
  108. };
  109. TaskHandle_t msc_task_hdl;
  110. xTaskCreatePinnedToCore(msc_client_async_seq_task, "msc", 4096, (void *)&msc_params, 2, &msc_task_hdl, 0);
  111. //Create task a control transfer client
  112. ctrl_client_test_param_t ctrl_params = {
  113. .num_ctrl_xfer_to_send = TEST_CTRL_NUM_TRANSFERS,
  114. .idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR,
  115. .idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT,
  116. };
  117. TaskHandle_t ctrl_task_hdl;
  118. xTaskCreatePinnedToCore(ctrl_client_async_seq_task, "ctrl", 4096, (void *)&ctrl_params, 2, &ctrl_task_hdl, 0);
  119. //Start both tasks
  120. xTaskNotifyGive(msc_task_hdl);
  121. xTaskNotifyGive(ctrl_task_hdl);
  122. while (1) {
  123. //Start handling system events
  124. uint32_t event_flags;
  125. usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
  126. if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
  127. printf("No more clients\n");
  128. TEST_ASSERT_EQUAL(ESP_ERR_NOT_FINISHED, usb_host_device_free_all());
  129. }
  130. if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
  131. break;
  132. }
  133. }
  134. //Short delay to allow task to be cleaned up
  135. vTaskDelay(10);
  136. //Clean up USB Host
  137. ESP_ERROR_CHECK(usb_host_uninstall());
  138. }