refactor(platform): update platform support

This commit is contained in:
sakumisu 2024-05-23 23:14:53 +08:00
parent 3336919e0d
commit 865d2f5d96
25 changed files with 1431 additions and 365 deletions

View File

@ -197,19 +197,22 @@ if CHERRYUSB
prompt "Enable usb msc driver"
default n
config CHERRYUSB_HOST_CDC_RNDIS
bool
prompt "Enable usb rndis driver"
default n
config CHERRYUSB_HOST_CDC_ECM
bool
prompt "Enable usb cdc ecm driver"
select USBHOST_PLATFORM_CDC_ECM
default n
config CHERRYUSB_HOST_CDC_RNDIS
bool
prompt "Enable usb rndis driver"
select USBHOST_PLATFORM_CDC_RNDIS
default n
config CHERRYUSB_HOST_CDC_NCM
bool
prompt "Enable usb cdc ncm driver"
select USBHOST_PLATFORM_CDC_NCM
default n
config CHERRYUSB_HOST_VIDEO
@ -230,11 +233,13 @@ if CHERRYUSB
config CHERRYUSB_HOST_ASIX
bool
prompt "Enable usb asix driver"
select USBHOST_PLATFORM_ASIX
default n
config CHERRYUSB_HOST_RTL8152
bool
prompt "Enable usb rtl8152 driver"
select USBHOST_PLATFORM_RTL8152
default n
config CHERRYUSB_HOST_FTDI
@ -252,6 +257,26 @@ if CHERRYUSB
prompt "Enable usb cp210x driver"
default n
config CHERRYUSB_HOST_PL2303
bool
prompt "Enable usb pl2303 driver"
default n
config USBHOST_PLATFORM_CDC_ECM
bool
config USBHOST_PLATFORM_CDC_RNDIS
bool
config USBHOST_PLATFORM_CDC_NCM
bool
config USBHOST_PLATFORM_ASIX
bool
config USBHOST_PLATFORM_RTL152
bool
config CHERRYUSB_HOST_TEMPLATE
bool
prompt "Use usb host template"
@ -270,34 +295,9 @@ if CHERRYUSB
depends on CHERRYUSB_HOST_HID
config TEST_USBH_MSC
int
prompt "demo for test msc, do not enable because it has used dfs instead"
prompt "demo for test msc"
default 0
depends on CHERRYUSB_HOST_MSC
config TEST_USBH_CDC_ECM
int
prompt "demo for test cdc ecm"
default 0
depends on CHERRYUSB_HOST_CDC_ECM
config TEST_USBH_CDC_NCM
int
prompt "demo for test cdc ncm"
default 0
depends on CHERRYUSB_HOST_CDC_NCM
config TEST_USBH_RNDIS
int
prompt "demo for test cdc rndis"
default 0
depends on CHERRYUSB_HOST_CDC_RNDIS
config TEST_USBH_ASIX
int
prompt "demo for test asix"
default 0
depends on CHERRYUSB_HOST_ASIX
config TEST_USBH_RTL8152
int
prompt "demo for test rtl8152"
default 0
depends on CHERRYUSB_HOST_RTL8152
endif
endif

View File

@ -36,27 +36,14 @@ Taking into account USB performance issues and trying to achieve the theoretical
## Directoy Structure
```
.
├── class
├── common
├── core
├── demo
├── docs
├── osal
├── packet capture
└── port
└── tools
```
| Directory | Description |
|:-------------:|:---------------------------:|
|class | usb class driver |
|common | usb spec macros and utils |
|core | usb core implementation |
|demo | different chips demo |
|demo | usb device and host demo |
|osal | os wrapper |
|platform | class support for other os |
|docs | doc for guiding |
|port | usb dcd and hcd porting |
|tools | tool url |

View File

@ -36,26 +36,15 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带
## 目录结构
```
.
├── class
├── common
├── core
├── demo
├── docs
├── osal
└── port
└── tools
```
| 目录名 | 描述 |
|:-------------:|:-------------------------------:|
|class | usb class 类主从驱动 |
|common | usb spec 定义、常用宏、标准接口定义 |
|core | usb 主从协议栈核心实现 |
|demo | 示例 |
|demo | 主从 class demo |
|docs | 文档 |
|osal | os 封装层 |
|platform | 其他 os 全家桶适配 |
|port | usb 主从需要实现的 porting 接口 |
|tools | 工具链接 |

View File

@ -191,11 +191,18 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
if GetDepend(['PKG_CHERRYUSB_HOST_TEMPLATE']):
src += Glob('demo/usb_host.c')
if GetDepend('RT_USING_DFS'):
src += Glob('third_party/rt-thread-5.0/dfs_usbh_msc.c')
if GetDepend('RT_USING_DFS') and GetDepend(['PKG_CHERRYUSB_HOST_MSC']):
src += Glob('platform/rtthread/usbh_dfs.c')
src += Glob('third_party/rt-thread-5.0/usb_msh.c')
src += Glob('third_party/rt-thread-5.0/usb_check.c')
if GetDepend('PKG_CHERRYUSB_HOST_CDC_ECM') \
or GetDepend('PKG_CHERRYUSB_HOST_CDC_RNDIS') \
or GetDepend('PKG_CHERRYUSB_HOST_CDC_NCM') \
or GetDepend('PKG_CHERRYUSB_HOST_CDC_ASIX') \
or GetDepend('PKG_CHERRYUSB_HOST_CDC_RTL8152'):
src += Glob('platform/rtthread/usbh_lwip.c')
src += Glob('platform/rtthread/usb_msh.c')
src += Glob('platform/rtthread/usb_check.c')
group = DefineGroup('CherryUSB', src, depend = ['PKG_USING_CHERRYUSB'], CPPPATH = path, CPPDEFINES = CPPDEFINES)

View File

@ -230,14 +230,6 @@ void usbh_cdc_ecm_rx_thread(void *argument)
{
uint32_t g_cdc_ecm_rx_length;
int ret;
err_t err;
struct pbuf *p;
#if LWIP_TCPIP_CORE_LOCKING_INPUT
pbuf_type type = PBUF_ROM;
#else
pbuf_type type = PBUF_POOL;
#endif
struct netif *netif = (struct netif *)argument;
USB_LOG_INFO("Create cdc ecm rx thread\r\n");
// clang-format off
@ -269,23 +261,9 @@ find_class:
if (g_cdc_ecm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ecm_class.bulkin->wMaxPacketSize)) {
USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ecm_rx_length);
p = pbuf_alloc(PBUF_RAW, g_cdc_ecm_rx_length, type);
if (p != NULL) {
#if LWIP_TCPIP_CORE_LOCKING_INPUT
p->payload = g_cdc_ecm_rx_buffer;
#else
memcpy(p->payload, (uint8_t *)g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_length);
#endif
g_cdc_ecm_rx_length = 0;
usbh_cdc_ecm_eth_input(g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_length);
err = netif->input(p, netif);
if (err != ERR_OK) {
pbuf_free(p);
}
} else {
g_cdc_ecm_rx_length = 0;
USB_LOG_ERR("No memory to alloc pbuf for cdc ecm rx\r\n");
}
g_cdc_ecm_rx_length = 0;
} else {
/* read continue util read short packet */
if (g_cdc_ecm_rx_length > CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE) {
@ -301,30 +279,20 @@ delete:
// clang-format on
}
err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p)
int usbh_cdc_ecm_eth_output(uint8_t *buf, uint32_t buflen)
{
int ret;
struct pbuf *q;
uint8_t *buffer = g_cdc_ecm_tx_buffer;
if (g_cdc_ecm_class.connect_status == false) {
return ERR_BUF;
return -USB_ERR_NOTCONN;
}
for (q = p; q != NULL; q = q->next) {
memcpy(buffer, q->payload, q->len);
buffer += q->len;
}
memcpy(buffer, buf, buflen);
USB_LOG_DBG("txlen:%d\r\n", p->tot_len);
USB_LOG_DBG("txlen:%d\r\n", buflen);
usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkout_urb, g_cdc_ecm_class.hport, g_cdc_ecm_class.bulkout, g_cdc_ecm_tx_buffer, p->tot_len, USB_OSAL_WAITING_FOREVER, NULL, NULL);
ret = usbh_submit_urb(&g_cdc_ecm_class.bulkout_urb);
if (ret < 0) {
return ERR_BUF;
}
return ERR_OK;
usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkout_urb, g_cdc_ecm_class.hport, g_cdc_ecm_class.bulkout, g_cdc_ecm_tx_buffer, buflen, USB_OSAL_WAITING_FOREVER, NULL, NULL);
return usbh_submit_urb(&g_cdc_ecm_class.bulkout_urb);
}
__WEAK void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class)

View File

