当前位置: 首页 > news >正文

【Linux驱动开发】Linux SDIO 底层原理与实现细节详解

Linux SDIO 底层原理与实现细节详解

1. SDIO 协议概述

SDIO (Secure Digital Input Output) 是一种基于 SD 卡接口的扩展协议,它允许在 SD 卡物理接口上连接各种外设设备。SDIO 不仅支持存储设备,还支持 WiFi、蓝牙、GPS、摄像头等多种功能设备。

1.1 SDIO 协议特点

  • 兼容性: 后向兼容 SD 存储卡协议
  • 多功能: 支持多种外设类型
  • 热插拔: 支持设备的热插拔操作
  • 低功耗: 适用于移动设备
  • 高速传输: 支持高速数据传输模式

2. SDIO 硬件接口

2.1 物理接口

SDIO 使用 9-pin 接口,与标准 SD 卡接口完全兼容:

引脚定义:
┌─────┬─────┬─────┐
│  1  │  2  │  3  │
│ CD/DAT3 │ CMD │ VSS │
├─────┼─────┼─────┤
│  4  │  5  │  6  │
│ VDD │ CLK │ VSS │
├─────┼─────┼─────┤
│  7  │  8  │  9  │
│ DAT0 │ DAT1 │ DAT2 │
└─────┴─────┴─────┘

2.2 信号线功能

  • CMD: 命令/响应线,双向传输
  • CLK: 时钟信号,由主机提供
  • DAT0-DAT3: 数据线,支持 1-bit 或 4-bit 模式
  • VDD/VSS: 电源和地线
  • CD: 卡检测信号

3. SDIO 协议架构

3.1 协议层次结构

┌─────────────────────────────────────┐
│        应用层 (Application)         │
├─────────────────────────────────────┤
│       SDIO 功能层 (Function)       │
├─────────────────────────────────────┤
│      SDIO 核心层 (SDIO Core)       │
├─────────────────────────────────────┤
│        SD 物理层 (Physical)         │
└─────────────────────────────────────┘

3.2 功能编号 (Function Number)

SDIO 设备可以包含多个功能:

  • Function 0: 卡信息功能 (CIA - Card Information Area)
  • Function 1-7: 具体设备功能
  • Function 8-255: 保留

3.3 寄存器空间

SDIO 设备寄存器空间映射:

0x00-0x0FFF: Function 0 (CIA) - 卡基本信息
0x1000-0x1FFF: Function 1 寄存器空间
0x2000-0x2FFF: Function 2 寄存器空间
...
0x7000-0x7FFF: Function 7 寄存器空间

4. Linux SDIO 子系统架构

4.1 子系统组件

Linux SDIO 子系统主要包含以下组件:

┌─────────────────────────────────────┐
│      SDIO 设备驱动层               │
│   (WiFi, Bluetooth, GPS, etc.)    │
├─────────────────────────────────────┤
│      SDIO 核心层                   │
│   (mmc/sdio/core.c)               │
├─────────────────────────────────────┤
│      MMC/SD 主机控制器驱动          │
│   (mmc/host/*.c)                  │
├─────────────────────────────────────┤
│      硬件平台层                     │
│   (SoC SDIO 控制器)                │
└─────────────────────────────────────┘

4.2 核心数据结构

4.2.1 struct sdio_func
struct sdio_func {struct mmc_card *card;      /* 关联的 MMC 卡 */struct sdio_func_tuple *tuples; /* 功能元数据 */unsigned int num;           /* 功能编号 (1-7) */unsigned char class;        /* 设备类别 */u16 vendor;                 /* 厂商 ID */u16 device;                 /* 设备 ID */unsigned int max_blksize;   /* 最大块大小 */unsigned int cur_blksize;   /* 当前块大小 */struct device dev;          /* 设备模型 */struct sdio_func *next;     /* 下一个功能 *//* 中断处理 */sdio_irq_handler_t *irq_handler;void *irq_data;/* 电源管理 */unsigned int enable_timeout;
};
4.2.2 struct mmc_card
struct mmc_card {struct mmc_host *host;      /* 主机控制器 */struct device dev;          /* 设备模型 */unsigned int rca;           /* 相对地址 */unsigned int type;          /* 卡类型 (MMC/SD/SDIO) */unsigned int state;         /* 卡状态 *//* SDIO 特有字段 */unsigned int sdio_funcs;    /* SDIO 功能数量 */struct sdio_func *sdio_func[SDIO_MAX_FUNCS];/* 卡信息 */char *name;                 /* 卡名称 */struct cis *cis;            /* 卡信息结构 */
};

