Deploying to gh-pages from @ cherry-embedded/CherryUSB@e2a3356945 🚀

This commit is contained in:
sakumisu
2025-12-12 14:36:13 +00:00
parent 41a9842018
commit 78f6414b52
5 changed files with 395 additions and 11 deletions

View File

@@ -154,14 +154,115 @@ lsusb
int lsusb(int argc, char **argv);
CDC ACM
SERIAL
-----------------
usbh_serial_open
""""""""""""""""""""""""""""""""""""
``usbh_serial_open`` 根据路径打开一个串口设备。
.. code-block:: C
struct usbh_serial *usbh_serial_open(const char *devname, uint32_t open_flags);
- **devname** 串口路径
- **open_flags** 打开标志,参考 `USBH_SERIAL_OFLAG_*` 定义
- **return** serial 结构体句柄
usbh_serial_close
""""""""""""""""""""""""""""""""""""
``usbh_serial_close`` 关闭串口设备。
.. code-block:: C
void usbh_serial_close(struct usbh_serial *serial);
- **serial** serial 结构体句柄
usbh_serial_control
""""""""""""""""""""""""""""""""""""
``usbh_serial_control`` 对串口进行配置。
.. code-block:: C
int usbh_serial_control(struct usbh_serial *serial, int cmd, void *arg);
- **serial** serial 结构体句柄
- **cmd** 控制命令,参考 `USBH_SERIAL_CMD_*` 定义
- **arg** 控制参数指针
- **return** 0 表示正常其他表示错误
usbh_serial_write
""""""""""""""""""""""""""""""""""""
``usbh_serial_write`` 向串口写数据。 **串口设备如果是 USB2TTL 类型,必须按照波特率发送,否则会丢包**
.. code-block:: C
int usbh_serial_write(struct usbh_serial *serial, const void *buffer, uint32_t buflen);
- **serial** serial 结构体句柄
- **buffer** 数据缓冲区指针
- **buflen** 要写入的数据长度,如果是 USB2TTL 设备,一次最高 wMaxPacketSize
- **return** 实际写入的数据长度或者错误码
.. note:: 有无设置波特率都可以使用该 API当未设置波特率时长度无限制如果设置了波特率则为 wMaxPacketSize。
usbh_serial_read
""""""""""""""""""""""""""""""""""""
``usbh_serial_read`` 从串口读数据。 **如果没有设置波特率,不允许使用该 API**。
.. code-block:: C
int usbh_serial_read(struct usbh_serial *serial, void *buffer, uint32_t buflen);
- **serial** serial 结构体句柄
- **buffer** 数据缓冲区指针
- **buflen** 要读取的最大数据长度
- **return** 实际读取的数据长度或者错误码
usbh_serial_cdc_write_async
""""""""""""""""""""""""""""""""""""
``usbh_serial_cdc_write_async`` 异步从串口读数据。 **如果设置了波特率,不允许使用该 API**。
.. code-block:: C
int usbh_serial_cdc_write_async(struct usbh_serial *serial, uint8_t *buffer, uint32_t buflen, usbh_complete_callback_t complete, void *arg);
- **serial** serial 结构体句柄
- **buffer** 数据缓冲区指针
- **buflen** 要发送的数据长度
- **complete** 读数据完成回调函数
- **arg** 回调函数参数
- **return** 0 表示正常其他表示错误
usbh_serial_cdc_read_async
""""""""""""""""""""""""""""""""""""
``usbh_serial_cdc_read_async`` 异步从串口读数据。 **如果设置了波特率,不允许使用该 API**。
.. code-block:: C
int usbh_serial_cdc_read_async(struct usbh_serial *serial, uint8_t *buffer, uint32_t buflen, usbh_complete_callback_t complete, void *arg);
- **serial** serial 结构体句柄
- **buffer** 数据缓冲区指针
- **buflen** 要读取的最大数据长度,一次最高 16K。并且需要是 wMaxPacketSize 的整数倍
- **complete** 读数据完成回调函数
- **arg** 回调函数参数
- **return** 0 表示正常其他表示错误
HID
-----------------
MSC
-----------------
RNDIS
NETWORK
-----------------

