use OSAL_MUTEX_REQUIRED to replace CFG_FIFO_MUTEX/TUSB_OPT_MUTEX

add macro to swallow mutex API in order to simplify code with mutex
This commit is contained in:
hathach 2022-12-15 18:03:01 +07:00
parent f4f85bad54
commit 88e6da7273
9 changed files with 67 additions and 81 deletions

View File

@ -62,10 +62,8 @@ typedef struct
uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE]; uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE];
uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE]; uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE];
#if CFG_FIFO_MUTEX OSAL_MUTEX_DEF(rx_ff_mutex);
osal_mutex_def_t rx_ff_mutex; OSAL_MUTEX_DEF(tx_ff_mutex);
osal_mutex_def_t tx_ff_mutex;
#endif
// Endpoint Transfer buffer // Endpoint Transfer buffer
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE];
@ -248,10 +246,8 @@ void cdcd_init(void)
// In this way, the most current data is prioritized. // In this way, the most current data is prioritized.
tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, true); tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, true);
#if CFG_FIFO_MUTEX
tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, osal_mutex_create(&p_cdc->rx_ff_mutex)); tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, osal_mutex_create(&p_cdc->rx_ff_mutex));
tu_fifo_config_mutex(&p_cdc->tx_ff, osal_mutex_create(&p_cdc->tx_ff_mutex), NULL); tu_fifo_config_mutex(&p_cdc->tx_ff, osal_mutex_create(&p_cdc->tx_ff_mutex), NULL);
#endif
} }
} }

View File

@ -42,15 +42,13 @@ extern "C" {
// within a certain number (see tu_fifo_overflow()). // within a certain number (see tu_fifo_overflow()).
#include "common/tusb_common.h" #include "common/tusb_common.h"
#include "osal/osal.h"
#define tu_fifo_mutex_t osal_mutex_t
// mutex is only needed for RTOS // mutex is only needed for RTOS
// for OS None, we don't get preempted // for OS None, we don't get preempted
#define CFG_FIFO_MUTEX (CFG_TUSB_OS != OPT_OS_NONE) #define CFG_FIFO_MUTEX OSAL_MUTEX_REQUIRED
#if CFG_FIFO_MUTEX
#include "osal/osal.h"
#define tu_fifo_mutex_t osal_mutex_t
#endif
typedef struct typedef struct
{ {
@ -65,7 +63,7 @@ typedef struct
volatile uint16_t wr_idx ; ///< write pointer volatile uint16_t wr_idx ; ///< write pointer
volatile uint16_t rd_idx ; ///< read pointer volatile uint16_t rd_idx ; ///< read pointer
#if CFG_FIFO_MUTEX #if OSAL_MUTEX_REQUIRED
tu_fifo_mutex_t mutex_wr; tu_fifo_mutex_t mutex_wr;
tu_fifo_mutex_t mutex_rd; tu_fifo_mutex_t mutex_rd;
#endif #endif
@ -99,13 +97,18 @@ bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable);
bool tu_fifo_clear(tu_fifo_t *f); bool tu_fifo_clear(tu_fifo_t *f);
bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable); bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable);
#if CFG_FIFO_MUTEX #if OSAL_MUTEX_REQUIRED
TU_ATTR_ALWAYS_INLINE static inline TU_ATTR_ALWAYS_INLINE static inline
void tu_fifo_config_mutex(tu_fifo_t *f, tu_fifo_mutex_t write_mutex_hdl, tu_fifo_mutex_t read_mutex_hdl) void tu_fifo_config_mutex(tu_fifo_t *f, tu_fifo_mutex_t write_mutex_hdl, tu_fifo_mutex_t read_mutex_hdl)
{ {
f->mutex_wr = write_mutex_hdl; f->mutex_wr = write_mutex_hdl;
f->mutex_rd = read_mutex_hdl; f->mutex_rd = read_mutex_hdl;
} }
#else
#define tu_fifo_config_mutex(_f, _wr_mutex, _rd_mutex)
#endif #endif
bool tu_fifo_write (tu_fifo_t* f, void const * p_data); bool tu_fifo_write (tu_fifo_t* f, void const * p_data);

View File

@ -281,6 +281,10 @@
// Default Values // Default Values
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
#ifndef TUP_MCU_MULTIPLE_CORE
#define TUP_MCU_MULTIPLE_CORE 0
#endif
#ifndef TUP_DCD_ENDPOINT_MAX #ifndef TUP_DCD_ENDPOINT_MAX
#warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8"
#define TUP_DCD_ENDPOINT_MAX 8 #define TUP_DCD_ENDPOINT_MAX 8

View File