@ -8,9 +8,6 @@
#include "usb_cdc.h"
#include "lwip/netif.h"
#include "lwip/pbuf.h"
struct usbh_cdc_ecm {
struct usbh_hubport *hport;
struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */
@ -29,10 +26,6 @@ struct usbh_cdc_ecm {
uint16_t max_segment_size;
uint32_t speed[2];
ip_addr_t ipaddr;
ip_addr_t netmask;
ip_addr_t gateway;
void *user_data;
};
@ -45,7 +38,8 @@ int usbh_cdc_ecm_get_connect_status(struct usbh_cdc_ecm *cdc_ecm_class);
void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class);
void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class);
err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p);
int usbh_cdc_ecm_eth_output(uint8_t *buf, uint32_t buflen);
void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_cdc_ecm_rx_thread(void *argument);
#ifdef __cplusplus

View File

@ -248,14 +248,6 @@ void usbh_cdc_ncm_rx_thread(void *argument)
{
uint32_t g_cdc_ncm_rx_length;
int ret;
err_t err;
struct pbuf *p;
#if LWIP_TCPIP_CORE_LOCKING_INPUT
pbuf_type type = PBUF_ROM;
#else
pbuf_type type = PBUF_POOL;
#endif
struct netif *netif = (struct netif *)argument;
USB_LOG_INFO("Create cdc ncm rx thread\r\n");
// clang-format off
@ -311,20 +303,8 @@ find_class:
if (ndp16_datagram->wDatagramIndex && ndp16_datagram->wDatagramLength) {
USB_LOG_DBG("ndp16_datagram index:%02x, length:%02x\r\n", ndp16_datagram->wDatagramIndex, ndp16_datagram->wDatagramLength);
p = pbuf_alloc(PBUF_RAW, ndp16_datagram->wDatagramLength, type);
if (p != NULL) {
#if LWIP_TCPIP_CORE_LOCKING_INPUT
p->payload = (uint8_t *)&g_cdc_ncm_rx_buffer[ndp16_datagram->wDatagramIndex];
#else
memcpy(p->payload, (uint8_t *)&g_cdc_ncm_rx_buffer[ndp16_datagram->wDatagramIndex], ndp16_datagram->wDatagramLength);
#endif
err = netif->input(p, netif);
if (err != ERR_OK) {
pbuf_free(p);
}
} else {
USB_LOG_ERR("No memory to alloc pbuf for cdc ncm rx\r\n");
}
uint8_t *buf = (uint8_t *)&g_cdc_ncm_rx_buffer[ndp16_datagram->wDatagramIndex];
usbh_cdc_ncm_eth_input(buf, ndp16_datagram->wDatagramLength);
}
}
@ -344,15 +324,13 @@ delete:
// clang-format on
}
err_t usbh_cdc_ncm_linkoutput(struct netif *netif, struct pbuf *p)
int usbh_cdc_ncm_eth_output(uint8_t *buf, uint32_t buflen)
{
int ret;
struct pbuf *q;
uint8_t *buffer;
struct cdc_ncm_ndp16_datagram *ndp16_datagram;
if (g_cdc_ncm_class.connect_status == false) {
return ERR_BUF;
return -USB_ERR_NOTCONN;
}
struct cdc_ncm_nth16 *nth16 = (struct cdc_ncm_nth16 *)&g_cdc_ncm_tx_buffer[0];
@ -360,8 +338,8 @@ err_t usbh_cdc_ncm_linkoutput(struct netif *netif, struct pbuf *p)
nth16->dwSignature = CDC_NCM_NTH16_SIGNATURE;
nth16->wHeaderLength = 12;
nth16->wSequence = g_cdc_ncm_class.bulkout_sequence++;
nth16->wBlockLength = 16 + 16 + USB_ALIGN_UP(p->tot_len, 4);
nth16->wNdpIndex = 16 + USB_ALIGN_UP(p->tot_len, 4);
nth16->wBlockLength = 16 + 16 + USB_ALIGN_UP(buflen, 4);
nth16->wNdpIndex = 16 + USB_ALIGN_UP(buflen, 4);
struct cdc_ncm_ndp16 *ndp16 = (struct cdc_ncm_ndp16 *)&g_cdc_ncm_tx_buffer[nth16->wNdpIndex];
@ -371,28 +349,19 @@ err_t usbh_cdc_ncm_linkoutput(struct netif *netif, struct pbuf *p)
ndp16_datagram = (struct cdc_ncm_ndp16_datagram *)&g_cdc_ncm_tx_buffer[nth16->wNdpIndex + 8 + 4 * 0];
ndp16_datagram->wDatagramIndex = 16;
ndp16_datagram->wDatagramLength = p->tot_len;
ndp16_datagram->wDatagramLength = buflen;
ndp16_datagram = (struct cdc_ncm_ndp16_datagram *)&g_cdc_ncm_tx_buffer[nth16->wNdpIndex + 8 + 4 * 1];
ndp16_datagram->wDatagramIndex = 0;
ndp16_datagram->wDatagramLength = 0;
buffer = &g_cdc_ncm_tx_buffer[16];
for (q = p; q != NULL; q = q->next) {
memcpy(buffer, q->payload, q->len);
buffer += q->len;
}
memcpy(buffer, buf, buflen);
USB_LOG_DBG("txlen:%d\r\n", nth16->wBlockLength);
usbh_bulk_urb_fill(&g_cdc_ncm_class.bulkout_urb, g_cdc_ncm_class.hport, g_cdc_ncm_class.bulkout, g_cdc_ncm_tx_buffer, nth16->wBlockLength, USB_OSAL_WAITING_FOREVER, NULL, NULL);
ret = usbh_submit_urb(&g_cdc_ncm_class.bulkout_urb);
if (ret < 0) {
return ERR_BUF;
}
return ERR_OK;
return usbh_submit_urb(&g_cdc_ncm_class.bulkout_urb);
}
__WEAK void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class)

View File

@ -8,9 +8,6 @@
#include "usb_cdc.h"
#include "lwip/netif.h"
#include "lwip/pbuf.h"
struct usbh_cdc_ncm {
struct usbh_hubport *hport;
struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */
@ -33,10 +30,6 @@ struct usbh_cdc_ncm {
uint16_t max_segment_size;
uint32_t speed[2];
ip_addr_t ipaddr;
ip_addr_t netmask;
ip_addr_t gateway;
void *user_data;
};
@ -49,7 +42,8 @@ int usbh_cdc_ncm_get_connect_status(struct usbh_cdc_ncm *cdc_ncm_class);
void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class);
void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class);
err_t usbh_cdc_ncm_linkoutput(struct netif *netif, struct pbuf *p);
int usbh_cdc_ncm_eth_output(uint8_t *buf, uint32_t buflen);
void usbh_cdc_ncm_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_cdc_ncm_rx_thread(void *argument);
#ifdef __cplusplus

View File

