4.3.21. SDIO 使用说明

4.3.21.1. 概述

  • X5 支持 SDIO(Secure Digital Input Output)接口,用于高速数据传输和扩展外设。

  • X5 提供完整的 SDIO 硬件支持与驱动框架,支持多种传输模式及协议版本,允许通过标准接口连接多种外设如 Wi-Fi 模块、蓝牙模块。

4.3.21.2. 特点

  • 支持协议版本:兼容 SDIO Ver3.0 协议(含 eSDIO)。

  • 高速时钟支持:接口最高支持 200 MHz 时钟输入。

  • 多种传输模式:支持 4 线 数据传输,包括 SD High Speed、SDR12、SDR25、SDR50、SDR104 等模式,详细规格如下:

Bus Speed Mode Maximum Frequency Signal Voltage Bus Maximum Performance Spec. Version
Default Speed (DS) 25MHz 3.3V 12.5MB/sec 1.01
High Speed (HS) 50MHz 3.3V 25MB/sec 1.10
UHS-I: SDR12 25MHz 1.8V 12.5MB/sec 3.01
UHS-I: SDR25 50MHz 1.8V 25MB/sec 3.01
UHS-I: SDR50 100MHz 1.8V 50MB/sec 3.01
UHS-I: SDR104 208MHz 1.8V 104MB/sec 3.01

SDIO 协议详细文档请从SD 联盟官网自行获取。

4.3.21.3. 功能描述

典型应用

SDIO 接口的结构框图如下:

image-20250115-213644

  • CLK:主机提供的时钟信号给到 SDIO 外设

  • CMD:用于发送命令和接收响应

    • 主机通过这条线向 SDIO 外设发送控制命令(如初始化、配置、数据读写等)

    • 外设通过这条线将命令的响应返回给主机

  • DATA: 模式不同,支持 单线(DATA0) 或 多线传输(DATA0-DATA3)

    • 单线模式:只有 DATA0 一根线用于数据传输

    • 4线模式:DATA0-DATA3 提供更高的数据传输速率

SDIO 常见的应用场景包括:

  • Bluetooth :通过 SDIO 接口连接蓝牙模块,实现无线通信功能。

  • Wi-Fi :利用 SDIO 接口与主控通信,提供无线局域网(WLAN)连接。

  • 4G :支持 SDIO 接口的 4G 模块,用于提供高速的移动数据通信。

功能原理

  • 协议支持: 基于 SDIO Ver3.0 标准,支持完整的命令接口(CMD0~CMD52),支持 eSDIO(Embedded SDIO)。

  • 驱动架构: 内核中的 MMC 框架与 SDIO 驱动协同工作,负责完成以下任务:

    • 通过 sdio_register_driversdio_unregister_driver 完成设备注册和注销。

    • 解析设备树(DTS)中的硬件信息,初始化硬件资源。

    • 利用中断机制和 DMA 引擎高效处理数据传输。

4.3.21.4. 驱动代码

Kernel 驱动

在内核阶段,默认启用了 SDIO 支持,SDIO 驱动基于 MMC 框架实现,无需额外修改内核 defconfig。

驱动接口说明

驱动注册函数:

int sdio_register_driver(struct sdio_driver *drv)

驱动注销函数:

void sdio_unregister_driver(struct sdio_driver *drv)

sdio_driver 结构体定义如下:

struct sdio_driver {
	char *name;
	const struct sdio_device_id *id_table;
	int (*probe)(struct sdio_func *, const struct sdio_device_id *);
	void (*remove)(struct sdio_func *);
	struct device_driver drv;
};

设备树配置指南

SDIO 控制器的dts位置:arch/arm64/boot/dts/hobot/x5.dtsi

适配外设注意事项
  • 根据硬件设计,确认目标 MMC 控制器的 SDIO 编号是否与设备树(DTS)中配置的物理地址和设备类型一致。

  • 以 X5 EVB 为参考设计,配置如下:

SDIO 控制器 物理地址 设备类型
SDIO0 0x35040000 eMMC
SDIO1 0x35020000 SD 卡
SDIO2 0x35030000 其它 SDIO 设备,一般为 WiFi 卡

常用字段解释:

  • non-removable:标记不可移除设备,系统启动后不支持热插拔。

  • cd-gpios:定义 SD 卡检测引脚。

  • broken-cd:禁用卡槽检测功能。

  • broken-cd:禁用卡槽检测功能。

  • no-sd:禁用 SD 卡功能。

  • no-mmc:禁用 eMMC 功能。

  • cap-sdio-irq:启用 SDIO 中断。

  • clock-frequency:自定义工作时钟频率,单位 Hz。

以下是不同设备类型的关键配置说明:

eMMC
  • 关键属性

    • non-removable:标记为不可移除设备。注意,此配置会使系统在启动时仅对该控制器的设备进行一次探测。

  • 运行模式:一般有以下两种选择:

    • cap-mmc-highspeed:High Speed 模式,最高时钟频率为 52 MHz(X5 平台实际限制为 50 MHz)。

    • mmc-hs200-1_8v:HS200 模式,最高时钟频率为 200 MHz。

  • bus-width:数据线宽度,通常配置为 8

SD 卡
  • 关键属性

    • no-mmcno-sdio:SD 卡默认 DTS 配置包含 no-mmcno-sdio 以优化探测流程。

    • broken-cdcd-gpios

      • 如果未连接 SD 卡插拔检测中断引脚,请配置 broken-cd 并删除 cd-gpios 字段,系统将通过轮询方式检测卡槽状态。

      • 如果有插拔检测中断引脚,按照实际硬件定义配置 cd-gpios(包括极性)。

  • 运行模式:根据需求配置 sd-uhs-*cap-sd-highspeed 模式,具体说明参考 SD 协议或 MMC 协议文档。

  • 电压域调整

    • SD 卡默认探测电压为 3.3V,高速模式(sd-uhs-*)需要 1.8V IO 电压。

    • 配置项:

      • uhs-180v-gpio + uhs-180v-logic:配置用于切换 SD 卡槽 IO 供电的 GPIO 和极性,需与硬件设计一致。

      • MMC 电压域的切换由 MMC 自己控制,对应的 pinctrl 信息不需要调整。

其他 SDIO 设备(如 WiFi)
  • 关键属性

    • no-mmcno-sd:SDIO 设备默认 DTS 配置 no-mmcno-sd 优化探测流程。

    • broken-cd:通常 SDIO 设备不需要插拔检测中断。如果需要,配置方式与 SD 卡类似。

      • 如果 WIFI 模组没有 Card Detect 管脚,必须将”broken-cd”加上。

      • 如果需要对WiFi进行上下电,需要将”non-removable”字段删除,host端才会进行多次探测;否则 WiFi 模组不会被二次探测。

    • cap-sdio-irq:用于接收 SDIO 设备的中断(如 WiFi 唤醒)。

  • 运行模式:根据需求配置 sd-uhs-*cap-sd-highspeed 模式。

  • 电压域调整

    • 若默认电压为 3.3V,但需切换至 1.8V:参考 SD 卡配置方法。

    • 若默认电压为 1.8V:

      • 删除 uhs-180v-gpiouhs-180v-logic等字段,以防对GPIO进行误操作

      • 配置 mmc-fixed-voltage:特殊 DTS 字段,用于强制指定 MMC 控制器的IO供电,定义为”1800或”3300”,以配置为对应的电压,示例:

        mmc-fixed-voltage = <1800>;
        

完整说明请参考内核文档:Documentation/devicetree/bindings/mmc/mmc-controller.yaml

Kernel SDIO 框架调试

X5 SDIO 接口基于内核 MMC 框架,可通过Dynamic Debugftrace调试工具检查传输问题。

下面对Dynamic Debugftrace调试工具简单使用讲解,更详细的说明请参考:

  1. Dynamic Debug Linux 官方说明

  2. ftrace Linux 官方说明

Dynamic Debug 使用指南

Dynamic debug(具体路径及开启的文件可以根据需要修改):

echo 'file drivers/mmc/core/core.c +p' >/sys/kernel/debug/dynamic_debug/control
echo 'file drivers/mmc/core/mmc.c +p' >/sys/kernel/debug/dynamic_debug/control
echo 'file drivers/mmc/core/block.c +p' >/sys/kernel/debug/dynamic_debug/control
echo 'file drivers/mmc/host/sdhci-of-dwcmshc.c +p' > /sys/kernel/debug/dynamic_debug/control
echo 'file drivers/mmc/host/sdhci.c +p' > /sys/kernel/debug/dynamic_debug/control
echo 7 7 7 7 > /proc/sys/kernel/printk