5. SDIO 初始化流程

5.1 卡检测与识别

/* 1. 卡插入检测 */
mmc_detect_change(host, 0);/* 2. 发送 CMD5 (IO_SEND_OP_COND) */
mmc_send_io_op_cond(host, ocr, &rocr);/* 3. 获取卡相对地址 */
mmc_send_relative_addr(card, &card->rca);/* 4. 选择卡 */
mmc_select_card(card);/* 5. 读取 CIS (Card Information Structure) */
sdio_read_cis(card);/* 6. 初始化各个功能 */
for (func = 1; func <= card->sdio_funcs; func++) {sdio_init_func(card, func);
}

5.2 CIS (Card Information Structure) 解析

CIS 包含设备的关键信息:

struct cis_tuple {u8 code;    /* Tuple 代码 */u8 size;    /* 数据大小 */u8 data[0]; /* 数据内容 */
};

主要 Tuple 类型:

  • 0x20: 功能扩展 Tuple
  • 0x21: 功能信息 Tuple
  • 0x22: 功能扩展信息 Tuple
  • 0x80: 厂商特定 Tuple

6. SDIO 数据传输机制

6.1 传输模式

SDIO 支持两种数据传输模式:

6.1.1 字节模式 (Byte Mode)
/* 读取单个寄存器 */
u8 sdio_readb(struct sdio_func *func, unsigned int addr, int *err_ret);/* 写入单个寄存器 */
void sdio_writeb(struct sdio_func *func, u8 b, unsigned int addr, int *err_ret);
6.1.2 块模式 (Block Mode)
/* 读取数据块 */
int sdio_readsb(struct sdio_func *func, void *dst, unsigned int addr, int count);/* 写入数据块 */
int sdio_writesb(struct sdio_func *func, unsigned int addr, void *src, int count);

6.2 DMA 传输

Linux SDIO 支持 DMA 传输以提高性能:

struct mmc_data {unsigned int timeout_ns;    /* 超时时间 */unsigned int timeout_clks;   /* 时钟周期超时 */unsigned int blksz;         /* 块大小 */unsigned int blocks;        /* 块数量 */unsigned int error;         /* 错误码 */unsigned int flags;         /* 标志位 *//* 数据缓冲区 */struct scatterlist *sg;       /* 散列表 */unsigned int sg_len;        /* 散列表长度 *//* DMA 相关 */int dma_ch;                 /* DMA 通道 */unsigned int dma_dir;       /* DMA 方向 */
};

7. SDIO 中断处理

7.1 中断类型

SDIO 支持两种中断模式:

7.1.1 功能中断 (Function Interrupt)

每个功能可以独立产生中断:

/* 注册中断处理函数 */
int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler);/* 释放中断 */
int sdio_release_irq(struct sdio_func *func);
7.1.2 卡中断 (Card Interrupt)

整个卡产生的中断:

/* 在主机控制器中处理卡中断 */
static irqreturn_t sdio_irq(int irq, void *dev_id)
{struct mmc_host *host = dev_id;/* 读取中断状态 */status = sdio_readb(func, SDIO_CCCR_INTx, &err);/* 处理各个功能的中断 */for (i = 1; i <= 7; i++) {if (status & (1 << i)) {/* 调用功能的中断处理函数 */if (card->sdio_func[i]->irq_handler) {card->sdio_func[i]->irq_handler(card->sdio_func[i]);}}}return IRQ_HANDLED;
}

7.2 中断使能寄存器