View File

@@ -1,4 +1,96 @@
usbh_serial
===============
当前仅支持 rt-thread device 框架,包括 cdc acm, ftdi, cp210x, ch34x, pl2303, 具体使用方式参考 rt-thread device api 即可。
Serial 框架当前支持 cdc acm, ftdi, cp210x, ch34x, pl2303gsm 驱动。当前支持两种使用方式,
一种是使用源生 CherryUSB usbhost serial API 进行操作,另一种是基于平台封装的 API 操作,比如 rt-thread device API。nuttx posix API。
下面演示的是使用 CherryUSB usbhost serial API 进行串口回环测试,并且使用阻塞发送,异步读取的方式:
.. code-block:: C
struct usbh_serial *serial;
serial = usbh_serial_open("/dev/ttyACM0", USBH_SERIAL_O_RDWR | USBH_SERIAL_O_NONBLOCK);
if (serial == NULL) {
serial = usbh_serial_open("/dev/ttyUSB0", USBH_SERIAL_O_RDWR | USBH_SERIAL_O_NONBLOCK);
if (serial == NULL) {
USB_LOG_RAW("no serial device found\r\n");
goto delete;
}
}
struct usbh_serial_termios termios;
memset(&termios, 0, sizeof(termios));
termios.baudrate = 115200;
termios.stopbits = 0;
termios.parity = 0;
termios.databits = 8;
termios.rtscts = false;
termios.rx_timeout = 0;
ret = usbh_serial_control(serial, USBH_SERIAL_CMD_SET_ATTR, &termios);
if (ret < 0) {
USB_LOG_RAW("set serial attr error, ret:%d\r\n", ret);
goto delete_with_close;
}
serial_tx_bytes = 0;
while (1) {
/* for common, we use timeout with 0xffffffff, this is just a test */
ret = usbh_serial_write(serial, serial_tx_buffer, sizeof(serial_tx_buffer));
if (ret < 0) {
USB_LOG_RAW("serial write error, ret:%d\r\n", ret);
goto delete_with_close;
} else {
serial_tx_bytes += ret;
usb_osal_msleep(10); // 11.52 Byte/ms at 115200bps --> 64Byte/5.5ms
if (serial_tx_bytes == SERIAL_TEST_LEN) {
USB_LOG_RAW("send over\r\n");
break;
}
}
}
volatile uint32_t wait_timeout = 0;
serial_rx_bytes = 0;
while (1) {
ret = usbh_serial_read(serial, &serial_rx_data[serial_rx_bytes], SERIAL_TEST_LEN);
if (ret < 0) {
USB_LOG_RAW("serial read error, ret:%d\r\n", ret);
goto delete_with_close;
} else {
serial_rx_bytes += ret;
if (serial_rx_bytes == SERIAL_TEST_LEN) {
USB_LOG_RAW("receive over\r\n");
for (uint32_t i = 0; i < SERIAL_TEST_LEN; i++) {
if (serial_rx_data[i] != 0xa5) {
USB_LOG_RAW("serial loopback data error at index %d, data: 0x%02x\r\n", (unsigned int)i, serial_rx_data[i]);
goto delete_with_close;
}
}
USB_LOG_RAW("serial loopback test success\r\n");
break;
}
}
wait_timeout++;
if (wait_timeout > 500) { // 5s
USB_LOG_RAW("serial read timeout\r\n");
goto delete_with_close;
}
usb_osal_msleep(10);
}
usbh_serial_close(serial);
用户需要考虑以下三种场景:
- USB2TTL 设备 + 启用了波特率,这种情况下需要使用 `usbh_serial_write` 和 `usbh_serial_read` 进行收发数据, **并且需要根据波特率控制发送频率,防止对端丢包**
- 纯 USB 设备 + 未启动波特率,这种情况下可以使用 `usbh_serial_cdc_write_async` 和 `usbh_serial_cdc_read_async` 进行异步收发数据,阻塞则用 `usbh_serial_write` 并且不需要控制发送频率。不可以使用 `usbh_serial_read`。
- 纯 USB 设备 + 启动波特率,同 1但是速率打折扣。不可以使用 `usbh_serial_cdc_write_async` 和 `usbh_serial_cdc_read_async`。如果是 GSM 设备需要使用第一种。

