Linux 驱动开发之WIFI设备分析3(基于Linux6.6)---SDIO接口WiFi介绍
一、SDIO相关基础知识解析
1、SDIO接口
SDIO 故名思义,就是 SD 的 I/O 接口(interface)的意思,不过这样解释可能还有点抽像。更具体的说明,SD 本来是记忆卡的标准,但是现在也可以把 SD 拿来插上一些外围接口使用,这样的技术便是 SDIO。
所以 SDIO 本身是一种相当单纯的技术,透过 SD 的 I/O 接脚来连接外部外围,并且透过 SD 上的 I/O 数据接位与这些外围传输数据,而且 SD 协会会员也推出很完整的 SDIO stack 驱动程序,使得 SDIO 外围(我们称为SDIO 卡)的开发与应用变得相当热门。
现在已经有非常多的手机或是手持装置都支持 SDIO 的功能(SD 标准原本就是针对 mobile device 而制定),而且许多 SDIO 外围也都被开发出来,让手机外接外围更加容易,并且开发上更有弹性(不需要内建外围)。目前常见的 SDIO 外围(SDIO 卡)有:
· Wi-Fi card(无线网络卡)
· CMOS sensor card(照相模块)
· GPS card
· GSM/GPRS modem card
· Bluetooth card
SDIO 的应用将是未来嵌入式系统最重要的接口技术之一,并且也会取代目前 GPIO 式的 SPI 接口。
2、SDIO总线
SDIO总线 和 USB总线 类似,SDIO也有两端,其中一端是HOST端,另一端是device端。所有的通信都是由HOST端 发送 命令 开始的,Device端只要能解析命令,就可以相互通信。
CLK信号:HOST给DEVICE的 时钟信号,每个时钟周期传输一个命令。
CMD信号:双向 的信号,用于传送 命令 和 反应。
DAT0-DAT3 信号:四条用于传送的数据线。
VDD信号:电源信号。
VSS1,VSS2:电源地信号。
3、SDIO热插拔原理
方法:设置一个 定时器检查 或 插拔中断检测
硬件:假如GPG10(EINT18)用于SD卡检测
GPG10 为高电平 即没有插入SD卡
GPG10为低电平 即插入了SD卡
4、SDIO命令
SDIO总线上都是HOST端发起请求,然后DEVICE端回应请求。sdio命令由6个字节组成。
a -- Command:用于开始传输的命令,是由HOST端发往DEVICE端的。其中命令是通过CMD信号线传送的。
b -- Response:回应是DEVICE返回的HOST的命令,作为Command的回应。也是通过CMD线传送的。
c -- Data:数据是双向的传送的。可以设置为1线模式,也可以设置为4线模式。数据是通过DAT0-DAT3信号线传输的。
SDIO的每次操作都是由HOST在CMD线上发起一个CMD,对于有的CMD,DEVICE需要返回Response,有的则不需要。
对于读命令,首先HOST会向DEVICE发送命令,紧接着DEVICE会返回一个握手信号,此时,当HOST收到回应的握手信号后,会将数据放在4位的数据线上,在传送数据的同时会跟随着CRC校验码。当整个读传送完毕后,HOST会再次发送一个命令,通知DEVICE操作完毕,DEVICE同时会返回一个响应。
对于写命令,首先HOST会向DEVICE发送命令,紧接着DEVICE会返回一个握手信号,此时,当HOST收到回应的握手信号后,会将数据放在4位的数据线上,在传送数据的同时会跟随着CRC校验码。当整个写传送完毕后,HOST会再次发送一个命令,通知DEVICE操作完毕,DEVICE同时会返回一个响应。
二、SDIO接口驱动
前面讲到,SDIO接口的wifi,首先,它是一个sdio的卡的设备,然后具备了wifi的功能,所以SDIO接口的WiFi驱动就是在wifi驱动外面套上了一个SDIO驱动的外壳,
在 Linux 内核中,设备驱动的设计通常遵循分层结构,即将不同层次的功能进行模块化,以便于管理、扩展和维护。主要的设计思想包括:
-
硬件抽象层:提供对不同硬件设备的统一接口,使得上层软件不需要直接与硬件打交道。硬件的细节和实现被封装在较低层,驱动程序仅关心上层所需的接口。
-
分离硬件与操作系统的依赖:驱动程序不仅要能在不同的硬件上运行,还要与操作系统的其他部分进行适配和配合。因此,硬件相关的代码和操作系统核心代码应当分离,减少耦合。
-
设备类型抽象:不同种类的设备(如块设备、字符设备、网络设备等)会有不同的处理方式,驱动程序通过在内核中对设备进行类型化,来实现设备与操作系统的松耦合。
下面先分析SDIO接口驱动的实现,看几个重要的数据结构(用于核心层与主机驱动层 的数据交换处理)。
include/linux/mmc/host.h
struct mmc_host 用来描述卡控制器
struct mmc_card 用来描述卡
struct mmc_driver 用来描述 mmc 卡驱动
struct sdio_func 用来描述 功能设备
struct mmc_host_ops 用来描述卡控制器操作接口函数功能,用于从 主机控制器层向 core 层注册操作函数,从而将core 层与具体的主机控制器隔离。也就是说 core 要操作主机控制器,就用这个 ops 当中给的函数指针操作,不能直接调用具体主控制器的函数。
2.1、编写Host层驱动
例:drivers/mmc/host/s3cmci.c
- MODULE_DEVICE_TABLE(platform, s3cmci_driver_ids);
-
- static struct platform_driver s3cmci_driver = {
- .driver = {
- .name = "s3c-sdi",
- .probe_type = PROBE_PREFER_ASYNCHRONOUS,
- .of_match_table = s3cmci_dt_match,
- },
- .id_table = s3cmci_driver_ids,
- .probe = s3cmci_probe,
- .remove = s3cmci_remove,
- .shutdown = s3cmci_shutdown,
- };
-
- module_platform_driver(s3cmci_driver);
-
- s3cmci_probe(struct platform_device *pdev)
- {
- //....
- struct mmc_host *mmc;
- mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev); //分配mmc_host结构体
-
- //.....
- }
-
- /*注册中断处理函数s3cmci_irq,来处理数据收发过程引起的各种中断*/
- request_irq(host->irq, s3cmci_irq, 0, DRIVER_NAME, host) //注册中断处理函数s3cmci_irq
-
- /*注册中断处理s3cmci_irq_cd函数,来处理热拨插引起的中断,中断触发的形式为上升沿、下降沿触发*/
- request_irq(host->irq_cd, s3cmci_irq_cd,IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING, DRIVER_NAME, host)
-
- mmc_add_host(mmc); //initialise host hardware //向MMC core注册host驱动
- ----> device_add(&host->class_dev); //添加设备到mmc_bus_type总线上的设备链表中
- ----> mmc_start_host(host); //启动mmc host
-
- /*MMC drivers should call this when they detect a card has been inserted or removed.检测sd卡是否插上或移除*/
- ---->mmc_detect_change(host, 0);
-
- /*Schedule delayed work in the MMC work queue.调度延时工作队列*/
- mmc_schedule_delayed_work(&host->detect, delay);
搜索host->detected得到以下信息:
drivers/mmc/core/host.c
- NIT_DELAYED_WORK(&host->detect, mmc_rescan);
-
- mmc_rescan(struct work_struct *work)
- ---->mmc_bus_put(host);//card 从bus上移除时,释放它占有的总线空间
-
- /*判断当前mmc host
评论记录:
回复评论: