某设备需要提供多路USB串口的功能给主机端使用,比如一路用作业务1通信功能,一路用作业务2通信功能,一路用作debug抓log用途,诸如此类。如下图所示。

要实现上述设备功能,可以参考如下步骤。

1)首先,了解一下背景知识。Linux kernel为设备端USB驱动提供了名为USB Gadget的驱动框架,设备端要基于Linux系统实现USB device功能,都需要基于Gadget框架。各种USB class定义的功能,在设备端的实现,称之为USB function。常见的USB function,比如 serial, ecm, storage, video, audio等,kernel原生代码都已经实现了。产品开发的大部分工作是放在理解并使用这些代码,并调试可能出现的bug;以及针对某些usb controller的特性,需要在function driver层面处理的时候,打一些补丁,当然这种补丁是很难合入kernel社区的,只能是在自家的产品上用用。

2)其次,了解一下gadget驱动代码目录结构。如下图所示。

gadget驱动包含三大部分:

  • function驱动 —— 实现各种usb class功能

  • udc驱动 —— 实现usb controller driver

  • 辅助驱动 —— configfs.c实现用户空间配置usb, composite.c实现复合设备

进入function目录,可以看到各种已经实现的function,接下来我们要用到的serial function也在其中。

3)了解具体如何开启usb串口的功能。其实很简单,要开启usb serial function driver,在kernel config中开启以下CONFIG即可:

CONFIG_USB_GADGET=y

CONFIG_USB_U_SERIAL=y

CONFIG_USB_F_SERIAL=y

开启以上CONFIG后,只是打开了usb driver支持serial的能力;要生成多路串口,还需要通过configfs动态配置相关功能,以下就是生成三路USB generic serial串口的示例:

mkdir -p /sys/kernel/config/usb_gadget/g1/functions/gser.gs0
chmod 755 /sys/kernel/config/usb_gadget/g1/functions/gser.gs0
mkdir -p /sys/kernel/config/usb_gadget/g1/functions/gser.gs1
chmod 755 /sys/kernel/config/usb_gadget/g1/functions/gser.gs1
mkdir -p /sys/kernel/config/usb_gadget/g1/functions/gser.gs2
chmod 755 /sys/kernel/config/usb_gadget/g1/functions/gser.gs2


ln -s /sys/kernel/config/usb_gadget/g1/functions/gser.gs2 /sys/kernel/config/usb_gadget/g1/configs/b.1/f1
ln -s /sys/kernel/config/usb_gadget/g1/functions/gser.gs0 /sys/kernel/config/usb_gadget/g1/configs/b.1/f2
ln -s /sys/kernel/config/usb_gadget/g1/functions/gser.gs1 /sys/kernel/config/usb_gadget/g1/configs/b.1/f3

  

configfs本身的介绍,可参考kernel文档:

Documentation\filesystems\configfs\configfs.txt

USB gadget configfs的使用介绍,可以参考kernel文档:

Documentation\ABI\testing\configfs-usb-gadget

Documentation\ABI\testing\configfs-usb-gadget-serial

三路USB串口启用成功后,在设备端会生成三个ttyGS设备:

  • /dev/ttyGS0

  • /dev/ttyGS1

  • /dev/ttyGS2

4)主机端看到的情况

主机端识别USB串口和加载相关驱动的方法,可以参考我的另一篇文章

加载usbserial驱动后,为什么adb不可用了

这里主要讲一讲主机端生成了多个名为ttyUSBx(x=0~n)的设备,我们如何确定它们与设备端多路USB串口(ttyGSx)的对应关系?

方法之一,当然可以通过遍历测试串口通信的方式来找到对应关系。比如主机端用串口工具或者echo指令发送数据,设备端用串口工具或者cat指令接收数据,一个一个遍历尝试,能正常通信的,就说明两边是对应的。

方法之二,通过主机端和设备端的USB interface number (接口号)找到对应关系。以Ubuntu主机为例:

在Ubuntu端执行 ls -l /sys/class/tty/ttyUSB*,可以看到ttyUSBx和USB接口号的对应关系。比如ttyUSB1对应3-6:1.2,这个末尾的数字2就表示接口2(简称f2)。