View File

@@ -78,10 +78,19 @@
<li class="toctree-l3"><a class="reference internal" href="#lsusb">lsusb</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#cdc-acm">CDC ACM</a></li>
<li class="toctree-l2"><a class="reference internal" href="#serial">SERIAL</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#usbh-serial-open">usbh_serial_open</a></li>
<li class="toctree-l3"><a class="reference internal" href="#usbh-serial-close">usbh_serial_close</a></li>
<li class="toctree-l3"><a class="reference internal" href="#usbh-serial-control">usbh_serial_control</a></li>
<li class="toctree-l3"><a class="reference internal" href="#usbh-serial-write">usbh_serial_write</a></li>
<li class="toctree-l3"><a class="reference internal" href="#usbh-serial-read">usbh_serial_read</a></li>
<li class="toctree-l3"><a class="reference internal" href="#usbh-serial-cdc-write-async">usbh_serial_cdc_write_async</a></li>
<li class="toctree-l3"><a class="reference internal" href="#usbh-serial-cdc-read-async">usbh_serial_cdc_read_async</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#hid">HID</a></li>
<li class="toctree-l2"><a class="reference internal" href="#msc">MSC</a></li>
<li class="toctree-l2"><a class="reference internal" href="#rndis">RNDIS</a></li>
<li class="toctree-l2"><a class="reference internal" href="#network">NETWORK</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="api_port.html">主从驱动</a></li>
@@ -322,8 +331,103 @@
</div>
</section>
</section>
<section id="cdc-acm">
<h2>CDC ACM<a class="headerlink" href="#cdc-acm" title="Link to this heading"></a></h2>
<section id="serial">
<h2>SERIAL<a class="headerlink" href="#serial" title="Link to this heading"></a></h2>
<section id="usbh-serial-open">
<h3>usbh_serial_open<a class="headerlink" href="#usbh-serial-open" title="Link to this heading"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">usbh_serial_open</span></code> 根据路径打开一个串口设备。</p>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_serial</span><span class="w"> </span><span class="o">*</span><span class="n">usbh_serial_open</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">devname</span><span class="p">,</span><span class="w"> </span><span class="kt">uint32_t</span><span class="w"> </span><span class="n">open_flags</span><span class="p">);</span>
</pre></div>
</div>
<ul class="simple">
<li><p><strong>devname</strong> 串口路径</p></li>
<li><p><strong>open_flags</strong> 打开标志,参考 <cite>USBH_SERIAL_OFLAG_*</cite> 定义</p></li>
<li><p><strong>return</strong> serial 结构体句柄</p></li>
</ul>
</section>
<section id="usbh-serial-close">
<h3>usbh_serial_close<a class="headerlink" href="#usbh-serial-close" title="Link to this heading"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">usbh_serial_close</span></code> 关闭串口设备。</p>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span><span class="w"> </span><span class="nf">usbh_serial_close</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_serial</span><span class="w"> </span><span class="o">*</span><span class="n">serial</span><span class="p">);</span>
</pre></div>
</div>
<ul class="simple">
<li><p><strong>serial</strong> serial 结构体句柄</p></li>
</ul>
</section>
<section id="usbh-serial-control">
<h3>usbh_serial_control<a class="headerlink" href="#usbh-serial-control" title="Link to this heading"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">usbh_serial_control</span></code> 对串口进行配置。</p>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span><span class="w"> </span><span class="nf">usbh_serial_control</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_serial</span><span class="w"> </span><span class="o">*</span><span class="n">serial</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">cmd</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">arg</span><span class="p">);</span>
</pre></div>
</div>
<ul class="simple">
<li><p><strong>serial</strong> serial 结构体句柄</p></li>
<li><p><strong>cmd</strong> 控制命令,参考 <cite>USBH_SERIAL_CMD_*</cite> 定义</p></li>
<li><p><strong>arg</strong> 控制参数指针</p></li>
<li><p><strong>return</strong> 0 表示正常其他表示错误</p></li>
</ul>
</section>
<section id="usbh-serial-write">
<h3>usbh_serial_write<a class="headerlink" href="#usbh-serial-write" title="Link to this heading"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">usbh_serial_write</span></code> 向串口写数据。 <strong>串口设备如果是 USB2TTL 类型,必须按照波特率发送,否则会丢包</strong></p>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span><span class="w"> </span><span class="nf">usbh_serial_write</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_serial</span><span class="w"> </span><span class="o">*</span><span class="n">serial</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">buffer</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>
</pre></div>
</div>
<ul class="simple">
<li><p><strong>serial</strong> serial 结构体句柄</p></li>
<li><p><strong>buffer</strong> 数据缓冲区指针</p></li>
<li><p><strong>buflen</strong> 要写入的数据长度,如果是 USB2TTL 设备,一次最高 wMaxPacketSize</p></li>
<li><p><strong>return</strong> 实际写入的数据长度或者错误码</p></li>
</ul>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>有无设置波特率都可以使用该 API当未设置波特率时长度无限制如果设置了波特率则为 wMaxPacketSize。</p>
</div>
</section>
<section id="usbh-serial-read">
<h3>usbh_serial_read<a class="headerlink" href="#usbh-serial-read" title="Link to this heading"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">usbh_serial_read</span></code> 从串口读数据。 <strong>如果没有设置波特率,不允许使用该 API</strong></p>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span><span class="w"> </span><span class="nf">usbh_serial_read</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_serial</span><span class="w"> </span><span class="o">*</span><span class="n">serial</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">buffer</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>
</pre></div>
</div>
<ul class="simple">
<li><p><strong>serial</strong> serial 结构体句柄</p></li>
<li><p><strong>buffer</strong> 数据缓冲区指针</p></li>
<li><p><strong>buflen</strong> 要读取的最大数据长度</p></li>
<li><p><strong>return</strong> 实际读取的数据长度或者错误码</p></li>
</ul>
</section>
<section id="usbh-serial-cdc-write-async">
<h3>usbh_serial_cdc_write_async<a class="headerlink" href="#usbh-serial-cdc-write-async" title="Link to this heading"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">usbh_serial_cdc_write_async</span></code> 异步从串口读数据。 <strong>如果设置了波特率,不允许使用该 API</strong></p>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span><span class="w"> </span><span class="nf">usbh_serial_cdc_write_async</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_serial</span><span class="w"> </span><span class="o">*</span><span class="n">serial</span><span class="p">,</span><span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="o">*</span><span class="n">buffer</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="w"> </span><span class="n">usbh_complete_callback_t</span><span class="w"> </span><span class="n">complete</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">arg</span><span class="p">);</span>
</pre></div>
</div>
<ul class="simple">
<li><p><strong>serial</strong> serial 结构体句柄</p></li>
<li><p><strong>buffer</strong> 数据缓冲区指针</p></li>
<li><p><strong>buflen</strong> 要发送的数据长度</p></li>
<li><p><strong>complete</strong> 读数据完成回调函数</p></li>
<li><p><strong>arg</strong> 回调函数参数</p></li>
<li><p><strong>return</strong> 0 表示正常其他表示错误</p></li>
</ul>
</section>
<section id="usbh-serial-cdc-read-async">
<h3>usbh_serial_cdc_read_async<a class="headerlink" href="#usbh-serial-cdc-read-async" title="Link to this heading"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">usbh_serial_cdc_read_async</span></code> 异步从串口读数据。 <strong>如果设置了波特率,不允许使用该 API</strong></p>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span><span class="w"> </span><span class="nf">usbh_serial_cdc_read_async</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_serial</span><span class="w"> </span><span class="o">*</span><span class="n">serial</span><span class="p">,</span><span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="o">*</span><span class="n">buffer</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="w"> </span><span class="n">usbh_complete_callback_t</span><span class="w"> </span><span class="n">complete</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">arg</span><span class="p">);</span>
</pre></div>
</div>
<ul class="simple">
<li><p><strong>serial</strong> serial 结构体句柄</p></li>
<li><p><strong>buffer</strong> 数据缓冲区指针</p></li>
<li><p><strong>buflen</strong> 要读取的最大数据长度,一次最高 16K。并且需要是 wMaxPacketSize 的整数倍</p></li>
<li><p><strong>complete</strong> 读数据完成回调函数</p></li>
<li><p><strong>arg</strong> 回调函数参数</p></li>
<li><p><strong>return</strong> 0 表示正常其他表示错误</p></li>
</ul>
</section>
</section>
<section id="hid">
<h2>HID<a class="headerlink" href="#hid" title="Link to this heading"></a></h2>
@@ -331,8 +435,8 @@
<section id="msc">
<h2>MSC<a class="headerlink" href="#msc" title="Link to this heading"></a></h2>
</section>
<section id="rndis">
<h2>RNDIS<a class="headerlink" href="#rndis" title="Link to this heading"></a></h2>
<section id="network">
<h2>NETWORK<a class="headerlink" href="#network" title="Link to this heading"></a></h2>
</section>
</section>