@ -272,10 +272,12 @@ static uint8_t _usbd_rhport = RHPORT_INVALID;
OSAL_QUEUE_DEF(usbd_int_set, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t); OSAL_QUEUE_DEF(usbd_int_set, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t);
static osal_queue_t _usbd_q; static osal_queue_t _usbd_q;
// Mutex for claiming endpoint, only needed when using with preempted RTOS // Mutex for claiming endpoint
#if CFG_TUSB_OS != OPT_OS_NONE #if OSAL_MUTEX_REQUIRED
static osal_mutex_def_t _ubsd_mutexdef; static osal_mutex_def_t _ubsd_mutexdef;
static osal_mutex_t _usbd_mutex; static osal_mutex_t _usbd_mutex;
#else
#define _usbd_mutex NULL
#endif #endif
@ -389,7 +391,7 @@ bool tud_init (uint8_t rhport)
tu_varclr(&_usbd_dev); tu_varclr(&_usbd_dev);
#if CFG_TUSB_OS != OPT_OS_NONE #if OSAL_MUTEX_REQUIRED
// Init device mutex // Init device mutex
_usbd_mutex = osal_mutex_create(&_ubsd_mutexdef); _usbd_mutex = osal_mutex_create(&_ubsd_mutexdef);
TU_ASSERT(_usbd_mutex); TU_ASSERT(_usbd_mutex);
@ -1209,11 +1211,7 @@ bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr)
uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr);
tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir]; tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir];
#if TUSB_OPT_MUTEX
return tu_edpt_claim(ep_state, _usbd_mutex); return tu_edpt_claim(ep_state, _usbd_mutex);
#else
return tu_edpt_claim(ep_state, NULL);
#endif
} }
bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr) bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr)
@ -1224,11 +1222,7 @@ bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr)
uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr);
tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir]; tu_edpt_state_t* ep_state = &_usbd_dev.ep_status[epnum][dir];
#if TUSB_OPT_MUTEX
return tu_edpt_release(ep_state, _usbd_mutex); return tu_edpt_release(ep_state, _usbd_mutex);
#else
return tu_edpt_release(ep_state, NULL);
#endif
} }
bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)

View File

@ -212,28 +212,12 @@ static usbh_dev0_t _dev0;
// TODO: hub can has its own simpler struct to save memory // TODO: hub can has its own simpler struct to save memory
CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[TOTAL_DEVICES]; CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[TOTAL_DEVICES];
// Mutex for claiming endpoint, only needed when using with preempted RTOS // Mutex for claiming endpoint
#if TUSB_OPT_MUTEX #if OSAL_MUTEX_REQUIRED
static osal_mutex_def_t _usbh_mutexdef; static osal_mutex_def_t _usbh_mutexdef;
static osal_mutex_t _usbh_mutex; static osal_mutex_t _usbh_mutex;
TU_ATTR_ALWAYS_INLINE static inline void usbh_lock(void)
{
osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
}
TU_ATTR_ALWAYS_INLINE static inline void usbh_unlock(void)
{
osal_mutex_unlock(_usbh_mutex);
}
#else #else
#define _usbh_mutex NULL
#define _usbh_mutex NULL
#define usbh_lock()
#define usbh_unlock()
#endif #endif
// Event queue // Event queue
@ -277,8 +261,6 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t
// TODO rework time-related function later // TODO rework time-related function later
void osal_task_delay(uint32_t msec) void osal_task_delay(uint32_t msec)
{ {
(void) msec;
const uint32_t start = hcd_frame_number(_usbh_controller); const uint32_t start = hcd_frame_number(_usbh_controller);
while ( ( hcd_frame_number(_usbh_controller) - start ) < msec ) {} while ( ( hcd_frame_number(_usbh_controller) - start ) < msec ) {}
} }
@ -352,8 +334,8 @@ bool tuh_init(uint8_t controller_id)
_usbh_q = osal_queue_create( &_usbh_qdef ); _usbh_q = osal_queue_create( &_usbh_qdef );
TU_ASSERT(_usbh_q != NULL); TU_ASSERT(_usbh_q != NULL);
#if TUSB_OPT_MUTEX #if OSAL_MUTEX_REQUIRED
// Mutex // Init mutex
_usbh_mutex = osal_mutex_create(&_usbh_mutexdef); _usbh_mutex = osal_mutex_create(&_usbh_mutexdef);
TU_ASSERT(_usbh_mutex); TU_ASSERT(_usbh_mutex);
#endif #endif
@ -537,8 +519,7 @@ bool tuh_control_xfer (tuh_xfer_t* xfer)
uint8_t const daddr = xfer->daddr; uint8_t const daddr = xfer->daddr;
// TODO probably better to use semaphore as resource management than mutex (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
usbh_lock();
bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE); bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE);
if (is_idle) if (is_idle)
@ -553,7 +534,7 @@ bool tuh_control_xfer (tuh_xfer_t* xfer)
_ctrl_xfer.user_data = xfer->user_data; _ctrl_xfer.user_data = xfer->user_data;
} }
usbh_unlock(); (void) osal_mutex_unlock(_usbh_mutex);
TU_VERIFY(is_idle); TU_VERIFY(is_idle);
const uint8_t rhport = usbh_get_rhport(daddr); const uint8_t rhport = usbh_get_rhport(daddr);
@ -597,9 +578,9 @@ bool tuh_control_xfer (tuh_xfer_t* xfer)
TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage)
{ {
usbh_lock(); osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
_ctrl_xfer.stage = stage; _ctrl_xfer.stage = stage;
usbh_unlock(); osal_mutex_unlock(_usbh_mutex);
} }
static void _xfer_complete(uint8_t daddr, xfer_result_t result) static void _xfer_complete(uint8_t daddr, xfer_result_t result)