@ -653,16 +653,8 @@ void usbh_asix_rx_thread(void *argument)
{
uint32_t g_asix_rx_length;
int ret;
err_t err;
uint16_t len;
uint16_t len_crc;
struct pbuf *p;
#if LWIP_TCPIP_CORE_LOCKING_INPUT
pbuf_type type = PBUF_ROM;
#else
pbuf_type type = PBUF_POOL;
#endif
struct netif *netif = (struct netif *)argument;
USB_LOG_INFO("Create asix rx thread\r\n");
// clang-format off
@ -702,23 +694,9 @@ find_class:
USB_LOG_DBG("rxlen:%d\r\n", g_asix_rx_length);
p = pbuf_alloc(PBUF_RAW, len, type);
if (p != NULL) {
#if LWIP_TCPIP_CORE_LOCKING_INPUT
p->payload = (uint8_t *)&g_asix_rx_buffer[4];
#else
memcpy(p->payload, (uint8_t *)&g_asix_rx_buffer[4], len);
#endif
g_asix_rx_length = 0;
err = netif->input(p, netif);
if (err != ERR_OK) {
pbuf_free(p);
}
} else {
g_asix_rx_length = 0;
USB_LOG_ERR("No memory to alloc pbuf for asix rx\r\n");
}
uint8_t *buf = (uint8_t *)&g_asix_rx_buffer[4];
usbh_asix_eth_input(buf, len);
g_asix_rx_length = 0;
} else {
if (g_asix_rx_length > CONFIG_USBHOST_ASIX_ETH_MAX_SIZE) {
USB_LOG_ERR("Rx packet is overflow\r\n");
@ -733,46 +711,37 @@ delete:
// clang-format on
}
err_t usbh_asix_linkoutput(struct netif *netif, struct pbuf *p)
int usbh_asix_eth_output(uint8_t *buf, uint32_t buflen)
{
int ret;
struct pbuf *q;
uint16_t actual_len;
uint8_t *buffer = &g_asix_tx_buffer[4];
uint8_t *buffer;
if (g_asix_class.connect_status == false) {
return ERR_BUF;
return -USB_ERR_NOTCONN;
}
for (q = p; q != NULL; q = q->next) {
memcpy(buffer, q->payload, q->len);
buffer += q->len;
}
buffer = &g_asix_tx_buffer[4];
memcpy(buffer, buf, buflen);
g_asix_tx_buffer[0] = p->tot_len & 0xff;
g_asix_tx_buffer[1] = (p->tot_len >> 8) & 0xff;
g_asix_tx_buffer[0] = buflen & 0xff;
g_asix_tx_buffer[1] = (buflen >> 8) & 0xff;
g_asix_tx_buffer[2] = ~g_asix_tx_buffer[0];
g_asix_tx_buffer[3] = ~g_asix_tx_buffer[1];
if (!(p->tot_len + 4) % USB_GET_MAXPACKETSIZE(g_asix_class.bulkout->wMaxPacketSize)) {
USB_LOG_DBG("txlen:%d\r\n", p->tot_len + 8);
g_asix_tx_buffer[p->tot_len + 4 + 0] = 0x00;
g_asix_tx_buffer[p->tot_len + 4 + 1] = 0x00;
g_asix_tx_buffer[p->tot_len + 4 + 2] = 0xff;
g_asix_tx_buffer[p->tot_len + 4 + 3] = 0xff;
actual_len = p->tot_len + 8;
if (!(buflen + 4) % USB_GET_MAXPACKETSIZE(g_asix_class.bulkout->wMaxPacketSize)) {
USB_LOG_DBG("txlen:%d\r\n", buflen + 8);
g_asix_tx_buffer[buflen + 4 + 0] = 0x00;
g_asix_tx_buffer[buflen + 4 + 1] = 0x00;
g_asix_tx_buffer[buflen + 4 + 2] = 0xff;
g_asix_tx_buffer[buflen + 4 + 3] = 0xff;
actual_len = buflen + 8;
} else {
USB_LOG_DBG("txlen:%d\r\n", p->tot_len + 4);
actual_len = p->tot_len + 4;
USB_LOG_DBG("txlen:%d\r\n", buflen + 4);
actual_len = buflen + 4;
}
usbh_bulk_urb_fill(&g_asix_class.bulkout_urb, g_asix_class.hport, g_asix_class.bulkout, g_asix_tx_buffer, actual_len, USB_OSAL_WAITING_FOREVER, NULL, NULL);
ret = usbh_submit_urb(&g_asix_class.bulkout_urb);
if (ret < 0) {
return ERR_BUF;
}
return ERR_OK;
return usbh_submit_urb(&g_asix_class.bulkout_urb);
}
__WEAK void usbh_asix_run(struct usbh_asix *asix_class)

View File

@ -6,9 +6,6 @@
#ifndef USBH_ASIX_H
#define USBH_ASIX_H
#include "lwip/netif.h"
#include "lwip/pbuf.h"
/* ASIX AX8817X based USB 2.0 Ethernet Devices */
#define AX_CMD_SET_SW_MII 0x06
@ -156,10 +153,6 @@ struct usbh_asix {
bool connect_status;
uint8_t mac[6];
ip_addr_t ipaddr;
ip_addr_t netmask;
ip_addr_t gateway;
void *user_data;
};
@ -172,8 +165,9 @@ int usbh_asix_get_connect_status(struct usbh_asix *asix_class);
void usbh_asix_run(struct usbh_asix *asix_class);
void usbh_asix_stop(struct usbh_asix *asix_class);
int usbh_asix_eth_output(uint8_t *buf, uint32_t buflen);
void usbh_asix_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_asix_rx_thread(void *argument);
err_t usbh_asix_linkoutput(struct netif *netif, struct pbuf *p);
#ifdef __cplusplus
}

View File

@ -2122,16 +2122,8 @@ void usbh_rtl8152_rx_thread(void *argument)
{
uint32_t g_rtl8152_rx_length;
int ret;
err_t err;
uint16_t len;
uint16_t data_offset;
struct pbuf *p;
#if LWIP_TCPIP_CORE_LOCKING_INPUT
pbuf_type type = PBUF_ROM;
#else
pbuf_type type = PBUF_POOL;
#endif
struct netif *netif = (struct netif *)argument;
USB_LOG_INFO("Create rtl8152 rx thread\r\n");
// clang-format off
@ -2181,20 +2173,9 @@ find_class:
USB_LOG_DBG("data_offset:%d, eth len:%d\r\n", data_offset, len);
p = pbuf_alloc(PBUF_RAW, len, type);
if (p != NULL) {
#if LWIP_TCPIP_CORE_LOCKING_INPUT
p->payload = (uint8_t *)&g_rtl8152_rx_buffer[data_offset + sizeof(struct rx_desc)];
#else
memcpy(p->payload, (uint8_t *)&g_rtl8152_rx_buffer[data_offset + sizeof(struct rx_desc)], len);
#endif
err = netif->input(p, netif);
if (err != ERR_OK) {
pbuf_free(p);
}
} else {
USB_LOG_ERR("No memory to alloc pbuf for rtl8152 rx\r\n");
}
uint8_t *buf = (uint8_t *)&g_rtl8152_rx_buffer[data_offset + sizeof(struct rx_desc)];
usbh_rtl8152_eth_input(buf, len);
data_offset += (len + sizeof(struct rx_desc));
g_rtl8152_rx_length -= (len + sizeof(struct rx_desc));
@ -2217,36 +2198,26 @@ delete:
// clang-format on
}
err_t usbh_rtl8152_linkoutput(struct netif *netif, struct pbuf *p)
int usbh_rtl8152_eth_output(uint8_t *buf, uint32_t buflen)
{
int ret;
struct pbuf *q;
uint8_t *buffer;
struct tx_desc *tx_desc = (struct tx_desc *)g_rtl8152_tx_buffer;
struct tx_desc *tx_desc;
if (g_rtl8152_class.connect_status == false) {
return ERR_BUF;
return -USB_ERR_NOTCONN;
}
tx_desc->opts1 = p->tot_len | TX_FS | TX_LS;
tx_desc = (struct tx_desc *)g_rtl8152_tx_buffer;
tx_desc->opts1 = buflen | TX_FS | TX_LS;
tx_desc->opts2 = 0;
buffer = g_rtl8152_tx_buffer + sizeof(struct tx_desc);
memcpy(buffer, buf, buflen);
for (q = p; q != NULL; q = q->next) {
memcpy(buffer, q->payload, q->len);
buffer += q->len;
}
USB_LOG_DBG("txlen:%d\r\n", buflen + sizeof(struct tx_desc));
USB_LOG_DBG("txlen:%d\r\n", p->tot_len + sizeof(struct tx_desc));
usbh_bulk_urb_fill(&g_rtl8152_class.bulkout_urb, g_rtl8152_class.hport, g_rtl8152_class.bulkout, g_rtl8152_tx_buffer, p->tot_len + sizeof(struct tx_desc), USB_OSAL_WAITING_FOREVER, NULL, NULL);
ret = usbh_submit_urb(&g_rtl8152_class.bulkout_urb);
if (ret < 0) {
return ERR_BUF;
}
return ERR_OK;
usbh_bulk_urb_fill(&g_rtl8152_class.bulkout_urb, g_rtl8152_class.hport, g_rtl8152_class.bulkout, g_rtl8152_tx_buffer, buflen + sizeof(struct tx_desc), USB_OSAL_WAITING_FOREVER, NULL, NULL);
return usbh_submit_urb(&g_rtl8152_class.bulkout_urb);
}
__WEAK void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class)

View File

@ -6,9 +6,6 @@
#ifndef USBH_RTL8152_H
#define USBH_RTL8152_H
#include "lwip/netif.h"
#include "lwip/pbuf.h"
struct usbh_rtl8152 {
struct usbh_hubport *hport;
struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */
@ -24,10 +21,6 @@ struct usbh_rtl8152 {
bool connect_status;
uint32_t speed[2];
ip_addr_t ipaddr;
ip_addr_t netmask;
ip_addr_t gateway;
uint8_t version;
uint8_t eee_adv;
uint8_t eee_en;
@ -63,8 +56,9 @@ int usbh_rtl8152_get_connect_status(struct usbh_rtl8152 *rtl8152_class);
void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class);
void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class);
int usbh_rtl8152_eth_output(uint8_t *buf, uint32_t buflen);
void usbh_rtl8152_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_rtl8152_rx_thread(void *argument);
err_t usbh_rtl8152_linkoutput(struct netif *netif, struct pbuf *p);
#ifdef __cplusplus
}

View File

@ -425,18 +425,10 @@ static int usbh_rndis_disconnect(struct usbh_hubport *hport, uint8_t intf)
void usbh_rndis_rx_thread(void *argument)
{
uint32_t g_rndis_rx_length;
uint32_t pmg_offset;
int ret;
err_t err;
struct pbuf *p;
uint32_t pmg_offset;
rndis_data_packet_t *pmsg;
rndis_data_packet_t temp;
#if LWIP_TCPIP_CORE_LOCKING_INPUT
pbuf_type type = PBUF_ROM;
#else
pbuf_type type = PBUF_POOL;
#endif
struct netif *netif = (struct netif *)argument;
USB_LOG_INFO("Create rndis rx thread\r\n");
// clang-format off
@ -481,28 +473,15 @@ find_class:
}
if (pmsg->MessageType == REMOTE_NDIS_PACKET_MSG) {
p = pbuf_alloc(PBUF_RAW, pmsg->DataLength, type);
if (p != NULL) {
void *src = (void *)(g_rndis_rx_buffer + pmg_offset + sizeof(rndis_generic_msg_t) + pmsg->DataOffset);
#if LWIP_TCPIP_CORE_LOCKING_INPUT
p->payload = src;
#else
memcpy(p->payload, src, pmsg->DataLength);
#endif
err = netif->input(p, netif);
if (err != ERR_OK) {
pbuf_free(p);
}
pmg_offset += pmsg->MessageLength;
g_rndis_rx_length -= pmsg->MessageLength;
uint8_t *buf = (uint8_t *)(g_rndis_rx_buffer + pmg_offset + sizeof(rndis_generic_msg_t) + pmsg->DataOffset);
/* drop the last dummy byte, it is a short packet to tell us we have received a multiple of wMaxPacketSize */
if (g_rndis_rx_length < 4) {
g_rndis_rx_length = 0;
}
} else {
usbh_rndis_eth_input(buf, pmsg->DataLength);
pmg_offset += pmsg->MessageLength;
g_rndis_rx_length -= pmsg->MessageLength;
/* drop the last dummy byte, it is a short packet to tell us we have received a multiple of wMaxPacketSize */
if (g_rndis_rx_length < 4) {
g_rndis_rx_length = 0;
USB_LOG_ERR("No memory to alloc pbuf for rndis rx\r\n");
}
} else {
USB_LOG_ERR("offset:%d,remain:%d,total:%d\r\n", pmg_offset, g_rndis_rx_length, total_len);
@ -525,31 +504,26 @@ delete:
// clang-format on
}
err_t usbh_rndis_linkoutput(struct netif *netif, struct pbuf *p)
int usbh_rndis_eth_output(uint8_t *buf, uint32_t buflen)
{
int ret;
struct pbuf *q;
uint8_t *buffer;
rndis_data_packet_t *hdr;
uint32_t len;
if (g_rndis_class.connect_status == false) {
return ERR_BUF;
return -USB_ERR_NOTCONN;
}
hdr = (rndis_data_packet_t *)g_rndis_tx_buffer;
memset(hdr, 0, sizeof(rndis_data_packet_t));
hdr->MessageType = REMOTE_NDIS_PACKET_MSG;
hdr->MessageLength = sizeof(rndis_data_packet_t) + p->tot_len;
hdr->MessageLength = sizeof(rndis_data_packet_t) + buflen;
hdr->DataOffset = sizeof(rndis_data_packet_t) - sizeof(rndis_generic_msg_t);
hdr->DataLength = p->tot_len;
hdr->DataLength = buflen;
buffer = (uint8_t *)(g_rndis_tx_buffer + sizeof(rndis_data_packet_t));
for (q = p; q != NULL; q = q->next) {
memcpy(buffer, q->payload, q->len);
buffer += q->len;
}
memcpy(buffer, buf, buflen);
len = hdr->MessageLength;
/* if message length is the multiple of wMaxPacketSize, we should add a short packet to tell device transfer is over. */
@ -560,12 +534,7 @@ err_t usbh_rndis_linkoutput(struct netif *netif, struct pbuf *p)
USB_LOG_DBG("txlen:%d\r\n", len);
usbh_bulk_urb_fill(&g_rndis_class.bulkout_urb, g_rndis_class.hport, g_rndis_class.bulkout, g_rndis_tx_buffer, len, USB_OSAL_WAITING_FOREVER, NULL, NULL);
ret = usbh_submit_urb(&g_rndis_class.bulkout_urb);
if (ret < 0) {
return ERR_BUF;
}
return ERR_OK;
return usbh_submit_urb(&g_rndis_class.bulkout_urb);
}
__WEAK void usbh_rndis_run(struct usbh_rndis *rndis_class)

View File

@ -8,9 +8,6 @@
#include "usb_cdc.h"
#include "lwip/netif.h"
#include "lwip/pbuf.h"
struct usbh_rndis {
struct usbh_hubport *hport;
struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */
@ -30,10 +27,6 @@ struct usbh_rndis {
bool connect_status;
uint8_t mac[6];
ip_addr_t ipaddr;
ip_addr_t netmask;
ip_addr_t gateway;
void *user_data;
};
@ -47,7 +40,8 @@ int usbh_rndis_keepalive(struct usbh_rndis *rndis_class);
void usbh_rndis_run(struct usbh_rndis *rndis_class);
void usbh_rndis_stop(struct usbh_rndis *rndis_class);
err_t usbh_rndis_linkoutput(struct netif *netif, struct pbuf *p);
int usbh_rndis_eth_output(uint8_t *buf, uint32_t buflen);
void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen);
void usbh_rndis_rx_thread(void *argument);
#ifdef __cplusplus

14
platform/README.md Normal file
View File

@ -0,0 +1,14 @@
# Platform Support
This is a platform support for other os with their own components.
| Platform | fs | net | serial |
|:---------:|:------------:|:------------:|:------------:|
|none | fatfs | lwip | none |
|rtthread | dfs | lwip | rt_device |
|nuttx | nuttx block driver | nuttx net | nuttx char driver|
|threadx | filex | netx | none |
- **fs** is for usbd_msc and usbh_msc
- **net** is for cdc_ecm, cdc_rndis, cdc_ncm, asix, rtl8152 and so on.
- **serial** is for cdc_acm, ch340, ftdi, cp210x, pl2303 and so on.

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "ff.h"
#include "diskio.h"
#include "usbh_core.h"
@ -9,6 +14,7 @@ int USB_disk_status(void)
{
return 0;
}
int USB_disk_initialize(void)
{
active_msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda");
@ -59,4 +65,4 @@ int USB_disk_ioctl(BYTE cmd, void *buff)
}
return result;
}
}

504
platform/none/usbh_lwip.c Normal file
View File

@ -0,0 +1,504 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "netif/etharp.h"
#include "lwip/netif.h"
#include "lwip/pbuf.h"
#include "lwip/tcpip.h"
#if LWIP_DHCP
#include "lwip/dhcp.h"
#include "lwip/prot/dhcp.h"
#endif
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "timers.h"
#include "usbh_core.h"
#if LWIP_TCPIP_CORE_LOCKING_INPUT !=1
#warning suggest you to set LWIP_TCPIP_CORE_LOCKING_INPUT to 1, usb handles eth input with own thread
#endif
#if LWIP_TCPIP_CORE_LOCKING !=1
#error must set LWIP_TCPIP_CORE_LOCKING to 1
#endif
#if PBUF_POOL_BUFSIZE < 1600
#error PBUF_POOL_BUFSIZE must be larger than 1600
#endif
#define CONFIG_USBHOST_PLATFORM_CDC_ECM
#define CONFIG_USBHOST_PLATFORM_CDC_RNDIS
#define CONFIG_USBHOST_PLATFORM_CDC_NCM
#define CONFIG_USBHOST_PLATFORM_ASIX
#define CONFIG_USBHOST_PLATFORM_RTL8152
ip_addr_t g_ipaddr;
ip_addr_t g_netmask;
ip_addr_t g_gateway;
void usbh_lwip_eth_input_common(struct netif *netif, uint8_t *buf, uint32_t len)
{
#if LWIP_TCPIP_CORE_LOCKING_INPUT
pbuf_type type = PBUF_REF;
#else
pbuf_type type = PBUF_POOL;
#endif
err_t err;
struct pbuf *p;
p = pbuf_alloc(PBUF_RAW, len, type);
if (p != NULL) {
#if LWIP_TCPIP_CORE_LOCKING_INPUT
p->payload = buf;
#else
memcpy(p->payload, buf, len);
#endif
err = netif->input(p, netif);
if (err != ERR_OK) {
pbuf_free(p);
}
} else {
USB_LOG_ERR("No memory to alloc pbuf\r\n");
}
}
TimerHandle_t dhcp_handle;
static void dhcp_timeout(TimerHandle_t xTimer)
{
struct netif *netif = (struct netif *)pvTimerGetTimerID(xTimer);
struct dhcp *dhcp;
if (netif_is_up(netif)) {
dhcp = netif_dhcp_data(netif);
if (dhcp && (dhcp->state == DHCP_STATE_BOUND)) {
USB_LOG_INFO("IPv4 Address : %s\r\n", ipaddr_ntoa(&netif->ip_addr));
USB_LOG_INFO("IPv4 Subnet mask : %s\r\n", ipaddr_ntoa(&netif->netmask));
USB_LOG_INFO("IPv4 Gateway : %s\r\n\r\n", ipaddr_ntoa(&netif->gw));
xTimerStop(xTimer, 0);
}
}
}
#ifdef CONFIG_USBHOST_PLATFORM_CDC_ECM
#include "usbh_cdc_ecm.h"
struct netif g_cdc_ecm_netif;
static err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p)
{
int ret = usbh_cdc_ecm_eth_output(p->payload, p->tot_len);
if (ret < 0) {
return ERR_BUF;
} else {
return ERR_OK;
}
}
void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_lwip_eth_input_common(&g_cdc_ecm_netif, buf, buflen);
}
static err_t usbh_cdc_ecm_if_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
netif->mtu = 1500;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
netif->state = NULL;
netif->name[0] = 'E';
netif->name[1] = 'X';
netif->output = etharp_output;
netif->linkoutput = usbh_cdc_ecm_linkoutput;
return ERR_OK;
}
void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class)
{
struct netif *netif = &g_cdc_ecm_netif;
netif->hwaddr_len = 6;
memcpy(netif->hwaddr, cdc_ecm_class->mac, 6);
IP4_ADDR(&g_ipaddr, 0, 0, 0, 0);
IP4_ADDR(&g_netmask, 0, 0, 0, 0);
IP4_ADDR(&g_gateway, 0, 0, 0, 0);
netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_cdc_ecm_if_init, tcpip_input);
netif_set_default(netif);
while (!netif_is_up(netif)) {
}
dhcp_handle = xTimerCreate((const char *)"dhcp", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle == NULL) {
USB_LOG_ERR("timer creation failed! \r\n");
while (1) {
}
}
usb_osal_thread_create("usbh_cdc_ecm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ecm_rx_thread, NULL);
#if LWIP_DHCP
dhcp_start(netif);
xTimerStart(dhcp_handle, 0);
#endif
}
void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class)
{
struct netif *netif = &g_cdc_ecm_netif;
#if LWIP_DHCP
dhcp_stop(netif);
dhcp_cleanup(netif);
xTimerStop(dhcp_handle, 0);
xTimerDelete(dhcp_handle, 0);
#endif
netif_set_down(netif);
netif_remove(netif);
}
#endif
#ifdef CONFIG_USBHOST_PLATFORM_CDC_RNDIS
#include "usbh_rndis.h"
TimerHandle_t timer_handle;
static void rndis_dev_keepalive_timeout(TimerHandle_t xTimer)
{
struct usbh_rndis *rndis_class = (struct usbh_rndis *)pvTimerGetTimerID(xTimer);
usbh_rndis_keepalive(rndis_class);
}
void timer_init(struct usbh_rndis *rndis_class)
{
timer_handle = xTimerCreate((const char *)NULL, (TickType_t)5000, (UBaseType_t)pdTRUE, (void *const)rndis_class, (TimerCallbackFunction_t)rndis_dev_keepalive_timeout);
if (NULL != timer_handle) {
xTimerStart(timer_handle, 0);
} else {
USB_LOG_ERR("timer creation failed! \r\n");
for (;;) {
;
}
}
}
struct netif g_rndis_netif;
static err_t usbh_rndis_linkoutput(struct netif *netif, struct pbuf *p)
{
int ret = usbh_rndis_eth_output(p->payload, p->tot_len);
if (ret < 0) {
return ERR_BUF;
} else {
return ERR_OK;
}
}
void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_lwip_eth_input_common(&g_rndis_netif, buf, buflen);
}
static err_t usbh_rndis_if_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
netif->mtu = 1500;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
netif->state = NULL;
netif->name[0] = 'E';
netif->name[1] = 'X';
netif->output = etharp_output;
netif->linkoutput = usbh_rndis_linkoutput;
return ERR_OK;
}
void usbh_rndis_run(struct usbh_rndis *rndis_class)
{
struct netif *netif = &g_rndis_netif;
netif->hwaddr_len = 6;
memcpy(netif->hwaddr, rndis_class->mac, 6);
IP4_ADDR(&g_ipaddr, 0, 0, 0, 0);
IP4_ADDR(&g_netmask, 0, 0, 0, 0);
IP4_ADDR(&g_gateway, 0, 0, 0, 0);
netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_rndis_if_init, tcpip_input);
netif_set_default(netif);
while (!netif_is_up(netif)) {
}
dhcp_handle = xTimerCreate((const char *)"dhcp", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle == NULL) {
USB_LOG_ERR("timer creation failed! \r\n");
while (1) {
}
}
usb_osal_thread_create("usbh_rndis_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rndis_rx_thread, NULL);
//timer_init(rndis_class);
#if LWIP_DHCP
dhcp_start(netif);
xTimerStart(dhcp_handle, 0);
#endif
}
void usbh_rndis_stop(struct usbh_rndis *rndis_class)
{
struct netif *netif = &g_rndis_netif;
#if LWIP_DHCP
dhcp_stop(netif);
dhcp_cleanup(netif);
xTimerStop(dhcp_handle, 0);
xTimerDelete(dhcp_handle, 0);
#endif
netif_set_down(netif);
netif_remove(netif);
// xTimerStop(timer_handle, 0);
// xTimerDelete(timer_handle, 0);
}
#endif
#ifdef CONFIG_USBHOST_PLATFORM_CDC_NCM
#include "usbh_cdc_ncm.h"
struct netif g_cdc_ncm_netif;
static err_t usbh_cdc_ncm_linkoutput(struct netif *netif, struct pbuf *p)
{
int ret = usbh_cdc_ncm_eth_output(p->payload, p->tot_len);
if (ret < 0) {
return ERR_BUF;
} else {
return ERR_OK;
}
}
void usbh_cdc_ncm_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_lwip_eth_input_common(&g_cdc_ncm_netif, buf, buflen);
}
static err_t usbh_cdc_ncm_if_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
netif->mtu = 1500;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
netif->state = NULL;
netif->name[0] = 'E';
netif->name[1] = 'X';
netif->output = etharp_output;
netif->linkoutput = usbh_cdc_ncm_linkoutput;
return ERR_OK;
}
void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class)
{
struct netif *netif = &g_cdc_ncm_netif;
netif->hwaddr_len = 6;
memcpy(netif->hwaddr, cdc_ncm_class->mac, 6);
IP4_ADDR(&g_ipaddr, 0, 0, 0, 0);
IP4_ADDR(&g_netmask, 0, 0, 0, 0);
IP4_ADDR(&g_gateway, 0, 0, 0, 0);
netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_cdc_ncm_if_init, tcpip_input);
netif_set_default(netif);
while (!netif_is_up(netif)) {
}
dhcp_handle = xTimerCreate((const char *)"dhcp", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle == NULL) {
USB_LOG_ERR("timer creation failed! \r\n");
while (1) {
}
}
usb_osal_thread_create("usbh_cdc_ncm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ncm_rx_thread, NULL);
#if LWIP_DHCP
dhcp_start(netif);
xTimerStart(dhcp_handle, 0);
#endif
}
void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class)
{
struct netif *netif = &g_cdc_ncm_netif;
#if LWIP_DHCP
dhcp_stop(netif);
dhcp_cleanup(netif);
xTimerStop(dhcp_handle, 0);
xTimerDelete(dhcp_handle, 0);
#endif
netif_set_down(netif);
netif_remove(netif);
}
#endif
#ifdef CONFIG_USBHOST_PLATFORM_ASIX
#include "usbh_asix.h"
struct netif g_asix_netif;
static err_t usbh_asix_linkoutput(struct netif *netif, struct pbuf *p)
{
int ret = usbh_asix_eth_output(p->payload, p->tot_len);
if (ret < 0) {
return ERR_BUF;
} else {
return ERR_OK;
}
}
void usbh_asix_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_lwip_eth_input_common(&g_asix_netif, buf, buflen);
}
static err_t usbh_asix_if_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
netif->mtu = 1500;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
netif->state = NULL;
netif->name[0] = 'E';
netif->name[1] = 'X';
netif->output = etharp_output;
netif->linkoutput = usbh_asix_linkoutput;
return ERR_OK;
}
void usbh_asix_run(struct usbh_asix *asix_class)
{
struct netif *netif = &g_asix_netif;
netif->hwaddr_len = 6;
memcpy(netif->hwaddr, asix_class->mac, 6);
IP4_ADDR(&g_ipaddr, 0, 0, 0, 0);
IP4_ADDR(&g_netmask, 0, 0, 0, 0);
IP4_ADDR(&g_gateway, 0, 0, 0, 0);
netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_asix_if_init, tcpip_input);
netif_set_default(netif);
while (!netif_is_up(netif)) {
}
dhcp_handle = xTimerCreate((const char *)"dhcp", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle == NULL) {
USB_LOG_ERR("timer creation failed! \r\n");
while (1) {
}
}
usb_osal_thread_create("usbh_asix_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_asix_rx_thread, NULL);
#if LWIP_DHCP
dhcp_start(netif);
xTimerStart(dhcp_handle, 0);
#endif
}
void usbh_asix_stop(struct usbh_asix *asix_class)
{
struct netif *netif = &g_asix_netif;
#if LWIP_DHCP
dhcp_stop(netif);
dhcp_cleanup(netif);
xTimerStop(dhcp_handle, 0);
xTimerDelete(dhcp_handle, 0);
#endif
netif_set_down(netif);
netif_remove(netif);
}
#endif
#ifdef CONFIG_USBHOST_PLATFORM_RTL8152
#include "usbh_rtl8152.h"
struct netif g_rtl8152_netif;
static err_t usbh_rtl8152_linkoutput(struct netif *netif, struct pbuf *p)
{
int ret = usbh_rtl8152_eth_output(p->payload, p->tot_len);
if (ret < 0) {
return ERR_BUF;
} else {
return ERR_OK;
}
}
void usbh_rtl8152_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_lwip_eth_input_common(&g_rtl8152_netif, buf, buflen);
}
static err_t usbh_rtl8152_if_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
netif->mtu = 1500;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
netif->state = NULL;
netif->name[0] = 'E';
netif->name[1] = 'X';
netif->output = etharp_output;
netif->linkoutput = usbh_rtl8152_linkoutput;
return ERR_OK;
}
void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class)
{
struct netif *netif = &g_rtl8152_netif;
netif->hwaddr_len = 6;
memcpy(netif->hwaddr, rtl8152_class->mac, 6);
IP4_ADDR(&g_ipaddr, 0, 0, 0, 0);
IP4_ADDR(&g_netmask, 0, 0, 0, 0);
IP4_ADDR(&g_gateway, 0, 0, 0, 0);
netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_rtl8152_if_init, tcpip_input);
netif_set_default(netif);
while (!netif_is_up(netif)) {
}
dhcp_handle = xTimerCreate((const char *)"dhcp", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout);
if (dhcp_handle == NULL) {
USB_LOG_ERR("timer creation failed! \r\n");
while (1) {
}
}
usb_osal_thread_create("usbh_rtl8152_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rtl8152_rx_thread, NULL);
#if LWIP_DHCP
dhcp_start(netif);
xTimerStart(dhcp_handle, 0);
#endif
}
void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class)
{
struct netif *netif = &g_rtl8152_netif;
#if LWIP_DHCP
dhcp_stop(netif);
dhcp_cleanup(netif);
xTimerStop(dhcp_handle, 0);
xTimerDelete(dhcp_handle, 0);
#endif
netif_set_down(netif);
netif_remove(netif);
}
#endif