user@PC1002:~$ ls -l /sys/class/tty/ttyUSB*
lrwxrwxrwx 1 root root 0 5月 21 13:15 /sys/class/tty/ttyUSB0 -> ../../devices/pci0000:00/0000:00:14.0/usb3/3-6/3-6:1.1/ttyUSB0/tty/ttyUSB0
lrwxrwxrwx 1 root root 0 5月 21 13:15 /sys/class/tty/ttyUSB1 -> ../../devices/pci0000:00/0000:00:14.0/usb3/3-6/3-6:1.2/ttyUSB1/tty/ttyUSB1
lrwxrwxrwx 1 root root 0 5月 21 13:15 /sys/class/tty/ttyUSB2 -> ../../devices/pci0000:00/0000:00:14.0/usb3/3-6/3-6:1.3/ttyUSB2/tty/ttyUSB2

 

类似的,在设备端也可以获得ttyGSx与接口号的对应关系。进入设备端shell,执行如下指令。

ls -l /sys/kernel/config/usb_gadget/g1/configs/b.1/
-rw-r--r-- 1 root root 4096 May 4 10:40 MaxPower
-rw-r--r-- 1 root root 4096 May 4 10:40 bmAttributes
lrwxrwxrwx 1 root root 0 May 4 10:40 f1 -> ../../../../usb_gadget/g1/functions/gser.gs2
lrwxrwxrwx 1 root root 0 May 4 10:40 f2 -> ../../../../usb_gadget/g1/functions/gser.gs0
lrwxrwxrwx 1 root root 0 May 4 10:40 f3 -> ../../../../usb_gadget/g1/functions/gser.gs1

  

可以看到f2对应gser.gs0,表示gser.gs0对应接口2。那么gser.gs0是不是一定就与ttyGS0对应呢?先说答案,不一定。准确的做法是读取gser.gs0目录下的port_num的值来获知是ttyGS几。比如port_num是0,那就说明gser.gs0对应/dev/ttyGS0,如果port_num是1,那就说明gser.gs0对应/dev/ttyGS1。

cat /sys/kernel/config/usb_gadget/g1/functions/gser.gs0/port_num
0

  

这里假定gser.gs0对应/dev/ttyGS0,那么到此就可以得知主机和设备的对应关系:ttyUSB1对应ttyGS0。如果设备端的业务2代码是通过读写/dev/ttyGS0来实现通信,那么主机端的业务2代码就需要通过读写/dev/ttyUSB1来实现和设备端业务2的交互。

至于port_num编号的背后规律,与每个gser.gsN这个末尾数字N无关;与我们前面编写configfs配置USB的指令时,mkdir指令执行的次序有关,port_num从0开始,依次+1。从我们前面的编写的指令看,先mkdir gser.gs0,再mkdir gser.gs1,那么gser.gs0的port_num是0,gser.gs1的port_num就是1。如果先mkdir gser.gs1,再mkdir gser.gs0,那么就会反过来,gser.gs1的port_num是0,gser.gs0的port_num是1。

5)USB gadget serial function的驱动实现细节,不是本文的重点,暂且不讲,后续会专门介绍USB gadget function driver。

以上是本文全部内容,谢谢阅读,希望能帮到你。

文章会在公众号“大鱼嵌入式”同步发布,欢迎关注,一起交流。

