[sd card] mmc硬件总线扫描流程(以sd card为例)

本文详细介绍了mmc硬件总线扫描的过程,包括何时扫描总线以及如何扫描。以sd card为例,讨论了获取卡插入状态的方法,如通过GPIO和host寄存器。同时,文章阐述了sd card热插拔的中断监控和轮询监控两种实现方式,解析了相关中断处理和轮询机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、扫描mmc硬件总线

扫描mmc硬件总线,也就是检测mmc硬件总线上是否有挂载card。更加通俗的,就是卡槽上是否有插入card。

1、扫描mmc硬件总线的时机

mmc core在如下情况下会去扫描mmc硬件总线:

  • 启动一个host的时候而调用mmc_detect_change
    当启动一个host的时候,并不知道当前是否有card插入,此时需要调用mmc_detect_change来假设card插入状态发生了变化,
    并且进行第一次扫描mmc硬件总线。
    代码如下,过滤掉无关代码:
void mmc_start_host(struct mmc_host *host)
{
        //...
    mmc_detect_change(host, 0);
}
  • 底层硬件发现card插入状态发生变化而调用mmc_detect_change的时候(sd card插入状态监控)
    当底层硬件发现card插入状态发生变化,例如sd card的插入或者拔出可以触发某个GPIO产生中断。
    此时,可以在中断处理中调用mmc_detect_change来进行扫描mmc硬件总线,并且根据总线上的card状态变化进行处理。
    这种情况的主要目的是为了实现sd card的热插拔。
    代码如下,过滤掉无关代码:
static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
{
    status = mmc_gpio_get_status(host);   // 先获取card的插入状态
    if (unlikely(status < 0))
        goto out;

    if (status ^ ctx->status) {   // 与之前的card的状态进行比较,不一样则说明mmc硬件总线上的card发生了插入或者拔出事件
        ctx->status = status;
        /* Schedule a card detection after a debounce timeout */
        mmc_detect_change(host, msecs_to_jiffies(200));
                // 调用mmc_detect_change对card的插入状态变化进行处理
                // 注意,这里延时了200ms是用来进行消抖
    }
out:
    return IRQ_HANDLED;
}
  • host要求轮询sd card插入状态的情况下,所进行的轮询操作(sd card插入状态监控)
    一般来说,在host无法根据硬件来及时获取card插入状态发生变化的情况下,会要求mmc_core每隔一段时间(一般是HZ,一秒)扫描一次mmc硬件总线。
    在这种情况下,mmc_host的MMC_CAP_NEEDS_POLL属性会被设置。
    这种情况的主要目的也是为了实现sd card的热插拔。
    代码如下,过滤掉无关代码:
void mmc_rescan(struct work_struct *work)
{
    if (host->caps & MMC_CAP_NEEDS_POLL)
        mmc_schedule_delayed_work(&host->detect, HZ);
        // 这里先说明下
        // 在《host模块说明》已经知道了在mmc_alloc_host中默认将host->detect工作设置为mmc_rescan(card扫描)函数, 
        // INIT_DELAYED_WORK(&host->detect, mmc_rescan)
        // 这样,通过mmc_schedule_delayed_work(&host->detect, HZ)就会每隔HZ时间就会执行一次mmc_rescan
}

2、如何扫描mmc硬件总线

从上述,我们知道了可以通过调用mmc_detect_change和执行host->detect工作来发起mmc硬件总线的扫描。
而mmc_detect_change最终也是执行mmc_host->detect工作来发起mmc硬件总线扫描的。
下面来看一下这两个函数

  • mmc_detect_change
    代码如下:
void mmc_detect_change(struct mmc_host *host, unsigned long delay)
{
    host->detect_change = 1;    // 设置mmc_host->detect_change,表示检测到card状态发生了变化
    mmc_schedule_delayed_work(&host->detect, delay);
        // 间隔delay时间之后,执行工作host->detect
        // 这个delay时间用于消抖
}

可以发现,mmc_detect_change最终也是执行mmc_host->detect工作来发起mmc硬件总线扫描的。

  • mmc_host->detect
    通过前面的说明,可以知道mmc_host->detect才是发起mmc硬件总线扫描的工作的。
    那么,这个东西是在哪里被设置又是被设置成什么的呢?这个其实在《[mmc subsystem] mmc core(第四章)——host模块说明》中已经说明过了。
    代码如下,去掉无关代码:
struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
{
        //...
    INIT_DELAYED_WORK(&host->detect, mmc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值