189
platform/nuttx/usbh_fs.c Normal file
View File

@ -0,0 +1,189 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <nuttx/config.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/kmalloc.h>
#include <nuttx/signal.h>
#include <nuttx/arch.h>
#include <nuttx/wqueue.h>
#include <nuttx/scsi.h>
#include <nuttx/fs/fs.h>
#include <nuttx/mutex.h>
#include "usbh_core.h"
#include "usbh_msc.h"
#ifdef CONFIG_ARCH_CHIP_HPMICRO
#include "hpm_misc.h"
#define usbhmsc_phy2sysaddr(a) core_local_mem_to_sys_address(0, a)
#else
#define usbhmsc_phy2sysaddr(a) (a)
#endif
static int usbhost_open(FAR struct inode *inode);
static int usbhost_close(FAR struct inode *inode);
static ssize_t usbhost_read(FAR struct inode *inode, unsigned char *buffer,
blkcnt_t startsector, unsigned int nsectors);
static ssize_t usbhost_write(FAR struct inode *inode,
FAR const unsigned char *buffer,
blkcnt_t startsector, unsigned int nsectors);
static int usbhost_geometry(FAR struct inode *inode,
FAR struct geometry *geometry);
static int usbhost_ioctl(FAR struct inode *inode, int cmd, unsigned long arg);
/* Block driver operations. This is the interface exposed to NuttX by the
* class that permits it to behave like a block driver.
*/
static const struct block_operations g_bops = {
usbhost_open, /* open */
usbhost_close, /* close */
usbhost_read, /* read */
usbhost_write, /* write */
usbhost_geometry, /* geometry */
usbhost_ioctl /* ioctl */
};
static int usbhost_open(FAR struct inode *inode)
{
struct usbh_msc *msc_class;
DEBUGASSERT(inode->i_private);
msc_class = (struct usbh_msc *)inode->i_private;
if (msc_class->hport && msc_class->hport->connected) {
return OK;
} else {
return -ENODEV;
}
}
static int usbhost_close(FAR struct inode *inode)
{
DEBUGASSERT(inode->i_private);
return 0;
}
static ssize_t usbhost_read(FAR struct inode *inode, unsigned char *buffer,
blkcnt_t startsector, unsigned int nsectors)
{
struct usbh_msc *msc_class;
int ret;
DEBUGASSERT(inode->i_private);
msc_class = (struct usbh_msc *)inode->i_private;
if (msc_class->hport && msc_class->hport->connected) {
ret = usbh_msc_scsi_read10(msc_class, startsector, (uint8_t *)usbhmsc_phy2sysaddr((uint32_t)buffer), nsectors);
if (ret < 0) {
return ret;
} else {
#ifdef CONFIG_USBHOST_MSC_DCACHE
up_invalidate_dcache((uintptr_t)buffer, (uintptr_t)(buffer + nsectors * msc_class->blocksize));
#endif
return nsectors;
}
} else {
return -ENODEV;
}
}
static ssize_t usbhost_write(FAR struct inode *inode,
FAR const unsigned char *buffer,
blkcnt_t startsector, unsigned int nsectors)
{
struct usbh_msc *msc_class;
int ret;
DEBUGASSERT(inode->i_private);
msc_class = (struct usbh_msc *)inode->i_private;
if (msc_class->hport && msc_class->hport->connected) {
#ifdef CONFIG_USBHOST_MSC_DCACHE
up_flush_dcache((uintptr_t)buffer, (uintptr_t)(buffer + nsectors * msc_class->blocksize));
#endif
ret = usbh_msc_scsi_write10(msc_class, startsector, (uint8_t *)usbhmsc_phy2sysaddr((uint32_t)buffer), nsectors);
if (ret < 0) {
return ret;
} else {
return nsectors;
}
} else {
return -ENODEV;
}
}
static int usbhost_geometry(FAR struct inode *inode,
FAR struct geometry *geometry)
{
struct usbh_msc *msc_class;
DEBUGASSERT(inode->i_private);
msc_class = (struct usbh_msc *)inode->i_private;
if (msc_class->hport && msc_class->hport->connected) {
memset(geometry, 0, sizeof(*geometry));
geometry->geo_available = true;
geometry->geo_mediachanged = false;
geometry->geo_writeenabled = true;
geometry->geo_nsectors = msc_class->blocknum;
geometry->geo_sectorsize = msc_class->blocksize;
uinfo("nsectors: %" PRIdOFF " sectorsize: %" PRIi16 "\n",
geometry->geo_nsectors, geometry->geo_sectorsize);
return OK;
} else {
return -ENODEV;
}
return 0;
}
static int usbhost_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
{
struct usbh_msc *msc_class;
DEBUGASSERT(inode->i_private);
msc_class = (struct usbh_msc *)inode->i_private;
if (msc_class->hport && msc_class->hport->connected) {
return -ENOTTY;
} else {
return -ENODEV;
}
return 0;
}
#define DEV_FORMAT "/dev/sd%c"
void usbh_msc_run(struct usbh_msc *msc_class)
{
char devname[32];
snprintf(devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar);
register_blockdriver(devname, &g_bops, 0, msc_class);
}
void usbh_msc_stop(struct usbh_msc *msc_class)
{
char devname[32];
snprintf(devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar);
unregister_blockdriver(devname);
}

165
platform/nuttx/usbh_net.c Normal file
View File

