From 2f593e767c28ac5b789a5def2221620c1a2e58b8 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Mar 2022 12:26:56 +0700 Subject: [PATCH] update use of mutex for host --- src/device/usbd.c | 2 +- src/host/usbh.c | 96 +++++++++++++++++++++++++++-------------------- src/tusb_option.h | 3 ++ 3 files changed, 59 insertions(+), 42 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 7926689b7..b14b5e0fc 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -273,7 +273,7 @@ enum { RHPORT_INVALID = 0xFFu }; static uint8_t _usbd_rhport = RHPORT_INVALID; // Event queue -// OPT_MODE_DEVICE is used by OS NONE for mutex (disable usb isr) +// usbd_int_set() is used as mutex in OS NONE config OSAL_QUEUE_DEF(usbd_int_set, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t); static osal_queue_t _usbd_q; diff --git a/src/host/usbh.c b/src/host/usbh.c index 74c763552..59fcb4da3 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -112,13 +112,6 @@ typedef struct { // TODO merge ep2drv here, 4-bit should be sufficient }ep_status[CFG_TUH_ENDPOINT_MAX][2]; - - // Mutex for claiming endpoint, only needed when using with preempted RTOS -#if CFG_TUSB_OS != OPT_OS_NONE - osal_mutex_def_t mutexdef; - osal_mutex_t mutex; -#endif - } usbh_device_t; @@ -204,6 +197,9 @@ enum { CONFIG_NUM = 1 }; // default to use configuration 1 // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ +// sum of end device + hub +#define TOTAL_DEVICES (CFG_TUH_DEVICE_MAX + CFG_TUH_HUB) + static bool _usbh_initialized = false; // Device with address = 0 for enumeration @@ -211,14 +207,43 @@ static usbh_dev0_t _dev0; // all devices excluding zero-address // hub address start from CFG_TUH_DEVICE_MAX+1 -CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[CFG_TUH_DEVICE_MAX + CFG_TUH_HUB]; +// TODO: hub can has its own simpler struct to save memory +CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[TOTAL_DEVICES]; + +// Mutex for claiming endpoint, only needed when using with preempted RTOS +#if TUSB_OPT_MUTEX + +static osal_mutex_def_t _usbh_mutexdef[TOTAL_DEVICES]; +static osal_mutex_t _usbh_mutex[TOTAL_DEVICES]; + +static inline void lock_device(uint8_t daddr) +{ + // addr0 is always available + if (daddr) return; + osal_mutex_lock(&_usbh_mutex[daddr-1], OSAL_TIMEOUT_WAIT_FOREVER); +} + +static inline void unlock_device(uint8_t daddr) +{ + // addr0 is always available + if (daddr) return; + osal_mutex_unlock(&_usbh_mutex[daddr-1]); +} + +#else + +#define lock_device(_addr) +#define unlock_device(_addr) + +#endif // Event queue -// role device/host is used by OS NONE for mutex (disable usb isr) +// usbh_int_set is used as mutex in OS NONE config OSAL_QUEUE_DEF(usbh_int_set, _usbh_qdef, CFG_TUH_TASK_QUEUE_SZ, hcd_event_t); static osal_queue_t _usbh_q; -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN +static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; //------------- Helper Function -------------// @@ -408,6 +433,13 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_comple // CLASS-USBD API (don't require to verify parameters) //--------------------------------------------------------------------+ +static void clear_device(usbh_device_t* dev) +{ + tu_memclr(dev, sizeof(usbh_device_t)); + memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping + memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping +} + bool tuh_inited(void) { return _usbh_initialized; @@ -421,25 +453,22 @@ bool tuh_init(uint8_t rhport) TU_LOG2("USBH init\r\n"); TU_LOG2_INT(sizeof(usbh_device_t)); - tu_memclr(_usbh_devices, sizeof(_usbh_devices)); - tu_memclr(&_dev0, sizeof(_dev0)); - //------------- Enumeration & Reporter Task init -------------// _usbh_q = osal_queue_create( &_usbh_qdef ); TU_ASSERT(_usbh_q != NULL); //------------- Semaphore, Mutex for Control Pipe -------------// - for(uint8_t i=0; imutex = osal_mutex_create(&dev->mutexdef); - TU_ASSERT(dev->mutex); +#if TUSB_OPT_MUTEX + _usbh_mutex[i] = osal_mutex_create(&_usbh_mutexdef[i]); + TU_ASSERT(_usbh_mutex[i]); #endif - - memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping - memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping } // Class drivers init @@ -686,14 +715,7 @@ void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port } hcd_device_close(rhport, dev_addr); - - // release all endpoints associated with the device - memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping - memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping - tu_memclr(dev->ep_status, sizeof(dev->ep_status)); - - dev->state = TUSB_DEVICE_STATE_UNPLUG; - dev->configured = false; + clear_device(dev); } } } @@ -1161,11 +1183,9 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) usbh_device_t* dev = get_device(dev_addr); -#if CFG_TUSB_OS != OPT_OS_NONE // pre-check to help reducing mutex lock TU_VERIFY((dev->ep_status[epnum][dir].busy == 0) && (dev->ep_status[epnum][dir].claimed == 0)); - osal_mutex_lock(dev->mutex, OSAL_TIMEOUT_WAIT_FOREVER); -#endif + lock_device(dev_addr); // can only claim the endpoint if it is not busy and not claimed yet. bool const ret = (dev->ep_status[epnum][dir].busy == 0) && (dev->ep_status[epnum][dir].claimed == 0); @@ -1174,9 +1194,7 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) dev->ep_status[epnum][dir].claimed = 1; } -#if CFG_TUSB_OS != OPT_OS_NONE - osal_mutex_unlock(dev->mutex); -#endif + unlock_device(dev_addr); return ret; } @@ -1189,9 +1207,7 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) usbh_device_t* dev = get_device(dev_addr); -#if CFG_TUSB_OS != OPT_OS_NONE - osal_mutex_lock(dev->mutex, OSAL_TIMEOUT_WAIT_FOREVER); -#endif + lock_device(dev_addr); // can only release the endpoint if it is claimed and not busy bool const ret = (dev->ep_status[epnum][dir].busy == 0) && (dev->ep_status[epnum][dir].claimed == 1); @@ -1200,9 +1216,7 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) dev->ep_status[epnum][dir].claimed = 0; } -#if CFG_TUSB_OS != OPT_OS_NONE - osal_mutex_unlock(dev->mutex); -#endif + unlock_device(dev_addr); return ret; } diff --git a/src/tusb_option.h b/src/tusb_option.h index afd69c38b..e5351b1c4 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -285,6 +285,9 @@ #define CFG_TUSB_OS_INC_PATH #endif +// mutex is only needed for RTOS +#define TUSB_OPT_MUTEX (CFG_TUSB_OS != OPT_OS_NONE) + //-------------------------------------------------------------------- // DEVICE OPTIONS //--------------------------------------------------------------------