/* CCCR (Card Common Control Registers) 中的中断控制 */
#define SDIO_CCCR_IENx      0x04    /* 中断使能寄存器 */
#define SDIO_CCCR_INTx      0x05    /* 中断状态寄存器 */
#define SDIO_CCCR_ABORT     0x06    /* 中止控制寄存器 */

8. 电源管理

8.1 电源状态

SDIO 定义了三种电源状态:

  • Active: 全功率运行
  • Idle: 低功耗状态,保持上下文
  • Standby: 最低功耗,丢失上下文

8.2 电源控制寄存器

/* 电源控制相关寄存器 */
#define SDIO_CCCR_BUS_IF_CTRL   0x07    /* 总线接口控制 */
#define SDIO_CCCR_CARD_CAPS     0x08    /* 卡能力 */
#define SDIO_CCCR_CIS_PTR       0x09    /* CIS 指针 */
#define SDIO_CCCR_BUS_SUSP      0x0C    /* 总线挂起控制 */
#define SDIO_CCCR_FUNC_SEL      0x0D    /* 功能选择 */
#define SDIO_CCCR_EXEC_FLAGS    0x0E    /* 执行标志 */
#define SDIO_CCCR_READY_FLAGS   0x0F    /* 就绪标志 */

8.3 Linux 电源管理实现

static int sdio_suspend(struct device *dev)
{struct sdio_func *func = dev_to_sdio_func(dev);struct sdio_driver *drv = to_sdio_driver(dev->driver);/* 调用驱动的挂起函数 */if (drv->suspend) {ret = drv->suspend(func);if (ret)return ret;}/* 禁用功能 */sdio_disable_func(func);return 0;
}static int sdio_resume(struct device *dev)
{struct sdio_func *func = dev_to_sdio_func(dev);struct sdio_driver *drv = to_sdio_driver(dev->driver);/* 启用功能 */ret = sdio_enable_func(func);if (ret)return ret;/* 调用驱动的恢复函数 */if (drv->resume) {ret = drv->resume(func);if (ret)goto disable_func;}return 0;
}

9. SDIO 驱动开发

9.1 驱动结构

struct sdio_driver {char *name;                 /* 驱动名称 */const struct sdio_device_id *id_table; /* 支持的设备 ID */int (*probe)(struct sdio_func *);      /* 探测函数 */void (*remove)(struct sdio_func *);    /* 移除函数 *//* 电源管理 */int (*suspend)(struct sdio_func *);int (*resume)(struct sdio_func *);struct device_driver drv;
};

9.2 设备 ID 匹配

static const struct sdio_device_id my_sdio_ids[] = {{ SDIO_DEVICE(SDIO_VENDOR_ID_XXX, SDIO_DEVICE_ID_XXX) },{ /* 结束标记 */ }
};
MODULE_DEVICE_TABLE(sdio, my_sdio_ids);

9.3 驱动注册

static struct sdio_driver my_sdio_driver = {.name = "my_sdio_device",.id_table = my_sdio_ids,.probe = my_sdio_probe,.remove = my_sdio_remove,.suspend = my_sdio_suspend,.resume = my_sdio_resume,
};static int __init my_sdio_init(void)
{return sdio_register_driver(&my_sdio_driver);
}static void __exit my_sdio_exit(void)
{sdio_unregister_driver(&my_sdio_driver);
}module_init(my_sdio_init);
module_exit(my_sdio_exit);

10. 调试技术

10.1 调试工具

# 查看 SDIO 设备信息
ls /sys/bus/sdio/devices/# 查看驱动信息
ls /sys/bus/sdio/drivers/# 查看详细的 SDIO 信息
cat /sys/kernel/debug/mmc*/ios
cat /sys/kernel/debug/mmc*/clock
cat /sys/kernel/debug/mmc*/stats

10.2 内核调试选项

# 启用 MMC/SDIO 调试信息
CONFIG_MMC_DEBUG=y
CONFIG_MMC_VERBOSE_PROBE=y# 查看内核日志
dmesg | grep -i sdio
dmesg | grep -i mmc