@ -0,0 +1,165 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <nuttx/config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <semaphore.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/net/ip.h>
#include <nuttx/net/netdev.h>
#include "usbh_core.h"
#define CONFIG_USBHOST_PLATFORM_CDC_ECM
#define CONFIG_USBHOST_PLATFORM_CDC_RNDIS
#define CONFIG_USBHOST_PLATFORM_CDC_NCM
#define CONFIG_USBHOST_PLATFORM_ASIX
#define CONFIG_USBHOST_PLATFORM_RTL8152
struct usbh_net {
struct net_driver_s netdev;
struct work_s txpollwork;
bool linkup;
};
void usbh_net_eth_input_common(struct net_driver_s *dev, uint8_t *buf, size_t len, int (*eth_output)(uint8_t *buf, uint32_t buflen))
{
FAR struct eth_hdr_s *hdr;
net_lock();
NETDEV_RXPACKETS(dev);
/* Any ACK or other response packet generated by the network stack
* will always be shorter than the received packet, therefore it is
* safe to pass the received frame buffer directly.
*/
dev->d_buf = buf;
dev->d_len = len;
hdr = (FAR struct eth_hdr_s *)dev->d_buf;
#ifdef CONFIG_NET_IPv4
if (hdr->type == HTONS(ETHTYPE_IP)) {
NETDEV_RXIPV4(dev);
/* Receive an IPv4 packet from the network device */
ipv4_input(dev);
if (dev->d_len > 0) {
/* And send the packet */
eth_output(dev->d_buf, dev->d_len);
}
} else
#endif
#ifdef CONFIG_NET_IPv6
if (hdr->type == HTONS(ETHTYPE_IP6)) {
NETDEV_RXIPV6(dev);
/* Give the IPv6 packet to the network layer */
ipv6_input(dev);
if (dev->d_len > 0) {
/* And send the packet */
eth_output(dev->d_buf, dev->d_len);
}
} else
#endif
#ifdef CONFIG_NET_ARP
if (hdr->type == HTONS(ETHTYPE_ARP)) {
NETDEV_RXARP(dev);
arp_input(dev);
if (dev->d_len > 0) {
eth_output(dev->d_buf, dev->d_len);
}
} else
#endif
{
NETDEV_RXDROPPED(dev);
}
net_unlock();
}
#ifdef CONFIG_USBHOST_PLATFORM_CDC_RNDIS
#include "usbh_rndis.h"
struct usbh_net g_rndis_dev;
static int rndis_ifup(struct net_driver_s *dev)
{
printf("rndis if up\r\n");
g_rndis_dev.linkup = true;
usb_osal_thread_create("usbh_rndis_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rndis_rx_thread, NULL);
return OK;
}
static int rndis_ifdown(struct net_driver_s *dev)
{
printf("rndis if down\r\n");
g_rndis_dev.linkup = false;
return OK;
}
static int rndis_txpoll(struct net_driver_s *dev)
{
return usbh_rndis_eth_output(g_rndis_dev.netdev.d_buf, g_rndis_dev.netdev.d_len);
}
static void rndis_txavail_work(void *arg)
{
net_lock();
if (g_rndis_dev.linkup) {
devif_poll(&g_rndis_dev.netdev, rndis_txpoll);
} else {
}
net_unlock();
}
static int rndis_txavail(struct net_driver_s *dev)
{
if (work_available(&g_rndis_dev.txpollwork)) {
work_queue(LPWORK, &g_rndis_dev.txpollwork, rndis_txavail_work, NULL, 0);
} else {
return -1;
}
return OK;
}
void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_net_eth_input_common(&g_rndis_dev.netdev, buf, buflen, usbh_rndis_eth_output);
}
void usbh_rndis_run(struct usbh_rndis *rndis_class)
{
memset(&g_rndis_dev.netdev, 0, sizeof(struct net_driver_s));
g_rndis_dev.netdev.d_ifup = rndis_ifup;
g_rndis_dev.netdev.d_ifdown = rndis_ifdown;
g_rndis_dev.netdev.d_txavail = rndis_txavail;
g_rndis_dev.netdev.d_private = rndis_class;
for (uint8_t j = 0; j < 6; j++) {
g_rndis_dev.netdev.d_mac.ether.ether_addr_octet[j] = rndis_class->mac[j];
}
netdev_register(&g_rndis_dev.netdev, NET_LL_ETHERNET);
}
void usbh_rndis_stop(struct usbh_rndis *rndis_class)
{
}
#endif

View File

@ -0,0 +1,17 @@
#include "rtthread.h"
#ifdef PKG_CHERRYUSB_HOST
#ifndef RT_USING_TIMER_SOFT
#error must enable RT_USING_TIMER_SOFT to support timer callback in thread
#endif
#if IDLE_THREAD_STACK_SIZE < 2048
#error "IDLE_THREAD_STACK_SIZE must be greater than 2048"
#endif
#if RT_TIMER_THREAD_STACK_SIZE < 2048
#error "RT_TIMER_THREAD_STACK_SIZE must be greater than 2048"
#endif
#endif

View File

@ -238,4 +238,4 @@ void usbh_msc_stop(struct usbh_msc *msc_class)
dfs_unmount(mount_point);
rt_device_unregister(rt_device_find(name));
}
}

View File

