From bbda99171da8858dc5cd6f4a305c63801e42faab Mon Sep 17 00:00:00 2001 From: ranchuan Date: Tue, 30 Sep 2025 16:45:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=91=E9=80=81=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/device/net_lwip_webserver/src/main.c | 28 +++++++++++---- src/class/net/ncm_device.c | 2 +- src/device/usbd.c | 35 +++++++++++++++++++ src/device/usbd_pvt.h | 2 +- src/osal/osal.h | 1 + 5 files changed, 59 insertions(+), 9 deletions(-) diff --git a/examples/device/net_lwip_webserver/src/main.c b/examples/device/net_lwip_webserver/src/main.c index c12c0a31e..ee92d6ad0 100644 --- a/examples/device/net_lwip_webserver/src/main.c +++ b/examples/device/net_lwip_webserver/src/main.c @@ -57,6 +57,7 @@ try changing the first byte of tud_network_mac_address[] below from 0x02 to 0x00 #include "bsp/board_api.h" #include "tusb.h" +#include "usbd_pvt.h" #include "dhserver.h" #include "dnserver.h" @@ -103,6 +104,23 @@ static const dhcp_config_t dhcp_config = { entries /* entries */ }; + + + + +static int tud_output_fn(void *t){ + struct pbuf *p = t; + /* if the network driver can accept another packet, we make it happen */ + if (tud_network_can_xmit(p->tot_len)) { + tud_network_xmit(p, 0 /* unused for this example */); + return ERR_OK; + } + return ERR_USE; +} + + + + static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) { (void) netif; @@ -110,13 +128,8 @@ static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) { /* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */ if (!tud_ready()) return ERR_USE; - - /* if the network driver can accept another packet, we make it happen */ - if (tud_network_can_xmit(p->tot_len)) { - tud_network_xmit(p, 0 /* unused for this example */); - return ERR_OK; - } - return ERR_USE; + /*rc this packet will be sent in usbd task */ + return usbd_defer_func_wait(tud_output_fn, p); /* transfer execution to TinyUSB in the hopes that it will finish transmitting the prior packet */ /*rc: if use rtos, this function still will be called? */ // tud_task(); @@ -124,6 +137,7 @@ static err_t linkoutput_fn(struct netif *netif, struct pbuf *p) { } static err_t ip4_output_fn(struct netif *netif, struct pbuf *p, const ip4_addr_t *addr) { + /*rc etharp_output() will call netif->linkoutput() */ return etharp_output(netif, p, addr); } diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 858a0f4c3..5e7c7b8a6 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -377,7 +377,7 @@ static void xmit_start_if_possible(uint8_t rhport) { } // Kick off an endpoint transfer - usbd_edpt_xfer(0, ncm_interface.ep_in, ncm_interface.xmit_tinyusb_ntb->data, ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength); + usbd_edpt_xfer(rhport, ncm_interface.ep_in, ncm_interface.xmit_tinyusb_ntb->data, ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength); } // xmit_start_if_possible /** diff --git a/src/device/usbd.c b/src/device/usbd.c index bbab1b39f..f086d0361 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -363,6 +363,7 @@ static osal_queue_t _usbd_q; #else #define _usbd_mutex NULL #endif +static osal_semaphore_def_t _defer_func_sem; TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, bool in_isr) { TU_ASSERT(osal_queue_send(_usbd_q, event, in_isr)); @@ -515,6 +516,8 @@ bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { _usbd_q = osal_queue_create(&_usbd_qdef); TU_ASSERT(_usbd_q); + osal_semaphore_create(&_defer_func_sem); + // Get application driver if available if (usbd_app_driver_get_cb) { _app_driver = usbd_app_driver_get_cb(&_app_driver_count); @@ -1351,6 +1354,38 @@ void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) { queue_event(&event, in_isr); } +typedef struct +{ + osal_defer_func_t func; + void* param; + int ret; +} usbd_defer_func_t; +static void usbd_defer_func_wrapper(void *par){ + usbd_defer_func_t *defer = (usbd_defer_func_t *)par; + defer->ret = -1; + if(defer->func){ + defer->ret=defer->func(defer->param); + } + osal_semaphore_post(&_defer_func_sem, false); +} + +int usbd_defer_func_wait(osal_defer_func_t func, void* param){ + dcd_event_t event = { + .rhport = 0, + .event_id = USBD_EVENT_FUNC_CALL, + }; + usbd_defer_func_t deferd; + usbd_defer_func_t *defer = &deferd; + defer->func = func; + defer->param = param; + event.func_call.func = usbd_defer_func_wrapper; + event.func_call.param = defer; + + queue_event(&event, false); + osal_semaphore_wait(&_defer_func_sem, -1); + return defer->ret; +} + //--------------------------------------------------------------------+ // USBD Endpoint API //--------------------------------------------------------------------+ diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index f1797bf0d..9db4b9de8 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -129,7 +129,7 @@ void usbd_sof_enable(uint8_t rhport, sof_consumer_t consumer, bool en); bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in); void usbd_defer_func(osal_task_func_t func, void *param, bool in_isr); - +int usbd_defer_func_wait(osal_defer_func_t func, void *param); #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback); diff --git a/src/osal/osal.h b/src/osal/osal.h index a33280425..3c58f02ab 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -34,6 +34,7 @@ #include "common/tusb_common.h" typedef void (*osal_task_func_t)( void * ); +typedef int (*osal_defer_func_t)( void * ); // Timeout #define OSAL_TIMEOUT_NOTIMEOUT (0) // Return immediately