View File

@ -33,17 +33,24 @@
#include "common/tusb_common.h" #include "common/tusb_common.h"
// Return immediately
#define OSAL_TIMEOUT_NOTIMEOUT (0)
// Default timeout
#define OSAL_TIMEOUT_NORMAL (10)
// Wait forever
#define OSAL_TIMEOUT_WAIT_FOREVER (UINT32_MAX)
#define OSAL_TIMEOUT_CONTROL_XFER OSAL_TIMEOUT_WAIT_FOREVER
typedef void (*osal_task_func_t)( void * ); typedef void (*osal_task_func_t)( void * );
// Timeout
#define OSAL_TIMEOUT_NOTIMEOUT (0) // Return immediately
#define OSAL_TIMEOUT_NORMAL (10) // Default timeout
#define OSAL_TIMEOUT_WAIT_FOREVER (UINT32_MAX) // Wait forever
#define OSAL_TIMEOUT_CONTROL_XFER OSAL_TIMEOUT_WAIT_FOREVER
// Mutex is required when using a preempted RTOS or MCU has multiple cores
#if (CFG_TUSB_OS == OPT_OS_NONE) && !TUP_MCU_MULTIPLE_CORE
#define OSAL_MUTEX_REQUIRED 0
#define OSAL_MUTEX_DEF(_name)
#else
#define OSAL_MUTEX_REQUIRED 1
#define OSAL_MUTEX_DEF(_name) osal_mutex_def_t _name
#endif
// OS thin implementation
#if CFG_TUSB_OS == OPT_OS_NONE #if CFG_TUSB_OS == OPT_OS_NONE
#include "osal_none.h" #include "osal_none.h"
#elif CFG_TUSB_OS == OPT_OS_FREERTOS #elif CFG_TUSB_OS == OPT_OS_FREERTOS

View File

@ -82,6 +82,10 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t s
typedef osal_semaphore_def_t osal_mutex_def_t; typedef osal_semaphore_def_t osal_mutex_def_t;
typedef osal_semaphore_t osal_mutex_t; typedef osal_semaphore_t osal_mutex_t;
#if OSAL_MUTEX_REQUIRED
// Note: multiple cores MCUs usually do provide IPC API for mutex
// or we can use std atomic function
TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
{ {
mdef->count = 1; mdef->count = 1;
@ -98,6 +102,14 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd
return osal_semaphore_post(mutex_hdl, false); return osal_semaphore_post(mutex_hdl, false);
} }
#else
#define osal_mutex_create(_mdef) (NULL)
#define osal_mutex_lock(_mutex_hdl, _ms) (true)
#define osal_mutex_unlock(_mutex_hdl) (true)
#endif
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// QUEUE API // QUEUE API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+

View File

@ -74,11 +74,9 @@ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex)
{ {
(void) mutex; (void) mutex;
#if TUSB_OPT_MUTEX
// pre-check to help reducing mutex lock // pre-check to help reducing mutex lock
TU_VERIFY((ep_state->busy == 0) && (ep_state->claimed == 0)); TU_VERIFY((ep_state->busy == 0) && (ep_state->claimed == 0));
osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER);
#endif
// can only claim the endpoint if it is not busy and not claimed yet. // can only claim the endpoint if it is not busy and not claimed yet.
bool const available = (ep_state->busy == 0) && (ep_state->claimed == 0); bool const available = (ep_state->busy == 0) && (ep_state->claimed == 0);
@ -87,9 +85,7 @@ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex)
ep_state->claimed = 1; ep_state->claimed = 1;
} }
#if TUSB_OPT_MUTEX (void) osal_mutex_unlock(mutex);
osal_mutex_unlock(mutex);
#endif
return available; return available;
} }
@ -98,9 +94,7 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex)
{ {
(void) mutex; (void) mutex;
#if TUSB_OPT_MUTEX (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER);
osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER);
#endif
// can only release the endpoint if it is claimed and not busy // can only release the endpoint if it is claimed and not busy
bool const ret = (ep_state->claimed == 1) && (ep_state->busy == 0); bool const ret = (ep_state->claimed == 1) && (ep_state->busy == 0);
@ -109,9 +103,7 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex)
ep_state->claimed = 0; ep_state->claimed = 0;
} }
#if TUSB_OPT_MUTEX (void) osal_mutex_unlock(mutex);
osal_mutex_unlock(mutex);
#endif
return ret; return ret;
} }

View File

@ -299,9 +299,6 @@ typedef int make_iso_compilers_happy;
#define CFG_TUSB_OS_INC_PATH #define CFG_TUSB_OS_INC_PATH
#endif #endif
// mutex is only needed for RTOS TODO also required with multiple core MCUs
#define TUSB_OPT_MUTEX (CFG_TUSB_OS != OPT_OS_NONE)
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Device Options (Default) // Device Options (Default)
//-------------------------------------------------------------------- //--------------------------------------------------------------------