View File

@@ -159,7 +159,94 @@
<section id="usbh-serial">
<h1>usbh_serial<a class="headerlink" href="#usbh-serial" title="Link to this heading"></a></h1>
<p>当前仅支持 rt-thread device 框架,包括 cdc acm, ftdi, cp210x, ch34x, pl2303, 具体使用方式参考 rt-thread device api 即可。</p>
<p>Serial 框架当前支持 cdc acm, ftdi, cp210x, ch34x, pl2303gsm 驱动。当前支持两种使用方式,
一种是使用源生 CherryUSB usbhost serial API 进行操作,另一种是基于平台封装的 API 操作,比如 rt-thread device API。nuttx posix API。</p>
<p>下面演示的是使用 CherryUSB usbhost serial API 进行串口回环测试,并且使用阻塞发送,异步读取的方式:</p>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span><span class="w"> </span><span class="nc">usbh_serial</span><span class="w"> </span><span class="o">*</span><span class="n">serial</span><span class="p">;</span>
<span class="n">serial</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">usbh_serial_open</span><span class="p">(</span><span class="s">&quot;/dev/ttyACM0&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">USBH_SERIAL_O_RDWR</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">USBH_SERIAL_O_NONBLOCK</span><span class="p">);</span>
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">serial</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">serial</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">usbh_serial_open</span><span class="p">(</span><span class="s">&quot;/dev/ttyUSB0&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">USBH_SERIAL_O_RDWR</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">USBH_SERIAL_O_NONBLOCK</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">serial</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_RAW</span><span class="p">(</span><span class="s">&quot;no serial device found</span><span class="se">\r\n</span><span class="s">&quot;</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="p">}</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">usbh_serial_termios</span><span class="w"> </span><span class="n">termios</span><span class="p">;</span>
<span class="n">memset</span><span class="p">(</span><span class="o">&amp;</span><span class="n">termios</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="n">termios</span><span class="p">));</span>
<span class="n">termios</span><span class="p">.</span><span class="n">baudrate</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">115200</span><span class="p">;</span>
<span class="n">termios</span><span class="p">.</span><span class="n">stopbits</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="n">termios</span><span class="p">.</span><span class="n">parity</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="n">termios</span><span class="p">.</span><span class="n">databits</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">8</span><span class="p">;</span>
<span class="n">termios</span><span class="p">.</span><span class="n">rtscts</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">false</span><span class="p">;</span>
<span class="n">termios</span><span class="p">.</span><span class="n">rx_timeout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">usbh_serial_control</span><span class="p">(</span><span class="n">serial</span><span class="p">,</span><span class="w"> </span><span class="n">USBH_SERIAL_CMD_SET_ATTR</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">termios</span><span class="p">);</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">&lt;</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">&quot;set serial attr error, ret:%d</span><span class="se">\r\n</span><span class="s">&quot;</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_with_close</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">serial_tx_bytes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</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="cm">/* for common, we use timeout with 0xffffffff, this is just a test */</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_serial_write</span><span class="p">(</span><span class="n">serial</span><span class="p">,</span><span class="w"> </span><span class="n">serial_tx_buffer</span><span class="p">,</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="n">serial_tx_buffer</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">&lt;</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">&quot;serial write error, ret:%d</span><span class="se">\r\n</span><span class="s">&quot;</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_with_close</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="n">serial_tx_bytes</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">ret</span><span class="p">;</span>
<span class="w"> </span><span class="n">usb_osal_msleep</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span><span class="w"> </span><span class="c1">// 11.52 Byte/ms at 115200bps --&gt; 64Byte/5.5ms</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">serial_tx_bytes</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">SERIAL_TEST_LEN</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">&quot;send over</span><span class="se">\r\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
<span class="k">volatile</span><span class="w"> </span><span class="kt">uint32_t</span><span class="w"> </span><span class="n">wait_timeout</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="n">serial_rx_bytes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</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="n">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">usbh_serial_read</span><span class="p">(</span><span class="n">serial</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">serial_rx_data</span><span class="p">[</span><span class="n">serial_rx_bytes</span><span class="p">],</span><span class="w"> </span><span class="n">SERIAL_TEST_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">&lt;</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">&quot;serial read error, ret:%d</span><span class="se">\r\n</span><span class="s">&quot;</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_with_close</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="n">serial_rx_bytes</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">ret</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">serial_rx_bytes</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">SERIAL_TEST_LEN</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">&quot;receive over</span><span class="se">\r\n</span><span class="s">&quot;</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">&lt;</span><span class="w"> </span><span class="n">SERIAL_TEST_LEN</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">serial_rx_data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mh">0xa5</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">&quot;serial loopback data error at index %d, data: 0x%02x</span><span class="se">\r\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">serial_rx_data</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="w"> </span><span class="k">goto</span><span class="w"> </span><span class="n">delete_with_close</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_LOG_RAW</span><span class="p">(</span><span class="s">&quot;serial loopback test success</span><span class="se">\r\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="w"> </span><span class="k">break</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">wait_timeout</span><span class="o">++</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">wait_timeout</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">500</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// 5s</span>
<span class="w"> </span><span class="n">USB_LOG_RAW</span><span class="p">(</span><span class="s">&quot;serial read timeout</span><span class="se">\r\n</span><span class="s">&quot;</span><span class="p">);</span>
<span class="w"> </span><span class="k">goto</span><span class="w"> </span><span class="n">delete_with_close</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">usb_osal_msleep</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">usbh_serial_close</span><span class="p">(</span><span class="n">serial</span><span class="p">);</span>
</pre></div>
</div>
<p>用户需要考虑以下三种场景:</p>
<ul class="simple">
<li><p>USB2TTL 设备 + 启用了波特率,这种情况下需要使用 <cite>usbh_serial_write</cite><cite>usbh_serial_read</cite> 进行收发数据, <strong>并且需要根据波特率控制发送频率,防止对端丢包</strong></p></li>
<li><p>纯 USB 设备 + 未启动波特率,这种情况下可以使用 <cite>usbh_serial_cdc_write_async</cite><cite>usbh_serial_cdc_read_async</cite> 进行异步收发数据,阻塞则用 <cite>usbh_serial_write</cite> 并且不需要控制发送频率。不可以使用 <cite>usbh_serial_read</cite></p></li>
<li><p>纯 USB 设备 + 启动波特率,同 1但是速率打折扣。不可以使用 <cite>usbh_serial_cdc_write_async</cite><cite>usbh_serial_cdc_read_async</cite>。如果是 GSM 设备需要使用第一种。</p></li>
</ul>
</section>

File diff suppressed because one or more lines are too long