Linux单设备多路USB串口的实现方法介绍的更多相关文章

  1. android设备使用usb串口传输数据

    首先介绍两个开源项目一个是Google的开源项目:https://code.google.com/archive/p/android-serialport-api/ 另一个是我们这次介绍的开源项目:h ...

  2. linux下USB串口,minicom

    [一].驱动相关说明: 如果直接使用串口线,而没有用到USB转串口设备,就不需要安装驱动. 如果使用了USB转串口,一般情况下也不需要安装驱动了,目前linux系统已经包含了该驱动,可以自动识别,亦可 ...

  3. linux下如何使用USB存储设备

    如何在Linux环境中使用USB接口的 存储 设备?这是各大电脑论坛上出现得比较多的一个问题,同此可见这也是摆在许多电脑玩家面前的一道难题. 本文就为您提供一套完美的解决方案,通过下面的方法,您仅可以 ...

  4. STM32组合设备实现USB转双串口

    USB转双串口,核心技术就在于组合设备(USB Composite)的实现,组合设备的实现,其核心技术在于描述符的实现,下面我们先给出描述符:设备描述符 [C] 纯文本查看 复制代码 ? 00001 ...

  5. (转载)linux中设备文件配置程序udev详解

    如果你使用Linux比较长时间了,那你就知道,在对待设备文件这块,Linux改变了几次策略.在Linux早期,设备文件仅仅是是一些带有适当的属性集的普通文件,它由mknod命令创建,文件存放在/dev ...

  6. ubuntu下minicom和usb串口转接

    ubuntu下minicom和USB转串口(转) (2013-03-23 21:07:54) 转载▼ 标签: it 分类: 嵌入式linux minicom是linux下串口通信的软件,它的使用完全依 ...

  7. (57)Linux驱动开发之三Linux字符设备驱动

    1.一般情况下,对每一种设备驱动都会定义一个软件模块,这个工程模块包含.h和.c文件,前者定义该设备驱动的数据结构并声明外部函数,后者进行设备驱动的具体实现. 2.典型的无操作系统下的逻辑开发程序是: ...

  8. Linux字符设备驱动框架

    字符设备是Linux三大设备之一(另外两种是块设备,网络设备),字符设备就是字节流形式通讯的I/O设备,绝大部分设备都是字符设备,常见的字符设备包括鼠标.键盘.显示器.串口等等,当我们执行ls -l ...

  9. linux内核打印数据到串口控制台,printk数据不打印问题

    linux内核打印数据到串口控制台问题 原文来源:http://i.cnblogs.com/EditPosts.aspx?opt=1 1.查看当前控制台的打印级别 cat /proc/sys/kern ...

随机推荐

  1. SDK音频测试流程

    概述 在上篇文章中,给小伙伴们讲述了sdk模板在渲染中的流程,我们简单来回顾一下,主要讲述了数据创建.素材替换.音频.文字等四部分,在上次讲述中也因为时间于原因没有特别仔细的去讲述他们.上次我们说到最 ...

  2. 谈谈对IOC及DI的理解与思考

    一.前言 在实际的开发过程中,我们经常会遇到这样的情况,在进行调试分析问题的时候,经常需要记录日志信息,这时可以采用输出到控制台. 因此,我们通常会定义一个日志类,来实现输出日志. 定义一个生成验证的 ...

  3. 【SqlServer】管理全文索引(FULL TEXT INDEX)

    Sql Server中的全文索引(下面统一使用FULLTEXT INDEX来表示全文索引),是一种特定语言搜索索引功能.它和LIKE的不一样,LIKE主要是根据搜索模板搜索数据,它的效率比FULLTE ...

  4. Gateway的限流重试机制详解

    前言 想要源码地址的可以加上此微信:Lemon877164954  前面给大家介绍了Spring Cloud Gateway的入门教程,这篇给大家探讨下Spring Cloud Gateway的一些其 ...

  5. OAuth2.0理解和用法

    现在网络的资料到处都是,很容易搜索到自己想要的答案.但答案通常只能解决自己一部分的问题.如果自己想要有一套自己的解决方案,还得重新撸一遍靠谱. 我需要学下OAuth2.0吗? 没看之前以为OAuth2 ...

  6. 使用gradle插件发布项目到nexus中央仓库

    目录 简介 Gradle Nexus Publish Plugin历史 插件的使用 Groovy DSL Kotlin DSL 插件背后的故事 总结 简介 Sonatype 提供了一个叫做开源软件资源 ...

  7. 《C++编程思想》部分章节学习笔记整理

    简介 此笔记为<C++编程思想>中部分章节的学习笔记,主要是第15章--多态性和虚函数 的学习笔记,此外还有少量其他章节的内容. 目录 文档:<C++编程思想>

  8. Python基础之容易忘记的地方

    (1)编译型与解释型语言区别: 编译型:一次性,把所有代码编译成机器能识别的二进制码,再运行 代表语言:c,c++ 优点: 执行速度块 缺点: 开发速度慢,调试周期长 解释型:代码从上到下一行一行解释 ...

  9. sed高级指令

    N命令 n命令 n命令简单来说就是提前读取下一行,覆盖模型空间前一行,然后执行后续命令.然后再读取新行,对新读取的内容重头执行sed //从test文件中取出偶数行 [root@localhost ~ ...

  10. tp5 composer phpexcel使用方法

    1.compser 安装phpexcel.在windows命令行下输入:进入网站根目录,compser phpoffice/phpexcel 2.页面引入两个类: use PHPExcel_IOFac ...