@ -0,0 +1,415 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "netif/etharp.h"
#include "lwip/netif.h"
#include "lwip/pbuf.h"
#include "lwip/tcpip.h"
#if LWIP_DHCP
#include "lwip/dhcp.h"
#include "lwip/prot/dhcp.h"
#endif
#include <rtthread.h>
#include <rtdevice.h>
#include <netif/ethernetif.h>
#include "usbh_core.h"
#include "lwip/opt.h"
#ifndef RT_USING_LWIP212
#error must enable RT_USING_LWIP212
#endif
#ifndef LWIP_NO_RX_THREAD
#error must enable LWIP_NO_RX_THREAD, we do not use rtthread eth rx thread
#endif
#ifndef LWIP_NO_TX_THREAD
#warning suggest you to enable LWIP_NO_TX_THREAD, we do not use rtthread eth tx thread
#endif
#if LWIP_TCPIP_CORE_LOCKING_INPUT !=1
#warning suggest you to set LWIP_TCPIP_CORE_LOCKING_INPUT to 1, usb handles eth input with own thread
#endif
#if LWIP_TCPIP_CORE_LOCKING !=1
#error must set LWIP_TCPIP_CORE_LOCKING to 1
#endif
#if PBUF_POOL_BUFSIZE < 1600
#error PBUF_POOL_BUFSIZE must be larger than 1600
#endif
// #define CONFIG_USBHOST_PLATFORM_CDC_ECM
// #define CONFIG_USBHOST_PLATFORM_CDC_RNDIS
// #define CONFIG_USBHOST_PLATFORM_CDC_NCM
// #define CONFIG_USBHOST_PLATFORM_ASIX
// #define CONFIG_USBHOST_PLATFORM_RTL8152
void usbh_lwip_eth_input_common(struct netif *netif, uint8_t *buf, uint32_t len)
{
#if LWIP_TCPIP_CORE_LOCKING_INPUT
pbuf_type type = PBUF_REF;
#else
pbuf_type type = PBUF_POOL;
#endif
err_t err;
struct pbuf *p;
p = pbuf_alloc(PBUF_RAW, len, type);
if (p != NULL) {
#if LWIP_TCPIP_CORE_LOCKING_INPUT
p->payload = buf;
#else
memcpy(p->payload, buf, len);
#endif
err = netif->input(p, netif);
if (err != ERR_OK) {
pbuf_free(p);
}
} else {
USB_LOG_ERR("No memory to alloc pbuf\r\n");
}
}
#ifdef CONFIG_USBHOST_PLATFORM_CDC_ECM
#include "usbh_cdc_ecm.h"
static struct eth_device g_cdc_ecm_dev;
static rt_err_t rt_usbh_cdc_ecm_control(rt_device_t dev, int cmd, void *args)
{
struct usbh_cdc_ecm *cdc_ecm_class = (struct usbh_cdc_ecm *)dev->user_data;
switch (cmd) {
case NIOCTL_GADDR:
/* get mac address */
if (args)
rt_memcpy(args, cdc_ecm_class->mac, 6);
else
return -RT_ERROR;
break;
default:
break;
}
return RT_EOK;
}
static rt_err_t rt_usbh_cdc_ecm_eth_tx(rt_device_t dev, struct pbuf *p)
{
int ret = usbh_cdc_ecm_eth_output(p->payload, p->tot_len);
if (ret < 0) {
return -RT_ERROR;
} else {
return RT_EOK;
}
}
void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_lwip_eth_input_common(g_cdc_ecm_dev.netif, buf, buflen);
}
void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class)
{
memset(&g_cdc_ecm_dev, 0, sizeof(struct eth_device));
g_cdc_ecm_dev.parent.control = rt_usbh_cdc_ecm_control;
g_cdc_ecm_dev.eth_rx = NULL;
g_cdc_ecm_dev.eth_tx = rt_usbh_cdc_ecm_eth_tx;
g_cdc_ecm_dev.parent.user_data = cdc_ecm_class;
eth_device_init(&g_cdc_ecm_dev, "u0");
eth_device_linkchange(&g_cdc_ecm_dev, RT_TRUE);
usb_osal_thread_create("usbh_cdc_ecm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ecm_rx_thread, NULL);
}
void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class)
{
eth_device_deinit(&g_cdc_ecm_dev);
}
#endif
#ifdef CONFIG_USBHOST_PLATFORM_CDC_RNDIS
#include "usbh_rndis.h"
static struct eth_device g_rndis_dev;
static rt_timer_t keep_timer = RT_NULL;
static void rndis_dev_keepalive_timeout(void *parameter)
{
struct usbh_rndis *rndis_class = (struct usbh_rndis *)parameter;
usbh_rndis_keepalive(rndis_class);
}
static void timer_init(struct usbh_rndis *rndis_class)
{
keep_timer = rt_timer_create("keep",
rndis_dev_keepalive_timeout,
rndis_class,
5000,
RT_TIMER_FLAG_PERIODIC |
RT_TIMER_FLAG_SOFT_TIMER);
rt_timer_start(keep_timer);
}
static rt_err_t rt_usbh_rndis_control(rt_device_t dev, int cmd, void *args)
{
struct usbh_rndis *rndis_class = (struct usbh_rndis *)dev->user_data;
switch (cmd) {
case NIOCTL_GADDR:
/* get mac address */
if (args)
rt_memcpy(args, rndis_class->mac, 6);
else
return -RT_ERROR;
break;
default:
break;
}
return RT_EOK;
}
static rt_err_t rt_usbh_rndis_eth_tx(rt_device_t dev, struct pbuf *p)
{
int ret = usbh_rndis_eth_output(p->payload, p->tot_len);
if (ret < 0) {
return -RT_ERROR;
} else {
return RT_EOK;
}
}
void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_lwip_eth_input_common(g_rndis_dev.netif, buf, buflen);
}
void usbh_rndis_run(struct usbh_rndis *rndis_class)
{
memset(&g_rndis_dev, 0, sizeof(struct eth_device));
g_rndis_dev.parent.control = rt_usbh_rndis_control;
g_rndis_dev.eth_rx = NULL;
g_rndis_dev.eth_tx = rt_usbh_rndis_eth_tx;
g_rndis_dev.parent.user_data = rndis_class;
eth_device_init(&g_rndis_dev, "u2");
eth_device_linkchange(&g_rndis_dev, RT_TRUE);
usb_osal_thread_create("usbh_rndis_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rndis_rx_thread, NULL);
//timer_init(rndis_class);
}
void usbh_rndis_stop(struct usbh_rndis *rndis_class)
{
eth_device_deinit(&g_rndis_dev);
// rt_timer_stop(keep_timer);
// rt_timer_delete(keep_timer);
}
#endif
#ifdef CONFIG_USBHOST_PLATFORM_CDC_NCM
#include "usbh_cdc_ncm.h"
static struct eth_device g_cdc_ncm_dev;
static rt_err_t rt_usbh_cdc_ncm_control(rt_device_t dev, int cmd, void *args)
{
struct usbh_cdc_ncm *cdc_ncm_class = (struct usbh_cdc_ncm *)dev->user_data;
switch (cmd) {
case NIOCTL_GADDR:
/* get mac address */
if (args)
rt_memcpy(args, cdc_ncm_class->mac, 6);
else
return -RT_ERROR;
break;
default:
break;
}
return RT_EOK;
}
static rt_err_t rt_usbh_cdc_ncm_eth_tx(rt_device_t dev, struct pbuf *p)
{
int ret = usbh_cdc_ncm_eth_output(p->payload, p->tot_len);
if (ret < 0) {
return -RT_ERROR;
} else {
return RT_EOK;
}
}
void usbh_cdc_ncm_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_lwip_eth_input_common(g_cdc_ncm_dev.netif, buf, buflen);
}
void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class)
{
memset(&g_cdc_ncm_dev, 0, sizeof(struct eth_device));
g_cdc_ncm_dev.parent.control = rt_usbh_cdc_ncm_control;
g_cdc_ncm_dev.eth_rx = NULL;
g_cdc_ncm_dev.eth_tx = rt_usbh_cdc_ncm_eth_tx;
g_cdc_ncm_dev.parent.user_data = cdc_ncm_class;
eth_device_init(&g_cdc_ncm_dev, "u1");
eth_device_linkchange(&g_cdc_ncm_dev, RT_TRUE);
usb_osal_thread_create("usbh_cdc_ncm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ncm_rx_thread, NULL);
}
void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class)
{
eth_device_deinit(&g_cdc_ncm_dev);
}
#endif
#ifdef CONFIG_USBHOST_PLATFORM_ASIX
#include "usbh_asix.h"
static struct eth_device g_asix_dev;
static rt_err_t rt_usbh_asix_control(rt_device_t dev, int cmd, void *args)
{
struct usbh_asix *asix_class = (struct usbh_asix *)dev->user_data;
switch (cmd) {
case NIOCTL_GADDR:
/* get mac address */
if (args)
rt_memcpy(args, asix_class->mac, 6);
else
return -RT_ERROR;
break;
default:
break;
}
return RT_EOK;
}
static rt_err_t rt_usbh_asix_eth_tx(rt_device_t dev, struct pbuf *p)
{
int ret = usbh_asix_eth_output(p->payload, p->tot_len);
if (ret < 0) {
return -RT_ERROR;
} else {
return RT_EOK;
}
}
void usbh_asix_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_lwip_eth_input_common(g_asix_dev.netif, buf, buflen);
}
void usbh_asix_run(struct usbh_asix *asix_class)
{
memset(&g_asix_dev, 0, sizeof(struct eth_device));
g_asix_dev.parent.control = rt_usbh_asix_control;
g_asix_dev.eth_rx = NULL;
g_asix_dev.eth_tx = rt_usbh_asix_eth_tx;
g_asix_dev.parent.user_data = asix_class;
eth_device_init(&g_asix_dev, "u3");
eth_device_linkchange(&g_asix_dev, RT_TRUE);
usb_osal_thread_create("usbh_asix_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_asix_rx_thread, NULL);
}
void usbh_asix_stop(struct usbh_asix *asix_class)
{
eth_device_deinit(&g_asix_dev);
}
#endif
#ifdef CONFIG_USBHOST_PLATFORM_RTL8152
#include "usbh_rtl8152.h"
static struct eth_device g_rtl8152_dev;
static rt_err_t rt_usbh_rtl8152_control(rt_device_t dev, int cmd, void *args)
{
struct usbh_rtl8152 *rtl8152_class = (struct usbh_rtl8152 *)dev->user_data;
switch (cmd) {
case NIOCTL_GADDR:
/* get mac address */
if (args)
rt_memcpy(args, rtl8152_class->mac, 6);
else
return -RT_ERROR;
break;
default:
break;
}
return RT_EOK;
}
static rt_err_t rt_usbh_rtl8152_eth_tx(rt_device_t dev, struct pbuf *p)
{
int ret = usbh_rtl8152_eth_output(p->payload, p->tot_len);
if (ret < 0) {
return -RT_ERROR;
} else {
return RT_EOK;
}
}
void usbh_rtl8152_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_lwip_eth_input_common(g_rtl8152_dev.netif, buf, buflen);
}
void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class)
{
memset(&g_rtl8152_dev, 0, sizeof(struct eth_device));
g_rtl8152_dev.parent.control = rt_usbh_rtl8152_control;
g_rtl8152_dev.eth_rx = NULL;
g_rtl8152_dev.eth_tx = rt_usbh_rtl8152_eth_tx;
g_rtl8152_dev.parent.user_data = rtl8152_class;
eth_device_init(&g_rtl8152_dev, "u4");
eth_device_linkchange(&g_rtl8152_dev, RT_TRUE);
usb_osal_thread_create("usbh_rtl8152_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rtl8152_rx_thread, NULL);
}
void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class)
{
eth_device_deinit(&g_rtl8152_dev);
}
#endif

View File

View File

@ -1,43 +0,0 @@
#include "rtthread.h"
#ifdef PKG_CHERRYUSB_HOST
#ifndef RT_USING_TIMER_SOFT
#error must enable RT_USING_TIMER_SOFT to support timer callback in thread
#endif
#if IDLE_THREAD_STACK_SIZE < 2048
#error "IDLE_THREAD_STACK_SIZE must be greater than 2048"
#endif
#if RT_TIMER_THREAD_STACK_SIZE < 2048
#error "RT_TIMER_THREAD_STACK_SIZE must be greater than 2048"
#endif
#ifdef RT_USING_LWIP
#include "lwip/opt.h"
#ifndef RT_USING_LWIP212
#error must enable RT_USING_LWIP212
#endif
#ifndef LWIP_NO_RX_THREAD
#error must enable LWIP_NO_RX_THREAD, we do not use rtthread eth rx thread
#endif
#if LWIP_TCPIP_CORE_LOCKING_INPUT !=1
#warning suggest you to set LWIP_TCPIP_CORE_LOCKING_INPUT to 1, usb handles eth input with own thread
#endif
#if LWIP_TCPIP_CORE_LOCKING !=1
#error must set LWIP_TCPIP_CORE_LOCKING to 1
#endif
#if PBUF_POOL_BUFSIZE < 1514
#error PBUF_POOL_BUFSIZE must be larger than 1514
#endif
#endif
#endif