驱动学习——Linux下浅析USB转串口驱动的流程

21 篇文章 0 订阅
7 篇文章 0 订阅

我们知道,Linux对于USB设备的支持是十分强大的,USB接口的无线网卡、USB的摄像头、USB键盘、鼠标等等。做些许代码修改,内核选项选中支持后,即可使用这些设备。但是我们要清楚,越是简单的使用,其背后就越是复杂的设计。粗略翻了翻《Linux 那些事儿之我是U盘》,才意识到Linux的USB host驱动有多复杂,不是两三天就能读懂的。( T^T..)。
这篇博文仅分析一下从内核初始化到USB设备插入USB接口到虚拟出tty设备的过程。


一、Linux初始化过程

1、首先在usb.c 中:

/* drivers\usb\core\usb.c */
static int __init usb_init(void)
{
    int retval;
    ... ...
    retval = bus_register(&usb_bus_type);
    ... ...
}

可以看到在usb_init 初始化函数中调用了bus_register 注册了一条USB总线。
还是在这个函数下接着:

/* drivers\usb\core\usb.c */
... ...
retval = usb_register_device_driver(&usb_generic_driver, THIS_MODULE);
    if (!retval)
        goto out;
... ...

usb_generic_driver 这个驱动程序注册给系统.

/* drivers\usb\core\generic.c */
struct usb_device_driver usb_generic_driver = {
    .name = "usb",
    .probe = generic_probe,
    .disconnect = generic_disconnect,
#ifdef  CONFIG_PM
    .suspend = generic_suspend,
    .resume = generic_resume,
#endif
    .supports_autosuspend = 1,
};

里面包含了它自己的probe 函数。

2、在usb_serial_init 中:

/*drivers\usb\serial\usb-serial.c*/
static int __init usb_serial_init(void)
{
    ... ...
    result = tty_register_driver(usb_serial_tty_driver);
    if (result) {
        printk(KERN_ERR "usb-serial: %s - tty_register_driver failed\n", __func__);
        goto exit_reg_driver;
    }
    ... ...
}

usb_serial_init()函数会调用tty_register_driver(usb_serial_tty_driver)向内核注册tty类的设备驱动,并在USB转串口总线上添加这个驱动。

3、在option.coption_init()中:

/*drivers\usb\serial\option.c*/
static int __init option_init(void)
{
    int retval;
    retval = usb_serial_register(&option_1port_device);
    if (retval)
        goto failed_1port_device_register;
    retval = usb_register(&option_driver);
    if (retval)
        goto failed_driver_register;

    printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
           DRIVER_DESC "\n");

    return 0;

failed_driver_register:
    usb_serial_deregister(&option_1port_device);
failed_1port_device_register:
    return retval;
}

可以看到:1.调用usb_serial_register(&option_1port_device)在USB转串口总线上注册驱动option_1port_device(注意,这仅仅是在总线上注册,并不向内核注册)。
2.调用usb_register(&option_driver) 在USB总线上注册USB驱动,该驱动是接口的驱动。

二、USB设备插入

1.当我们的USB Modem设备插入USB端口时,要调用bus_add_device()在USB总线上添加一个USB设备。
2.该USB设备由于有USB设备号,会找到刚才注册的usb_generic_driver中的generic_probe()函数,在这个函数中经过一系列的函数调用最后会 进入usb_set_configuration()
3.usb_set_configuration()函数会根据HOST和Device沟通的情况,进行总线枚举,我使用的fl2440上有5个USB接口,所以会生成5个interface,该函数会依次将这5个interface添加到USB总线上。
4.每个interface会根据VID和PID找到合适自己的probe函数,这里我们设备的4个接口会依次进入usb_serial_probe()

三、虚拟出ttyUSB设备

1.进入usb_serial_probe() 后,首先生成5个usb_serial_port,port0,port1,port2,port3,port4。接着调用device add()函数 ,再调用tty_register_device()
2.tty_register_device()函数主要做了三件事:
(1)向系统注册这5个串口设备。
(2)将串口设备,次设备号,串口驱动usb_serial_tty_driver绑定到一起。
(3)在/dev目录下生成/dev/ttyUSB0,/dev/ttyUSB1,/dev/ttyUSB2,/dev/ttyUSB3,/dev/ttyUSB4共5个设备。


回想当初在做移植3G无线上网卡时,要让Linux识别出我们得上网卡,只需要在option.coption_ids[] 里添加上自己的设备,包括厂家ID、设备ID。再配置内核选项后,即可识别我的3G上网卡。但是背后的工作流程可没这么简单的,这篇博文仍然比较片面,问题多多。这里仅做一个记录吧!

参考的资料:
《Linux 那些事儿之我是U盘》
http://blog.chinaunix.net/uid-20742320-id-4266188.html
http://blog.csdn.net/txxm520/article/details/8934706
http://blog.csdn.net/bingqingsuimeng/article/details/7834878

  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
SDIO是一种用于连接多种设备的接口标准,包括Wi-Fi等无线网络设备。SDIO接口Wi-Fi驱动程序是用来管理和控制SDIO模块连接Wi-Fi设备的程序。Wi-Fi驱动程序通常是由设备制造商或操作系统供应商提供的,它们可以针对特定的SDIO模块和Wi-Fi设备进行定制。驱动程序管理SDIO接口与Wi-Fi设备的通信,控制数据流和网络连接以及提供对Wi-Fi设备的配置和监视功能。 在SDIO接口中,Wi-Fi设备一般作为一个SDIO卡出现,并通过SDIO总线与主处理器通信。因此,SDIO接口Wi-Fi驱动程序需要充分考虑SDIO总线和Wi-Fi设备之间的交互,并提供相应的操作和处理流程。常见的SDIO接口Wi-Fi驱动程序包括驱动层和协议层两部分。驱动层主要负责设备驱动程序的加载和卸载,以及控制SDIO总线与Wi-Fi设备之间的基本交互。协议层则实现与Wi-Fi设备之间的高级通信协议和数据传输,如TCP/IP协议栈、接入控制和传输协议等。 SDIO接口Wi-Fi驱动程序的设计和实现需要考虑多方面的因素,如SDIO总线的带宽和时序控制、Wi-Fi设备的固件和驱动程序兼容性、网络连接和性能要求等。通常需要经过严格的测试和优化才能实现良好的性能和稳定性。 总之,SDIO接口Wi-Fi驱动程序是一项关键技术,它的实现对Wi-Fi设备的性能和可靠性都有着重要的影响。需要专业的技术团队和优秀的开发工具支持,才能实现高品质的SDIO接口Wi-Fi驱动程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值