feat(usb_host): Individual USB Host stack layers mocking

- Individual CMocks for separate USB Host layers
    - Allowing to test USB Host layers separately
    - Mocks: Full USB stack, USB Host, USBH
This commit is contained in:
peter.marcisovsky
2025-03-25 09:42:57 +01:00
parent 53e84d9729
commit 18ae6c38a9
13 changed files with 160 additions and 1 deletions

View File

@ -1,6 +1,8 @@
# NOTE: This kind of mocking currently works on Linux targets only.
# On Espressif chips, too many dependencies are missing at the moment.
message(STATUS "building USB HOST MOCKS")
# Full USB Host mock
message(STATUS "building full USB HOST MOCKS")
idf_component_get_property(original_usb_dir usb COMPONENT_OVERRIDEN_DIR)

View File

@ -0,0 +1,4 @@
# Full USB Host stack mock
This mock mocks all the USB Host stack layers, none of the USB Host stack layers are used as real.
This mock is useful for mock testing of the layers above the USB Host stack, EG USB Host Class drivers.

View File

@ -0,0 +1,26 @@
# NOTE: This kind of mocking currently works on Linux targets only.
# On Espressif chips, too many dependencies are missing at the moment.
# USB Host layer mock
message(STATUS "building USB HOST Layer MOCKS")
idf_component_get_property(original_usb_dir usb COMPONENT_OVERRIDEN_DIR)
idf_component_mock(INCLUDE_DIRS "${original_usb_dir}/include"
"${original_usb_dir}/include/esp_private"
"${original_usb_dir}/include/usb"
"${original_usb_dir}/private_include"
MOCK_HEADER_FILES ${original_usb_dir}/private_include/enum.h
${original_usb_dir}/private_include/hcd.h
${original_usb_dir}/private_include/hub.h
${original_usb_dir}/private_include/usbh.h
${original_usb_dir}/include/esp_private/usb_phy.h
REQUIRES freertos)
# We do not mock usb_host.c, we use the original implementation of it
target_sources(${COMPONENT_LIB} PRIVATE "${original_usb_dir}/usb_host.c")
# Original implementation of usb_private.c to allocate memory for transfers
target_sources(${COMPONENT_LIB} PRIVATE "${original_usb_dir}/usb_private.c")
# We do not mock usb_helpers. We use the original implementation
# This way, we can test descriptor parsing
target_sources(${COMPONENT_LIB} PRIVATE "${original_usb_dir}/usb_helpers.c")

View File

@ -0,0 +1,14 @@
# Config item from the original USB component needed for this CMock build
menu "USB Host Layer mock"
config USB_HOST_CONTROL_TRANSFER_MAX_SIZE
int "Largest size (in bytes) of transfers to/from default endpoints"
default 256
help
Each USB device attached is allocated a dedicated buffer for its OUT/IN transfers to/from the device's
control endpoint. The maximum size of that buffer is determined by this option. The limited size of the
transfer buffer have the following implications:
- The maximum length of control transfers is limited
- Device's with configuration descriptors larger than this limit cannot be supported
endmenu

View File

@ -0,0 +1,4 @@
# USB Host layer mock
This mock mocks all the USB layers below the USB Host layer. USB Host layer is used as a real component.
This mock is useful for mock testing of the USB Host layer, as all the below layers are mocked.

View File

@ -0,0 +1,7 @@
:cmock:
:plugins:
- expect
- expect_any_args
- return_thru_ptr
- ignore
- ignore_arg

View File

@ -0,0 +1,23 @@
# NOTE: This kind of mocking currently works on Linux targets only.
# On Espressif chips, too many dependencies are missing at the moment.
# USBH Layer mock
message(STATUS "building USBH Layer MOCKS")
idf_component_get_property(original_usb_dir usb COMPONENT_OVERRIDEN_DIR)
idf_component_mock(INCLUDE_DIRS "${original_usb_dir}/include"
"${original_usb_dir}/include/esp_private"
"${original_usb_dir}/include/usb"
"${original_usb_dir}/private_include"
MOCK_HEADER_FILES ${original_usb_dir}/private_include/hcd.h
${original_usb_dir}/private_include/usb_private.h
REQUIRES freertos)
# We do not mock usbh.c, we use the original implementation of it
target_sources(${COMPONENT_LIB} PRIVATE "${original_usb_dir}/usbh.c")
# Additionally, we include following src files from the above layers
target_sources(${COMPONENT_LIB} PRIVATE "${original_usb_dir}/usb_host.c")
target_sources(${COMPONENT_LIB} PRIVATE "${original_usb_dir}/enum.c")
target_sources(${COMPONENT_LIB} PRIVATE "${original_usb_dir}/hub.c")

View File

@ -0,0 +1,68 @@
# Config items from the original USB component needed for this CMock build
menu "USBH Layer mock"
config USB_HOST_CONTROL_TRANSFER_MAX_SIZE
int "Largest size (in bytes) of transfers to/from default endpoints"
default 256
help
Each USB device attached is allocated a dedicated buffer for its OUT/IN transfers to/from the device's
control endpoint. The maximum size of that buffer is determined by this option. The limited size of the
transfer buffer have the following implications:
- The maximum length of control transfers is limited
- Device's with configuration descriptors larger than this limit cannot be supported
menu "Hub Driver Configuration"
menu "Root Port configuration"
config USB_HOST_DEBOUNCE_DELAY_MS
int "Debounce delay in ms"
default 250
help
On connection of a USB device, the USB 2.0 specification requires
a "debounce interval with a minimum duration of 100ms" to allow the connection to stabilize
(see USB 2.0 chapter 7.1.7.3 for more details).
During the debounce interval, no new connection/disconnection events are registered.
The default value is set to 250 ms to be safe.
config USB_HOST_RESET_HOLD_MS
int "Reset hold in ms"
default 30
help
The reset signaling can be generated on any Hub or Host Controller port by request from
the USB System Software. The USB 2.0 specification requires that "the reset signaling must
be driven for a minimum of 10ms" (see USB 2.0 chapter 7.1.7.5 for more details).
After the reset, the hub port will transition to the Enabled state (refer to Section 11.5).
The default value is set to 30 ms to be safe.
config USB_HOST_RESET_RECOVERY_MS
int "Reset recovery delay in ms"
default 30
help
After a port stops driving the reset signal, the USB 2.0 specification requires that
the "USB System Software guarantees a minimum of 10 ms for reset recovery" before the
attached device is expected to respond to data transfers (see USB 2.0 chapter 7.1.7.3 for
more details).
The device may ignore any data transfers during the recovery interval.
The default value is set to 30 ms to be safe.
config USB_HOST_SET_ADDR_RECOVERY_MS
int "SetAddress() recovery time in ms"
default 10
help
"After successful completion of the Status stage, the device is allowed a SetAddress()
recovery interval of 2 ms. At the end of this interval, the device must be able to accept
Setup packets addressed to the new address. Also, at the end of the recovery interval, the
device must not respond to tokens sent to the old address (unless, of course, the old and new
address is the same)." See USB 2.0 chapter 9.2.6.3 for more details.
The default value is set to 10 ms to be safe.
endmenu #Root Hub configuration
endmenu #Hub Driver Configuration
endmenu

View File

@ -0,0 +1,4 @@
# USBH layer mock
This mock mocks all the USB layers below the USBH layer. USBH layer is used as a real component.
This mock is useful for mock testing of the USBH layer, as all the below layers are mocked.

View File

@ -0,0 +1,7 @@
:cmock:
:plugins:
- expect
- expect_any_args
- return_thru_ptr
- ignore
- ignore_arg