Skip to content

Commit

Permalink
Merge #19371
Browse files Browse the repository at this point in the history
19371: sys/usbus: check for the number of required and provided EPs in static configurations r=dylad a=gschorcht

### Contribution description

This PR provides a static check at compile time whether the number of EPs required in a static configuration does not exceed the number of EPs provided by the USB device.

#### Background

In issue #19359 the problem was reported that `usbus_cdc_ecm` didn't work together with `stdio_cdc_acm` on some STM32 boards. The reason for some of the boards was simply that the application tried to allocate more EPs than available and simply ignored this and just didn't work.

#### Solution

Since `auto_init_usb` uses a static configuration with exactly one USBUS stack instance and one USB device, at least in case `auto_init` is used a static check can be carried out to make sure that the number of EPs required by the application doesn't exceed the number of EPs provided by the USB device. For this purpose, each `usbus_*` module defines the number of IN and OUT EPs required by that module. Each USB device driver defines the number of EPs provided by USB device if it differs from the default of 8 EPs. During the auto initialization the total number of required IN and OUT EPs is then compared with the number of EPs provided by the USB device using a static assert.

### Testing procedure

1. Green CI
2. Compilation of
   ```python
   USEMODULE='stdio_cdc_acm' BOARD=nucleo-f439zi make -j8 -C tests/usbus_cdc_ecm
   ```
   should lead to compilation error
   ```python
   sys/auto_init/usb/auto_init_usb.c:81:1: error: static assertion failed: "Number of required IN endpoints exceeded"
    _Static_assert(USBUS_EP_IN_REQUIRED_NUMOF <= USBDEV_NUM_ENDPOINTS,
    ^~~~~~~~~~~~~~
   Makefile.base:146: recipe for target 'tests/usbus_cdc_ecm/bin/nucleo-f439zi/auto_init_usbus/auto_init_usb.o' failed
   ```
   while compilation of
   ```
   USEMODULE='stdio_cdc_acm' BOARD=nucleo-f767zi make -j8 -C tests/usbus_cdc_ecm
   ```
   should work.

### Issues/PRs references

Fixes issue #19359 partially.

Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
  • Loading branch information