Ftrace 使用指南

  1. 配置内核支持 Ftrace 相关选项

    CONFIG_FTRACE=y
    CONFIG_FUNCTION_TRACER=y
    CONFIG_DYNAMIC_FTRACE=y
    CONFIG_DEBUG_FS=y
    
  2. 完成内核配置后,重新编译并将生成的镜像烧录到目标设备。

  3. 进入系统加载驱动后开始 ftrace 使用,以 MMC 传输事件为例。

    cd /sys/kernel/debug/tracing/          #进入 Ftrace 工作目录
    echo mmc:mmc_request_start > set_event #添加事件 mmc_request_start,用于标识 MMC 请求的开始
    echo mmc:mmc_request_done >> set_event #添加事件 mmc_request_done,用于标识 MMC 请求的完成
    echo 0 > tracing_on                    #关闭实时跟踪功能,确保初始化阶段数据不被记录
    echo nop > current_tracer              #清除之前的跟踪器设置
    echo > trace                           #清空 trace 文件,避免干扰后续分析
    echo 1 > tracing_on                    #开启实时跟踪功能。
    cat /sys/kernel/debug/tracing/trace | grep mmc #查看并过滤 trace 文件中的 MMC 相关事件
    
  4. trace 文件分析

    通过 trace 文件中记录的事件,可以分析 MMC 请求的执行细节,包括请求发起、完成的具体时间及参数。以下是部分示例日志及其含义:

    kworker/5:1H-152  586.094457: mmc_request_start: mmc0: start struct mmc_request[000000007dc8561b]: cmd_opcode=25 cmd_arg=0xdca8 ....
    	<idle>-0      586.094839: mmc_request_done: mmc0: end struct mmc_request[000000007dc8561b]: cmd_opcode=25 cmd_err=0  ....
    kworker/0:0H-8    586.094911: mmc_request_start: mmc0: start struct mmc_request[00000000daeefa66]: cmd_opcode=13 cmd_arg=0x10000 ....
    kworker/0:0H-8    586.094936: mmc_request_done: mmc0: end struct mmc_request[00000000daeefa66]: cmd_opcode=13 cmd_err=0 ....
    kworker/5:1H-152  586.095231: mmc_request_start: mmc0: start struct mmc_request[000000002e7e251a]: cmd_opcode=6 cmd_arg=0x3200101 ....
    	<idle>-0      586.095258: mmc_request_done: mmc0: end struct mmc_request[000000002e7e251a]: cmd_opcode=6 cmd_err=0 ....
    kworker/5:1H-152  586.095866: mmc_request_start: mmc0: start struct mmc_request[000000001e3cd0e1]: cmd_opcode=13 cmd_arg=0x10000 ....
    	<idle>-0      586.095889: mmc_request_done: mmc0: end struct mmc_request[000000001e3cd0e1]: cmd_opcode=13 cmd_err=0 ....
    
  • 时间戳:586.094457 和 586.094839 分别为事件发生的时间点(单位:秒)。

  • 进程名:例如,kworker/5:1H-152 表示处理事件的内核线程。

  • 事件类型

    • mmc_request_start:表示发起 MMC 请求,包含具体的请求参数(如 cmd_opcode=25,cmd_arg=0xdca8)。

    • mmc_request_done:表示完成 MMC 请求,记录请求的执行结果(如 cmd_err=0 表示无错误,bytes_xfered=45056 表示传输了 45056 字节)。

    • 关联请求:通过 struct mmc_request[000000007dc8561b] 可定位每个请求的唯一标识。

MMC 控制器配置和运行参数

可以通过以下命令查看 MMC 控制器的配置和运行参数(以 mmc2 为例):

cat /sys/kernel/debug/mmc2/ios
clock:          200000000 Hz
actual clock:   200000000 Hz
vdd:            21 (3.3 ~ 3.4 V)
bus mode:       2 (push-pull)
chip select:    0 (don't care)
power mode:     2 (on)
bus width:      2 (4 bits)
timing spec:    6 (sd uhs SDR104)
signal voltage: 1 (1.80 V)
driver type:    0 (driver type B)

参数解释:

  • clock: MMC 控制器配置的时钟频率(200 MHz)。

  • actual clock:实际运行的时钟频率(200 MHz)。

  • vdd:供电电压范围(3.3 ~ 3.4 V)。

  • bus mode:总线模式(2:推挽模式)。

  • chip select:芯片选择模式(0:无关)。

  • power mode:电源模式(2:开启)。

  • bus width:总线宽度(4 位)。

  • timing spec:传输模式(SDR104)。

  • signal voltage:信号电压(1.8 V)。

  • driver type:驱动类型(B 类型)。

SDIO 设备调试

  • 请参考设备厂商提供的驱动源码,启用其内置调试选项进行编译与调试。

  • 关于 WIFI SDIO 设备调试请查阅 WIFI_Driver_Debug_Guide

4.3.21.5. 常见问题

1. 无法识别 SDIO 设备

  • 设备树检查:确认 SDIO 接口状态是否配置为 okay

  • 时钟配置检查:确保时钟频率和模式配置正确。

2. 卡运行模式与预期不符

  • DTS 配置检查:核对设备树中目标运行模式的配置(如电压域等)。

  • 硬件支持检查:确保硬件提供目标模式所需的 IO 电压。

3. 控制器未初始化

  • 初始化确认:通过检查 /sys/kernel/debug/mmc[x] 文件夹,确认当前已初始化的 MMC 控制器数量。

注意事项

  • 如果 SDIO0 在 DTS 中配置为 status="disabled",而 SDIO1 配置为 status="okay"

    • /sys/kernel/debug 中,SDIO1 会被枚举为 mmc0,依次类推。

  • 可通过以下命令查看对应 SDIO 控制器的初始化状态:

    cat /sys/firmware/devicetree/base/soc/hsio_apb/sdhci@xxx/status