test_usb_host_plugging.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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/timers.h"
  10. #include "esp_err.h"
  11. #include "esp_intr_alloc.h"
  12. #include "test_usb_common.h"
  13. #include "test_usb_mock_classes.h"
  14. #include "msc_client.h"
  15. #include "ctrl_client.h"
  16. #include "usb/usb_host.h"
  17. #include "unity.h"
  18. #include "test_utils.h"
  19. // --------------------------------------------------- Test Cases ------------------------------------------------------
  20. //Safe approximation of time it takes to connect and enumerate the device
  21. #define TEST_FORCE_DCONN_DELAY_MS 400
  22. static void trigger_dconn_timer_cb(TimerHandle_t xTimer)
  23. {
  24. printf("Forcing Sudden Disconnect\n");
  25. test_usb_force_conn_state(false, 0);
  26. }
  27. TEST_CASE("Test USB Host sudden disconnection (no client)", "[usb_host][ignore]")
  28. {
  29. //Install USB Host Library
  30. usb_host_config_t host_config = {
  31. .intr_flags = ESP_INTR_FLAG_LEVEL1,
  32. };
  33. ESP_ERROR_CHECK(usb_host_install(&host_config));
  34. printf("Installed\n");
  35. //Allocate timer to force disconnection after a short delay
  36. TimerHandle_t timer_hdl = xTimerCreate("dconn",
  37. pdMS_TO_TICKS(TEST_FORCE_DCONN_DELAY_MS),
  38. pdFALSE,
  39. NULL,
  40. trigger_dconn_timer_cb);
  41. TEST_ASSERT_NOT_EQUAL(NULL, timer_hdl);
  42. TEST_ASSERT_EQUAL(pdPASS, xTimerStart(timer_hdl, portMAX_DELAY));
  43. while (1) {
  44. //Start handling system events
  45. uint32_t event_flags;
  46. usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
  47. if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
  48. printf("All devices cleaned up\n");
  49. break;
  50. }
  51. }
  52. //Cleanup timer
  53. TEST_ASSERT_EQUAL(pdPASS, xTimerDelete(timer_hdl, portMAX_DELAY));
  54. //Clean up USB Host
  55. ESP_ERROR_CHECK(usb_host_uninstall());
  56. }
  57. #define TEST_FORCE_DCONN_NUM_TRANSFERS 3
  58. #define TEST_MSC_SCSI_TAG 0xDEADBEEF
  59. TEST_CASE("Test USB Host sudden disconnection (single client)", "[usb_host][ignore]")
  60. {
  61. //Install USB Host
  62. usb_host_config_t host_config = {
  63. .intr_flags = ESP_INTR_FLAG_LEVEL1,
  64. };
  65. ESP_ERROR_CHECK(usb_host_install(&host_config));
  66. printf("Installed\n");
  67. //Create task to run client that communicates with MSC SCSI interface
  68. msc_client_test_param_t params = {
  69. .num_sectors_to_read = 1, //Unused by disconnect MSC client
  70. .num_sectors_per_xfer = TEST_FORCE_DCONN_NUM_TRANSFERS * MOCK_MSC_SCSI_SECTOR_SIZE,
  71. .msc_scsi_xfer_tag = TEST_MSC_SCSI_TAG,
  72. .idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR,
  73. .idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT,
  74. };
  75. TaskHandle_t task_hdl;
  76. xTaskCreatePinnedToCore(msc_client_async_dconn_task, "async", 4096, (void *)&params, 2, &task_hdl, 0);
  77. //Start the task
  78. xTaskNotifyGive(task_hdl);
  79. bool all_clients_gone = false;
  80. bool all_dev_free = false;
  81. while (!all_clients_gone || !all_dev_free) {
  82. //Start handling system events
  83. uint32_t event_flags;
  84. usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
  85. if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
  86. printf("No more clients\n");
  87. all_clients_gone = true;
  88. }
  89. if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
  90. printf("All device's freed\n");
  91. all_dev_free = true;
  92. }
  93. }
  94. //Short delay to allow task to be cleaned up
  95. vTaskDelay(10);
  96. //Clean up USB Host
  97. ESP_ERROR_CHECK(usb_host_uninstall());
  98. }