10.3 常见问题排查

10.3.1 设备识别失败
# 检查硬件连接
# 验证电压和时钟信号
# 检查设备树配置
10.3.2 数据传输错误
# 检查 DMA 配置
# 验证时钟频率设置
# 检查数据线连接
10.3.3 中断问题
# 检查中断引脚配置
# 验证中断处理函数
# 检查中断使能寄存器

11. 性能优化

11.1 传输优化

  • 使用 DMA 传输: 减少 CPU 占用
  • 增加块大小: 提高传输效率
  • 使用高速模式: 支持 50MHz 以上时钟

11.2 中断优化

  • 中断合并: 减少中断频率
  • 轮询模式: 在高负载时使用轮询
  • 中断亲和性: 绑定到特定 CPU

11.3 电源优化

  • 动态时钟: 根据负载调整时钟频率
  • 智能休眠: 空闲时进入低功耗模式
  • 批量操作: 合并多个操作为一次传输

12. 安全考虑

12.1 数据安全

  • 加密传输: 对敏感数据进行加密
  • 访问控制: 实现基于功能的访问控制
  • 安全启动: 验证设备固件完整性

12.2 系统安全

  • 权限控制: 限制 SDIO 设备访问权限
  • 输入验证: 验证所有用户输入
  • 错误处理: 安全的错误处理机制

13. 总结

Linux SDIO 子系统提供了完整的 SDIO 设备支持框架,包括设备识别、数据传输、中断处理和电源管理等功能。理解其底层原理和实现细节对于开发高性能、高可靠性的 SDIO 设备驱动至关重要。

通过深入了解 SDIO 协议、Linux 内核实现机制以及调试技术,开发者可以更好地利用 SDIO 接口连接各种外设,构建功能丰富的嵌入式系统。

参考资料

  1. SDIO 规范: SDIO Specification Version 3.0
  2. Linux 内核源码: drivers/mmc/core/
  3. 内核文档: Documentation/mmc/
  4. SD 协会: www.sdcard.org
  5. Linux MMC 项目: git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc.git

本文档基于 Linux 5.x 内核版本编写,具体实现可能因内核版本而异。

http://www.dtcms.com/a/619109.html

相关文章:

  • 安徽建设厅官方网站路由下做网站映射
  • 二进制与字符编码
  • 网站开发和程序开发的却别wordpress文章html页面
  • 智慧农业/农业物联网技术架构
  • 广州网站建设多少钱wordpress超链接工信部
  • 煤矿传送带异物检测:深度学习引领煤矿安全新革命!
  • 卖链接的网站为什么高德地图没有外国位置信息
  • 【RL】KTO: Model Alignment as Prospect Theoretic Optimization
  • 前端网站开发教程优秀金融网站设计
  • 【TypeScript】事件循环和LibUV简述
  • Java泛型相关知识
  • 嵌入式复习
  • 莆田网站建设创意我的网站设计联盟
  • 东城建站推广做网站很麻烦吗
  • 图神经网络分享系列-GraphSage(Inductive Representation Learning on Large Graphs) (二)
  • 杭州企业建站程序中国镇江网
  • 做网站技术有什么网站可以推广信息
  • 开发做游戏的网站wordpress自定义新页面链接
  • 冬日骑行显格调!维乐Angel Revo坐垫暗藏高级感
  • 建网站有什么要求国外的建筑设计案例网站
  • 郑州免费做网站东三省网站建设公司
  • 网站建设可上传视频的企业建设网站流程图
  • 深入Rust标准库(std):核心能力与实战指南
  • MySQL: MaxScale架构解析与高可用集群部署实战之插件架构·权限配置·读写分离·监控体系
  • 太月星网站建设程序开发简述网站建设的主要步骤
  • Diffusion Model VS TSDiff
  • 网站怎么制作成软件免备案域名
  • 爱用建站下载跨境电商平台有哪些前期费用
  • 利用社交网站做淘宝客酒店网站建设策划书
  • 45_FastMCP 2.x 中文文档之FastMCP集成:Azure (Entra ID) 认证指南