查看: 1164|回复: 0

[技术交流] USB接口WiFi驱动浅析 (一)

[复制链接]

185

主题

204

帖子

596

积分

利尔达员工

Rank: 9Rank: 9Rank: 9

积分
596
发表于 2020-10-13 09:25:53 | 显示全部楼层 |阅读模式
  学习了SDIO接口的WiFi驱动,现在我们来学习一下USB接口的WiFi驱动,二者的区别在于接口不同。而USB接口的设备驱动,比如USB摄像头驱动、USB鼠标驱动,同样都符合LinuxUSB驱动结构:

USB设备驱动(字符设备、块设备、网络设备)
|
USB 核心
|
USB主机控制器驱动

  不同之处只是在于USB摄像头驱动是字符设备,而我们今天要学习的WiFi驱动是网络设备;当然由我们编写的部分还是USB设备驱动部分,下面进入USB接口WiFi驱动的分析,如何分析呢?我们下面从这几个方面入手:

  从硬件层面上看,WIFI设备与CPU通信是通过USB接口的,与其他WIFI设备之间的通信是通过无线射频(RF)。

  从软件层面上看,Linux操作系统要管理WIFI设备,那么就要将WIFI设备挂载到USB总线上,通过USB子系统实现管理。而同时为了对接网络,又将WIFI设备封装成一个网络设备。

  我们以USB接口的WIFI模块进行分析:
  a——从USB总线的角度去看,它是USB设备;
  b——从Linux设备的分类上看,它又是网络设备;
  c——从WIFI本身的角度去看,它又有自己独特的功能及属性,因此它又是一个私有的设备;

  通过上述的分析,我们只要抓住这三条线索深入去分析它的驱动源码,整个WIFI驱动框架就会浮现在你眼前。

  一、框架整理

  1、USB设备驱动

  现在我们先从USB设备开始,要写一个USB设备驱动,那么大致步骤如下:

  a——需要针对该设备定义一个USB驱动,对应到代码中即定义一个usb_driver结构体变量

  代码如下:

  struct usb_driver xxx_usb_wifi_driver;

  b——填充该设备的usb_driver结构体成员变量

  代码如下:

  static struct usb_driver xxx_usb_wifi_driver = {
    .name = "XXX_USB_WIFI",
    .probe = xxx_probe,
    .disconnect = xxx_disconnect,
    .suspend = xxx_suspend,
    .resume = xxx_resume,
    .id_table = xxx_table,
  };

  c——将该驱动注册到USB子系统

  代码如下:

  usb_register(&xxx_usb_wifi_driver);

  以上步骤只是一个大致的USB驱动框架流程,而最大和最复杂的工作是填充usb_driver结构体成员变量。以上步骤的主要工作是将USB接口的WIFI设备挂载到USB总线上,以便Linux系统在USB总线上就能够找到该设备。

  2、网络设备驱动

  接下来是网络设备的线索,网络设备驱动大致步骤如下:

  a——定义一个net_device结构体变量ndev

  代码如下:

  struct net_device *ndev;

  b——初始化ndev变量并分配内存

  代码如下:

  ndev=alloc_etherdev();

  c——填充ndev -> netdev_ops结构体成员变量

  代码如下:

  static const struct net_device_ops xxx_netdev_ops= {
    .ndo_init = xxx_ndev_init,
    .ndo_uninit = xxx _ndev_uninit,
    .ndo_open = netdev_open,
    .ndo_stop = netdev_close,
    .ndo_start_xmit = xxx_xmit_entry,
    .ndo_set_mac_address = xxx_net_set_mac_address,
    .ndo_get_stats = xxx_net_get_stats,
    .ndo_do_ioctl = xxx_ioctl,
  };

  d——填充ndev->wireless_handlers结构体成员变量,该变量是无线扩展功能

  代码如下:

  ndev->wireless_handlers = (struct iw_handler_def *)&xxx_handlers_def;

  e——将ndev设备注册到网络子系统

  代码如下:

  register_netdev(ndev);

  3、 WIFI设备本身私有的功能及属性

  如自身的配置及初始化、建立与用户空间的交互接口、自身功能的实现等。

  a——自身的配置及初始化

  代码如下:               

  xxx_read_chip_info();

  xxx_chip_configure();

  xxx_hal_init();

  b——主要是在proc和sys文件系统上建立与用户空间的交互接口

  代码如下:

  xxx_drv_proc_init();

  xxx_ndev_notifier_register();

  c——自身功能的实现

  WIFI的网络及接入原理,如扫描等。同时由于WIFI在移动设备中,相对功耗比较大,因此,对于功耗、电源管理也会在驱动中体现。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表