mirror of
https://github.com/sakumisu/CherryUSB.git
synced 2025-05-09 00:21:44 +08:00
Deploying to gh-pages from @ cherry-embedded/CherryUSB@87b8a4ad7f 🚀
This commit is contained in:
parent
d366678a7d
commit
33bf8eabc5
@ -1,2 +1,21 @@
|
||||
usbd_webusb
|
||||
===============
|
||||
|
||||
本 demo 主要演示 webusb 功能,webusb 主要用于弹出网页并对 USB 设备进行访问。示例使用 webusb_hid_template.c。
|
||||
|
||||
- 在注册描述符时注册 BOS, MSOSV2, WEBUSB 描述符即可。
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
usbd_bos_desc_register(busid, &bos_desc);
|
||||
usbd_msosv2_desc_register(busid, &msosv2_desc);
|
||||
usbd_webusb_desc_register(busid, &webusb_url_desc);
|
||||
|
||||
- 增加一个接口描述符用于 webusb
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
USB_INTERFACE_DESCRIPTOR_INIT(USBD_WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00)
|
||||
|
||||
- 其余使用 hid 描述符,不再赘述
|
||||
- 枚举完成后,电脑右下角会弹出网页信息,点击即可打开网页
|
@ -1,2 +1,32 @@
|
||||
usbd_winusb
|
||||
===============
|
||||
|
||||
本节主要介绍 winusb 驱动。winusb 是 windows 为了让用户友好的访问 USB 自定义类设备提供的一套通用驱动,其实本质就是 CDC ACM。
|
||||
WINUSB 版本根据 USB 版本分为 V1/V2 版本,V2 版本需要包含 BOS 描述符,V1 版本不需要。V2 版本需要在设备描述符中设置为 USB2.1 的版本号。
|
||||
|
||||
- V1 版本注册描述符
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
usbd_msosv1_desc_register(busid, &msosv1_desc);
|
||||
|
||||
- V2 版本注册描述符
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
usbd_bos_desc_register(busid, &bos_desc);
|
||||
usbd_msosv2_desc_register(busid, &msosv2_desc);
|
||||
|
||||
|
||||
- 接口描述符注册
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
/* Interface 0 */
|
||||
USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
|
||||
/* Endpoint OUT 2 */
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
|
||||
/* Endpoint IN 1 */
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
|
||||
|
||||
- 其余操作与 CDC ACM 相同,不再赘述
|
@ -1,2 +1,51 @@
|
||||
usbh_hid
|
||||
===============
|
||||
|
||||
本节主要介绍 HID 类的使用。
|
||||
|
||||
- HID 枚举完成回调中创建一次性线程
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
|
||||
void usbh_hid_run(struct usbh_hid *hid_class)
|
||||
{
|
||||
usb_osal_thread_create("usbh_hid", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hid_thread, hid_class);
|
||||
}
|
||||
|
||||
void usbh_hid_stop(struct usbh_hid *hid_class)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
- 这里我们使用 usbh_submit_urb 的异步操作,在中断中处理数据并继续接收下一次数据。
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
static void usbh_hid_thread(void *argument)
|
||||
{
|
||||
int ret;
|
||||
struct usbh_hid *hid_class = (struct usbh_hid *)argument;
|
||||
;
|
||||
|
||||
/* test with only one buffer, if you have more hid class, modify by yourself */
|
||||
|
||||
/* Suggest you to use timer for int transfer and use ep interval */
|
||||
usbh_int_urb_fill(&hid_class->intin_urb, hid_class->hport, hid_class->intin, hid_buffer, hid_class->intin->wMaxPacketSize, 0, usbh_hid_callback, hid_class);
|
||||
ret = usbh_submit_urb(&hid_class->intin_urb);
|
||||
if (ret < 0) {
|
||||
goto delete;
|
||||
}
|
||||
// clang-format off
|
||||
delete:
|
||||
usb_osal_thread_delete(NULL);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
- 当然,也可以不使用异步操作,而是使用 timeout 的同步操作。
|
||||
- HID 使用的是中断传输,因此正常来说,我们需要根据 **bInterval** 来设置定时器,定时触发中断传输,demo 这里没有使用,如果对时间有精确要求,可以选择使用定时器来触发异步发送。
|
||||
- 以 hub 通信为例,采用的是一次性定时器,也可以使用周期性定时器。
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
hub->int_timer = usb_osal_timer_create("hubint_tim", USBH_GET_URB_INTERVAL(hub->intin->bInterval, hport->speed), hub_int_timeout, hub, 0);
|
||||
|
@ -1,2 +1,56 @@
|
||||
usbh_msc
|
||||
===============
|
||||
|
||||
本节主要介绍主机 MSC 使用。借助 FATFS 实现读写功能。
|
||||
|
||||
- 在 msc 枚举完成的回调中注册一个线程,用于读写操作。
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
void usbh_msc_run(struct usbh_msc *msc_class)
|
||||
{
|
||||
usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class);
|
||||
}
|
||||
|
||||
void usbh_msc_stop(struct usbh_msc *msc_class)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
- 不使用 fatfs,则直接使用 usbh_msc_scsi_read10 或者 usbh_msc_scsi_write10 函数进行读写操作。
|
||||
- 如果使用 fatfs,则需要在 usbh_msc_thread 中调用 fatfs 的接口进行读写操作。msc读写适配fatfs 参考 `platform/none/usbh_fatfs.c`
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
static void usbh_msc_thread(void *argument)
|
||||
{
|
||||
int ret;
|
||||
struct usbh_msc *msc_class = (struct usbh_msc *)argument;
|
||||
|
||||
/* test with only one buffer, if you have more msc class, modify by yourself */
|
||||
#if 1
|
||||
/* get the partition table */
|
||||
ret = usbh_msc_scsi_read10(msc_class, 0, partition_table, 1);
|
||||
if (ret < 0) {
|
||||
USB_LOG_RAW("scsi_read10 error,ret:%d\r\n", ret);
|
||||
goto delete;
|
||||
}
|
||||
for (uint32_t i = 0; i < 512; i++) {
|
||||
if (i % 16 == 0) {
|
||||
USB_LOG_RAW("\r\n");
|
||||
}
|
||||
USB_LOG_RAW("%02x ", partition_table[i]);
|
||||
}
|
||||
USB_LOG_RAW("\r\n");
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_MSC_FATFS
|
||||
usb_msc_fatfs_test();
|
||||
#endif
|
||||
// clang-format off
|
||||
delete:
|
||||
usb_osal_thread_delete(NULL);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
- 最后处理完成或者失败后,删除线程。
|
@ -1,2 +1,106 @@
|
||||
usbh_net
|
||||
===============
|
||||
|
||||
本节主要介绍 USB 网卡的使用,USB 网卡推荐采用 AIR780(RNDIS),EC20(ECM/RNDIS), 手机(RNDIS),RTL8152 USB 网卡,AX88772 USB 网卡。
|
||||
|
||||
USB 网卡传输层面已经对接好了 LWIP 的收发接口,因此,用户只需要包含 **platform/XXX/usbh_lwip.c** 并根据需要开启对应的网卡类的宏即可。
|
||||
|
||||
- 当前支持以下网卡类:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
// #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
|
||||
// #define CONFIG_USBHOST_PLATFORM_BL616
|
||||
|
||||
- 包含了对接 LWIP 的输入输出接口,举例如下
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
static err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
int ret;
|
||||
(void)netif;
|
||||
|
||||
usbh_lwip_eth_output_common(p, usbh_cdc_ecm_get_eth_txbuf());
|
||||
ret = usbh_cdc_ecm_eth_output(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);
|
||||
}
|
||||
|
||||
|
||||
- 网卡类枚举完成后,注册 netif,并且创建网卡接收线程(因此使用 RTTHREAD 时不需要使用 RTT 的接收线程模块)。
|
||||
- 必须开启 DHCP client 服务,用于从 USB 网卡获取 IP 地址。
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
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 = usb_osal_timer_create("dhcp", 200, dhcp_timeout, netif, true);
|
||||
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);
|
||||
usb_osal_timer_start(dhcp_handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
- 获取到 IP 以后,就与 USB 没有关系了,直接使用 LWIP 的接口即可。
|
||||
|
||||
- 需要注意以下参数
|
||||
|
||||
LWIP_TCPIP_CORE_LOCKING_INPUT 用于不使用 lwip 内置的 tcpip 线程,而使用 USB 自己的处理线程。
|
||||
|
||||
LWIP_TCPIP_CORE_LOCKING 在现在 lwip 版本中默认是打开的,也推荐必须打开。
|
||||
|
||||
PBUF_POOL_BUFSIZE 推荐大于1600,搭配 LWIP_TCPIP_CORE_LOCKING_INPUT 使用,因为我们提供了使用 zero mempy 的方式,使用静态 pbuf,而不是把数据 copy 到 pbuf 中。
|
||||
|
||||
TCPIP_THREAD_STACKSIZE 推荐大于 1K,防止栈溢出。
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
#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
|
||||
|
||||
#if TCPIP_THREAD_STACKSIZE < 1024
|
||||
#error TCPIP_THREAD_STACKSIZE must be >= 1024
|
||||
#endif
|
||||
|
@ -151,6 +151,26 @@
|
||||
|
||||
<section id="usbd-webusb">
|
||||
<h1>usbd_webusb<a class="headerlink" href="#usbd-webusb" title="Link to this heading"></a></h1>
|
||||
<p>本 demo 主要演示 webusb 功能,webusb 主要用于弹出网页并对 USB 设备进行访问。示例使用 webusb_hid_template.c。</p>
|
||||
<ul class="simple">
|
||||
<li><p>在注册描述符时注册 BOS, MSOSV2, WEBUSB 描述符即可。</p></li>
|
||||
</ul>
|
||||
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="n">usbd_bos_desc_register</span><span class="p">(</span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">bos_desc</span><span class="p">);</span>
|
||||
<span class="n">usbd_msosv2_desc_register</span><span class="p">(</span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">msosv2_desc</span><span class="p">);</span>
|
||||
<span class="n">usbd_webusb_desc_register</span><span class="p">(</span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">webusb_url_desc</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>增加一个接口描述符用于 webusb</p></li>
|
||||
</ul>
|
||||
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>USB_INTERFACE_DESCRIPTOR_INIT(USBD_WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00)</p>
|
||||
<ul class="simple">
|
||||
<li><p>其余使用 hid 描述符,不再赘述</p></li>
|
||||
<li><p>枚举完成后,电脑右下角会弹出网页信息,点击即可打开网页</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
|
||||
|
@ -151,6 +151,35 @@
|
||||
|
||||
<section id="usbd-winusb">
|
||||
<h1>usbd_winusb<a class="headerlink" href="#usbd-winusb" title="Link to this heading"></a></h1>
|
||||
<p>本节主要介绍 winusb 驱动。winusb 是 windows 为了让用户友好的访问 USB 自定义类设备提供的一套通用驱动,其实本质就是 CDC ACM。
|
||||
WINUSB 版本根据 USB 版本分为 V1/V2 版本,V2 版本需要包含 BOS 描述符,V1 版本不需要。V2 版本需要在设备描述符中设置为 USB2.1 的版本号。</p>
|
||||
<ul class="simple">
|
||||
<li><p>V1 版本注册描述符</p></li>
|
||||
</ul>
|
||||
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="n">usbd_msosv1_desc_register</span><span class="p">(</span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">msosv1_desc</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>V2 版本注册描述符</p></li>
|
||||
</ul>
|
||||
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="n">usbd_bos_desc_register</span><span class="p">(</span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">bos_desc</span><span class="p">);</span>
|
||||
<span class="n">usbd_msosv2_desc_register</span><span class="p">(</span><span class="n">busid</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">msosv2_desc</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>接口描述符注册</p></li>
|
||||
</ul>
|
||||
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="cm">/* Interface 0 */</span>
|
||||
<span class="n">USB_INTERFACE_DESCRIPTOR_INIT</span><span class="p">(</span><span class="mh">0x00</span><span class="p">,</span><span class="w"> </span><span class="mh">0x00</span><span class="p">,</span><span class="w"> </span><span class="mh">0x02</span><span class="p">,</span><span class="w"> </span><span class="mh">0xFF</span><span class="p">,</span><span class="w"> </span><span class="mh">0x00</span><span class="p">,</span><span class="w"> </span><span class="mh">0x00</span><span class="p">,</span><span class="w"> </span><span class="mh">0x02</span><span class="p">),</span>
|
||||
<span class="cm">/* Endpoint OUT 2 */</span>
|
||||
<span class="n">USB_ENDPOINT_DESCRIPTOR_INIT</span><span class="p">(</span><span class="n">WINUSB_OUT_EP</span><span class="p">,</span><span class="w"> </span><span class="n">USB_ENDPOINT_TYPE_BULK</span><span class="p">,</span><span class="w"> </span><span class="n">WINUSB_EP_MPS</span><span class="p">,</span><span class="w"> </span><span class="mh">0x00</span><span class="p">),</span>
|
||||
<span class="cm">/* Endpoint IN 1 */</span>
|
||||
<span class="n">USB_ENDPOINT_DESCRIPTOR_INIT</span><span class="p">(</span><span class="n">WINUSB_IN_EP</span><span class="p">,</span><span class="w"> </span><span class="n">USB_ENDPOINT_TYPE_BULK</span><span class="p">,</span><span class="w"> </span><span class="n">WINUSB_EP_MPS</span><span class="p">,</span><span class="w"> </span><span class="mh">0x00</span><span class="p">),</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>其余操作与 CDC ACM 相同,不再赘述</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
|
||||
|
@ -151,6 +151,52 @@
|
||||
|
||||
<section id="usbh-hid">
|
||||
<h1>usbh_hid<a class="headerlink" href="#usbh-hid" title="Link to this heading"></a></h1>
|
||||
<p>本节主要介绍 HID 类的使用。</p>
|
||||
<ul class="simple">
|
||||
<li><p>HID 枚举完成回调中创建一次性线程</p></li>
|
||||
</ul>
|
||||
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span><span class="w"> </span><span class="nf">usbh_hid_run</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_hid</span><span class="w"> </span><span class="o">*</span><span class="n">hid_class</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">usb_osal_thread_create</span><span class="p">(</span><span class="s">"usbh_hid"</span><span class="p">,</span><span class="w"> </span><span class="mi">2048</span><span class="p">,</span><span class="w"> </span><span class="n">CONFIG_USBHOST_PSC_PRIO</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">usbh_hid_thread</span><span class="p">,</span><span class="w"> </span><span class="n">hid_class</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="kt">void</span><span class="w"> </span><span class="nf">usbh_hid_stop</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_hid</span><span class="w"> </span><span class="o">*</span><span class="n">hid_class</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>这里我们使用 usbh_submit_urb 的异步操作,在中断中处理数据并继续接收下一次数据。</p></li>
|
||||
</ul>
|
||||
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">usbh_hid_thread</span><span class="p">(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">argument</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_hid</span><span class="w"> </span><span class="o">*</span><span class="n">hid_class</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_hid</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="n">argument</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="p">;</span>
|
||||
|
||||
<span class="w"> </span><span class="cm">/* test with only one buffer, if you have more hid class, modify by yourself */</span>
|
||||
|
||||
<span class="w"> </span><span class="cm">/* Suggest you to use timer for int transfer and use ep interval */</span>
|
||||
<span class="w"> </span><span class="n">usbh_int_urb_fill</span><span class="p">(</span><span class="o">&</span><span class="n">hid_class</span><span class="o">-></span><span class="n">intin_urb</span><span class="p">,</span><span class="w"> </span><span class="n">hid_class</span><span class="o">-></span><span class="n">hport</span><span class="p">,</span><span class="w"> </span><span class="n">hid_class</span><span class="o">-></span><span class="n">intin</span><span class="p">,</span><span class="w"> </span><span class="n">hid_buffer</span><span class="p">,</span><span class="w"> </span><span class="n">hid_class</span><span class="o">-></span><span class="n">intin</span><span class="o">-></span><span class="n">wMaxPacketSize</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">usbh_hid_callback</span><span class="p">,</span><span class="w"> </span><span class="n">hid_class</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">usbh_submit_urb</span><span class="p">(</span><span class="o">&</span><span class="n">hid_class</span><span class="o">-></span><span class="n">intin_urb</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ret</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="k">goto</span><span class="w"> </span><span class="n">delete</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="w"> </span><span class="c1">// clang-format off</span>
|
||||
<span class="nl">delete</span><span class="p">:</span>
|
||||
<span class="w"> </span><span class="n">usb_osal_thread_delete</span><span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="c1">// clang-format on</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>当然,也可以不使用异步操作,而是使用 timeout 的同步操作。</p></li>
|
||||
<li><p>HID 使用的是中断传输,因此正常来说,我们需要根据 <strong>bInterval</strong> 来设置定时器,定时触发中断传输,demo 这里没有使用,如果对时间有精确要求,可以选择使用定时器来触发异步发送。</p></li>
|
||||
<li><p>以 hub 通信为例,采用的是一次性定时器,也可以使用周期性定时器。</p></li>
|
||||
</ul>
|
||||
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="n">hub</span><span class="o">-></span><span class="n">int_timer</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">usb_osal_timer_create</span><span class="p">(</span><span class="s">"hubint_tim"</span><span class="p">,</span><span class="w"> </span><span class="n">USBH_GET_URB_INTERVAL</span><span class="p">(</span><span class="n">hub</span><span class="o">-></span><span class="n">intin</span><span class="o">-></span><span class="n">bInterval</span><span class="p">,</span><span class="w"> </span><span class="n">hport</span><span class="o">-></span><span class="n">speed</span><span class="p">),</span><span class="w"> </span><span class="n">hub_int_timeout</span><span class="p">,</span><span class="w"> </span><span class="n">hub</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
|
@ -151,6 +151,59 @@
|
||||
|
||||
<section id="usbh-msc">
|
||||
<h1>usbh_msc<a class="headerlink" href="#usbh-msc" title="Link to this heading"></a></h1>
|
||||
<p>本节主要介绍主机 MSC 使用。借助 FATFS 实现读写功能。</p>
|
||||
<ul class="simple">
|
||||
<li><p>在 msc 枚举完成的回调中注册一个线程,用于读写操作。</p></li>
|
||||
</ul>
|
||||
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span><span class="w"> </span><span class="nf">usbh_msc_run</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_msc</span><span class="w"> </span><span class="o">*</span><span class="n">msc_class</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">usb_osal_thread_create</span><span class="p">(</span><span class="s">"usbh_msc"</span><span class="p">,</span><span class="w"> </span><span class="mi">2048</span><span class="p">,</span><span class="w"> </span><span class="n">CONFIG_USBHOST_PSC_PRIO</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">usbh_msc_thread</span><span class="p">,</span><span class="w"> </span><span class="n">msc_class</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="kt">void</span><span class="w"> </span><span class="nf">usbh_msc_stop</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_msc</span><span class="w"> </span><span class="o">*</span><span class="n">msc_class</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>不使用 fatfs,则直接使用 usbh_msc_scsi_read10 或者 usbh_msc_scsi_write10 函数进行读写操作。</p></li>
|
||||
<li><p>如果使用 fatfs,则需要在 usbh_msc_thread 中调用 fatfs 的接口进行读写操作。msc读写适配fatfs 参考 <cite>platform/none/usbh_fatfs.c</cite></p></li>
|
||||
</ul>
|
||||
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">usbh_msc_thread</span><span class="p">(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">argument</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_msc</span><span class="w"> </span><span class="o">*</span><span class="n">msc_class</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_msc</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="n">argument</span><span class="p">;</span>
|
||||
|
||||
<span class="w"> </span><span class="cm">/* test with only one buffer, if you have more msc class, modify by yourself */</span>
|
||||
<span class="cp">#if 1</span>
|
||||
<span class="w"> </span><span class="cm">/* get the partition table */</span>
|
||||
<span class="w"> </span><span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">usbh_msc_scsi_read10</span><span class="p">(</span><span class="n">msc_class</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">partition_table</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ret</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">USB_LOG_RAW</span><span class="p">(</span><span class="s">"scsi_read10 error,ret:%d</span><span class="se">\r\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">ret</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="k">goto</span><span class="w"> </span><span class="n">delete</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">uint32_t</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="mi">512</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="mi">16</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">USB_LOG_RAW</span><span class="p">(</span><span class="s">"</span><span class="se">\r\n</span><span class="s">"</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="w"> </span><span class="n">USB_LOG_RAW</span><span class="p">(</span><span class="s">"%02x "</span><span class="p">,</span><span class="w"> </span><span class="n">partition_table</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="w"> </span><span class="n">USB_LOG_RAW</span><span class="p">(</span><span class="s">"</span><span class="se">\r\n</span><span class="s">"</span><span class="p">);</span>
|
||||
<span class="cp">#endif</span>
|
||||
|
||||
<span class="cp">#if TEST_USBH_MSC_FATFS</span>
|
||||
<span class="w"> </span><span class="n">usb_msc_fatfs_test</span><span class="p">();</span>
|
||||
<span class="cp">#endif</span>
|
||||
<span class="w"> </span><span class="c1">// clang-format off</span>
|
||||
<span class="nl">delete</span><span class="p">:</span>
|
||||
<span class="w"> </span><span class="n">usb_osal_thread_delete</span><span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="c1">// clang-format on</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>最后处理完成或者失败后,删除线程。</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
|
||||
|
@ -151,6 +151,102 @@
|
||||
|
||||
<section id="usbh-net">
|
||||
<h1>usbh_net<a class="headerlink" href="#usbh-net" title="Link to this heading"></a></h1>
|
||||
<p>本节主要介绍 USB 网卡的使用,USB 网卡推荐采用 AIR780(RNDIS),EC20(ECM/RNDIS), 手机(RNDIS),RTL8152 USB 网卡,AX88772 USB 网卡。</p>
|
||||
<p>USB 网卡传输层面已经对接好了 LWIP 的收发接口,因此,用户只需要包含 <strong>platform/XXX/usbh_lwip.c</strong> 并根据需要开启对应的网卡类的宏即可。</p>
|
||||
<ul class="simple">
|
||||
<li><p>当前支持以下网卡类:</p></li>
|
||||
</ul>
|
||||
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="c1">// #define CONFIG_USBHOST_PLATFORM_CDC_ECM</span>
|
||||
<span class="c1">// #define CONFIG_USBHOST_PLATFORM_CDC_RNDIS</span>
|
||||
<span class="c1">// #define CONFIG_USBHOST_PLATFORM_CDC_NCM</span>
|
||||
<span class="c1">// #define CONFIG_USBHOST_PLATFORM_ASIX</span>
|
||||
<span class="c1">// #define CONFIG_USBHOST_PLATFORM_RTL8152</span>
|
||||
<span class="c1">// #define CONFIG_USBHOST_PLATFORM_BL616</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>包含了对接 LWIP 的输入输出接口,举例如下</p></li>
|
||||
</ul>
|
||||
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="n">err_t</span><span class="w"> </span><span class="nf">usbh_cdc_ecm_linkoutput</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">netif</span><span class="w"> </span><span class="o">*</span><span class="n">netif</span><span class="p">,</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">pbuf</span><span class="w"> </span><span class="o">*</span><span class="n">p</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">netif</span><span class="p">;</span>
|
||||
|
||||
<span class="w"> </span><span class="n">usbh_lwip_eth_output_common</span><span class="p">(</span><span class="n">p</span><span class="p">,</span><span class="w"> </span><span class="n">usbh_cdc_ecm_get_eth_txbuf</span><span class="p">());</span>
|
||||
<span class="w"> </span><span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">usbh_cdc_ecm_eth_output</span><span class="p">(</span><span class="n">p</span><span class="o">-></span><span class="n">tot_len</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ret</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">ERR_BUF</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">ERR_OK</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="kt">void</span><span class="w"> </span><span class="nf">usbh_cdc_ecm_eth_input</span><span class="p">(</span><span class="kt">uint8_t</span><span class="w"> </span><span class="o">*</span><span class="n">buf</span><span class="p">,</span><span class="w"> </span><span class="kt">uint32_t</span><span class="w"> </span><span class="n">buflen</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">usbh_lwip_eth_input_common</span><span class="p">(</span><span class="o">&</span><span class="n">g_cdc_ecm_netif</span><span class="p">,</span><span class="w"> </span><span class="n">buf</span><span class="p">,</span><span class="w"> </span><span class="n">buflen</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>网卡类枚举完成后,注册 netif,并且创建网卡接收线程(因此使用 RTTHREAD 时不需要使用 RTT 的接收线程模块)。</p></li>
|
||||
<li><p>必须开启 DHCP client 服务,用于从 USB 网卡获取 IP 地址。</p></li>
|
||||
</ul>
|
||||
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span><span class="w"> </span><span class="nf">usbh_cdc_ecm_run</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_cdc_ecm</span><span class="w"> </span><span class="o">*</span><span class="n">cdc_ecm_class</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">netif</span><span class="w"> </span><span class="o">*</span><span class="n">netif</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&</span><span class="n">g_cdc_ecm_netif</span><span class="p">;</span>
|
||||
|
||||
<span class="w"> </span><span class="n">netif</span><span class="o">-></span><span class="n">hwaddr_len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">6</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="n">memcpy</span><span class="p">(</span><span class="n">netif</span><span class="o">-></span><span class="n">hwaddr</span><span class="p">,</span><span class="w"> </span><span class="n">cdc_ecm_class</span><span class="o">-></span><span class="n">mac</span><span class="p">,</span><span class="w"> </span><span class="mi">6</span><span class="p">);</span>
|
||||
|
||||
<span class="w"> </span><span class="n">IP4_ADDR</span><span class="p">(</span><span class="o">&</span><span class="n">g_ipaddr</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">IP4_ADDR</span><span class="p">(</span><span class="o">&</span><span class="n">g_netmask</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">IP4_ADDR</span><span class="p">(</span><span class="o">&</span><span class="n">g_gateway</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
|
||||
|
||||
<span class="w"> </span><span class="n">netif</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">netif_add</span><span class="p">(</span><span class="n">netif</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">g_ipaddr</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">g_netmask</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">g_gateway</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">,</span><span class="w"> </span><span class="n">usbh_cdc_ecm_if_init</span><span class="p">,</span><span class="w"> </span><span class="n">tcpip_input</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">netif_set_default</span><span class="p">(</span><span class="n">netif</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">netif_is_up</span><span class="p">(</span><span class="n">netif</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
|
||||
<span class="w"> </span><span class="n">dhcp_handle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">usb_osal_timer_create</span><span class="p">(</span><span class="s">"dhcp"</span><span class="p">,</span><span class="w"> </span><span class="mi">200</span><span class="p">,</span><span class="w"> </span><span class="n">dhcp_timeout</span><span class="p">,</span><span class="w"> </span><span class="n">netif</span><span class="p">,</span><span class="w"> </span><span class="nb">true</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">dhcp_handle</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">USB_LOG_ERR</span><span class="p">(</span><span class="s">"timer creation failed! </span><span class="se">\r\n</span><span class="s">"</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
|
||||
<span class="w"> </span><span class="n">usb_osal_thread_create</span><span class="p">(</span><span class="s">"usbh_cdc_ecm_rx"</span><span class="p">,</span><span class="w"> </span><span class="mi">2048</span><span class="p">,</span><span class="w"> </span><span class="n">CONFIG_USBHOST_PSC_PRIO</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">usbh_cdc_ecm_rx_thread</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">);</span>
|
||||
<span class="cp">#if LWIP_DHCP</span>
|
||||
<span class="w"> </span><span class="n">dhcp_start</span><span class="p">(</span><span class="n">netif</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">usb_osal_timer_start</span><span class="p">(</span><span class="n">dhcp_handle</span><span class="p">);</span>
|
||||
<span class="cp">#endif</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<ul class="simple">
|
||||
<li><p>获取到 IP 以后,就与 USB 没有关系了,直接使用 LWIP 的接口即可。</p></li>
|
||||
<li><p>需要注意以下参数</p></li>
|
||||
</ul>
|
||||
<p>LWIP_TCPIP_CORE_LOCKING_INPUT 用于不使用 lwip 内置的 tcpip 线程,而使用 USB 自己的处理线程。</p>
|
||||
<p>LWIP_TCPIP_CORE_LOCKING 在现在 lwip 版本中默认是打开的,也推荐必须打开。</p>
|
||||
<p>PBUF_POOL_BUFSIZE 推荐大于1600,搭配 LWIP_TCPIP_CORE_LOCKING_INPUT 使用,因为我们提供了使用 zero mempy 的方式,使用静态 pbuf,而不是把数据 copy 到 pbuf 中。</p>
|
||||
<p>TCPIP_THREAD_STACKSIZE 推荐大于 1K,防止栈溢出。</p>
|
||||
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="cp">#if LWIP_TCPIP_CORE_LOCKING_INPUT != 1</span>
|
||||
<span class="cp">#warning suggest you to set LWIP_TCPIP_CORE_LOCKING_INPUT to 1, usb handles eth input with own thread</span>
|
||||
<span class="cp">#endif</span>
|
||||
|
||||
<span class="cp">#if LWIP_TCPIP_CORE_LOCKING != 1</span>
|
||||
<span class="cp">#error must set LWIP_TCPIP_CORE_LOCKING to 1</span>
|
||||
<span class="cp">#endif</span>
|
||||
|
||||
<span class="cp">#if PBUF_POOL_BUFSIZE < 1600</span>
|
||||
<span class="cp">#error PBUF_POOL_BUFSIZE must be larger than 1600</span>
|
||||
<span class="cp">#endif</span>
|
||||
|
||||
<span class="cp">#if TCPIP_THREAD_STACKSIZE < 1024</span>
|
||||
<span class="cp">#error TCPIP_THREAD_STACKSIZE must be >= 1024</span>
|
||||
<span class="cp">#endif</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user