bors[bot] and gschorcht authored Mar 11, 2023
2 parents 19da279 + ade0c95 commit 4041a12
Show file tree
Hide file tree
Showing 12 changed files with 173 additions and 22 deletions.
7 changes: 7 additions & 0 deletions cpu/efm32/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,13 @@ typedef struct {
#define WDT_HAS_STOP (1U)
/** @} */

/**
* @name USB device definitions
* @{
*/
#define USBDEV_NUM_ENDPOINTS 7 /**< Number of USB OTG FS endpoints including EP0 */
/** @} */

/* GPIO_LL's overrides */
#ifndef DOXYGEN

Expand Down
5 changes: 5 additions & 0 deletions cpu/esp32/include/periph_cpu_esp32s2.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,11 @@ extern "C" {
* @brief Buffers have to be word aligned for DMA
*/
#define USBDEV_CPU_DMA_ALIGNMENT (4)

/**
* @brief Number of USB IN and OUT endpoints available
*/
#define USBDEV_NUM_ENDPOINTS DWC2_USB_OTG_FS_NUM_EP
/** @} */


Expand Down
5 changes: 5 additions & 0 deletions cpu/esp32/include/periph_cpu_esp32s3.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,11 @@ extern "C" {
* @brief Buffers have to be word aligned for DMA
*/
#define USBDEV_CPU_DMA_ALIGNMENT (4)

/**
* @brief Number of USB IN and OUT endpoints available
*/
#define USBDEV_NUM_ENDPOINTS DWC2_USB_OTG_FS_NUM_EP
/** @} */

#ifdef __cplusplus
Expand Down
7 changes: 7 additions & 0 deletions cpu/gd32v/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,13 @@ typedef struct {
#define RTT_MIN_FREQUENCY (1U) /**< minimum RTT frequency in Hz */
/** @} */

/**
* @name USB device definitions
* @{
*/
#define USBDEV_NUM_ENDPOINTS 4 /**< Number of USB OTG FS endpoints including EP0 */
/** @} */

/**
* @brief Enable the given peripheral clock
*
Expand Down
51 changes: 51 additions & 0 deletions cpu/stm32/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,57 @@ typedef struct {
#define HAVE_PTP_TIMER_SET_ABSOLUTE 1 /**< Native implementation available */
/** @} */

#if !DOXYGEN /* hide implementation details */
/**
* @name USB device definitions
* @{
*/
/* Detect the IP version based on the available register define */
#if defined(USB_OTG_GCCFG_NOVBUSSENS)
#define STM32_USB_OTG_CID_1x /**< USB OTG FS version 0x00001200 */
#elif defined(USB_OTG_GCCFG_VBDEN)
#define STM32_USB_OTG_CID_2x /**< USB OTG FS version 0x00002000 */
#elif defined(USB)
#define STM32_USB_FS_CID_1x /**< USB FS version 0x00001200 */
#endif

/**
* @brief Number of endpoints available with the OTG FS peripheral
* including the control endpoint
*/
#ifdef STM32_USB_OTG_CID_1x
#define STM32_USB_OTG_FS_NUM_EP (4) /**< OTG FS with 4 endpoints */
#elif defined(STM32_USB_OTG_CID_2x)
#define STM32_USB_OTG_FS_NUM_EP (6) /**< OTG FS with 6 endpoints */
#endif

/**
* @brief Number of endpoints available with the OTG HS peripheral
* including the control endpoint
*/
#ifdef STM32_USB_OTG_CID_1x
#define STM32_USB_OTG_HS_NUM_EP (6) /**< OTG HS with 6 endpoints */
#elif defined(STM32_USB_OTG_CID_2x)
#define STM32_USB_OTG_HS_NUM_EP (9) /**< OTG HS with 9 endpoints */
#endif

/**
* @brief Number of IN/OUT endpoints including EP0 as used by USBUS
*
* @note Since only a single number of EPs can be defined for USBUS that is
* valid for all devices, the smallest number of EPs must be used for
* multiple USB devices.
*/
#if defined(STM32_USB_OTG_FS_NUM_EP)
#define USBDEV_NUM_ENDPOINTS STM32_USB_OTG_FS_NUM_EP
#elif defined(STM32_USB_OTG_HS_NUM_EP)
#define USBDEV_NUM_ENDPOINTS STM32_USB_OTG_HS_NUM_EP
#else
#define USBDEV_NUM_ENDPOINTS 8
#endif

#endif /* !DOXYGEN */

#ifdef __cplusplus
}
#endif
Expand Down
27 changes: 5 additions & 22 deletions cpu/stm32/include/usbdev_stm32.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,42 +41,22 @@
#include <stdint.h>
#include <stdlib.h>
#include "periph_cpu.h"
#include "periph/usbdev.h"

#ifdef __cplusplus
extern "C" {
#endif

/* Detect the IP version based on the available register define */
#if defined(USB_OTG_GCCFG_NOVBUSSENS)
#define STM32_USB_OTG_CID_1x /**< USB OTG FS version 0x00001200 */
#elif defined(USB_OTG_GCCFG_VBDEN)
#define STM32_USB_OTG_CID_2x /**< USB OTG FS version 0x00002000 */
#elif defined(USB)
#define STM32_USB_FS_CID_1x /**< USB FS version 0x00001200 */
#else
#error Unknown USB peripheral version
#endif

/**
* @brief Number of endpoints available with the OTG FS peripheral
* including the control endpoint
*/
#ifdef STM32_USB_OTG_CID_1x
#define DWC2_USB_OTG_FS_NUM_EP (4) /**< OTG FS with 4 endpoints */
#elif defined(STM32_USB_OTG_CID_2x)
#define DWC2_USB_OTG_FS_NUM_EP (6) /**< OTG FS with 6 endpoints */
#endif
#define DWC2_USB_OTG_FS_NUM_EP STM32_USB_OTG_FS_NUM_EP

/**
* @brief Number of endpoints available with the OTG HS peripheral
* including the control endpoint
*/
#ifdef STM32_USB_OTG_CID_1x
#define DWC2_USB_OTG_HS_NUM_EP (6) /**< OTG HS with 6 endpoints */
#elif defined(STM32_USB_OTG_CID_2x)
#define DWC2_USB_OTG_HS_NUM_EP (9) /**< OTG HS with 9 endpoints */
#endif
#define DWC2_USB_OTG_HS_NUM_EP STM32_USB_OTG_HS_NUM_EP

/**
* @brief USB OTG FS FIFO reception buffer space in 32-bit words
Expand Down Expand Up @@ -144,6 +124,9 @@ extern "C" {
#endif
#endif

/* periph/usbdev.h is included after the definitions above by intention */
#include "periph/usbdev.h"

/**
* @brief stm32 USB Device FS only peripheral device context
*/
Expand Down
43 changes: 43 additions & 0 deletions sys/auto_init/usb/auto_init_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <assert.h>

#include "usb/usbus.h"
#include "usb/usbus/control.h"

#ifdef MODULE_USBUS_CDC_ECM
#include "usb/usbus/cdc/ecm.h"
Expand All @@ -39,11 +40,53 @@ usbus_cdcecm_device_t cdcecm;
#include "usb/usbus/dfu.h"
static usbus_dfu_device_t dfu;
#endif
#ifdef MODULE_USBUS_HID
#include "usb/usbus/hid.h"
#endif
#ifdef MODULE_USBUS_MSC
#include "usb/usbus/msc.h"
static usbus_msc_device_t msc;
#endif

#ifndef MODULE_USBUS_CDC_ACM
#define USBUS_CDC_ACM_EP_IN_REQUIRED_NUMOF 0
#define USBUS_CDC_ACM_EP_OUT_REQUIRED_NUMOF 0
#endif

#ifndef MODULE_USBUS_CDC_ECM
#define USBUS_CDC_ECM_EP_IN_REQUIRED_NUMOF 0
#define USBUS_CDC_ECM_EP_OUT_REQUIRED_NUMOF 0
#endif

#ifndef MODULE_USBUS_HID
#define USBUS_HID_EP_IN_REQUIRED_NUMOF 0
#define USBUS_HID_EP_OUT_REQUIRED_NUMOF 0
#endif

#ifndef MODULE_USBUS_MSC
#define USBUS_MSC_EP_IN_REQUIRED_NUMOF 0
#define USBUS_MSC_EP_OUT_REQUIRED_NUMOF 0
#endif

#define USBUS_EP_IN_REQUIRED_NUMOF (USBUS_CONTROL_EP_IN_REQUIRED_NUMOF + \
USBUS_CDC_ACM_EP_IN_REQUIRED_NUMOF + \
USBUS_CDC_ECM_EP_IN_REQUIRED_NUMOF + \
USBUS_HID_EP_IN_REQUIRED_NUMOF + \
USBUS_MSC_EP_IN_REQUIRED_NUMOF)

#define USBUS_EP_OUT_REQUIRED_NUMOF (USBUS_CONTROL_EP_OUT_REQUIRED_NUMOF + \
USBUS_CDC_ACM_EP_OUT_REQUIRED_NUMOF + \
USBUS_CDC_ECM_EP_OUT_REQUIRED_NUMOF + \
USBUS_HID_EP_OUT_REQUIRED_NUMOF + \
USBUS_MSC_EP_OUT_REQUIRED_NUMOF)

static_assert(USBUS_EP_IN_REQUIRED_NUMOF <= USBDEV_NUM_ENDPOINTS,
"Number of required IN endpoints exceeded");

static_assert(USBUS_EP_OUT_REQUIRED_NUMOF <= USBDEV_NUM_ENDPOINTS,
"Number of required OUT endpoints exceeded");


static char _stack[USBUS_STACKSIZE];
static usbus_t usbus;

Expand Down
10 changes: 10 additions & 0 deletions sys/include/usb/hid.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@ extern "C" {
#define USB_HID_REQUEST_SET_PROTOCOL 0x0b
/** @} */

/**
* @brief Number of IN EPs required for the HID interface
*/
#define USBUS_HID_EP_IN_REQUIRED_NUMOF 1

/**
* @brief Number of Out EPs required for the HID interface
*/
#define USBUS_HID_EP_OUT_REQUIRED_NUMOF 1

/**
* @brief USB HID descriptor struct
*
Expand Down
10 changes: 10 additions & 0 deletions sys/include/usb/usbus/cdc/acm.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ extern "C" {
*/
#define USBUS_CDC_ACM_INT_EP_SIZE (8)

/**
* @brief Number of IN EPs required for the CDC ACM interface
*/
#define USBUS_CDC_ACM_EP_IN_REQUIRED_NUMOF 2

/**
* @brief Number of Out EPs required for the CDC ACM interface
*/
#define USBUS_CDC_ACM_EP_OUT_REQUIRED_NUMOF 1

/**
* @brief CDC ACM line state as reported by the host computer
*/
Expand Down
10 changes: 10 additions & 0 deletions sys/include/usb/usbus/cdc/ecm.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@ extern "C" {
*/
#define USBUS_ETHERNET_FRAME_BUF MATH_ALIGN(ETHERNET_FRAME_LEN, USBUS_CDCECM_EP_DATA_SIZE)

/**
* @brief Number of IN EPs required for the CDC ECM interface
*/
#define USBUS_CDC_ECM_EP_IN_REQUIRED_NUMOF 2

/**
* @brief Number of Out EPs required for the CDC ECM interface
*/
#define USBUS_CDC_ECM_EP_OUT_REQUIRED_NUMOF 1

/**
* @brief notification state, used to track which information must be send to
* the host
Expand Down
10 changes: 10 additions & 0 deletions sys/include/usb/usbus/control.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@
#ifndef USB_USBUS_CONTROL_H
#define USB_USBUS_CONTROL_H

/**
* @brief Number of IN EPs required for the control interface
*/
#define USBUS_CONTROL_EP_IN_REQUIRED_NUMOF 1

/**
* @brief Number of IN EPs required for the control interface
*/
#define USBUS_CONTROL_EP_OUT_REQUIRED_NUMOF 1

#include "usb/usbus.h"

#ifdef __cplusplus
Expand Down
10 changes: 10 additions & 0 deletions sys/include/usb/usbus/msc.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@
extern "C" {
#endif

/**
* @brief Number of IN EPs required for the MSC interface
*/
#define USBUS_MSC_EP_IN_REQUIRED_NUMOF 1

/**
* @brief Number of Out EPs required for the MSC interface
*/
#define USBUS_MSC_EP_OUT_REQUIRED_NUMOF 1

/**
* @brief USBUS MSC Number of exported MTD device through USB
*/
Expand Down

0 comments on commit 4041a12

Please sign in to comment.