飞思卡尔开发板留有可插拨的SD卡卡槽,BSP包中提供了热插拨的检测机制。在sdhci_probe_slot函数中,gpio_sdhc_active函数初始化SD卡相关的GPIO口,包括SD卡检测脚的初始化。下面的程序实现SD卡检测中断号的申请,以及中断的触发方式:

host->detect_irq = platform_get_irq(pdev, 1);//申请卡检测中断号

if (!host->detect_irq)

{

host->flags &= ~SDHCI_CD_PRESENT;

if ((pdev->id >= 0) && (pdev->id < MXC_SDHCI_NUM))

mxc_fix_chips[pdev->id] = chip;

goto no_detect_irq;

}

do

{

ret = host->plat_data->status(host->mmc->parent);//获取SD卡的存在状态

if (ret)//根据当前SD卡存在状态设置卡检测中断触发类型

set_irq_type(host->detect_irq, IRQF_TRIGGER_FALLING);

else

set_irq_type(host->detect_irq, IRQF_TRIGGER_RISING);

} while (ret != host->plat_data->status(host->mmc->parent));

ret = host->plat_data->status(host->mmc->parent);

程序首先使用platform_get_irq函数申请一个中断号,然后读取SD卡的存在状态,如果SD卡不在卡槽内,则设置为下降沿触发,反之则设置为上升沿触发。这一点需要与硬件接口对应起来,开发板的SD卡硬件电路如下图所示:

SD1_DET脚即为SD卡检测脚,在没有卡存在的情况下,该脚被硬件上拉为高电平,插入卡后,该脚被卡槽直连到地。因此,在没有卡存在时,需要设置为下降沿触发,反之设置为上升沿触发。其实如果CPU支持双边沿触发,可以设置为双边沿触发,然后在中断处理函数中通过检测脚的电平判断是插入还是拨出。

紧接着程序通过下面的函数初始化自旋锁:

spin_lock_init(&host->lock);

使用INIT_WORK函数初始化卡检测函数的工作队列:

INIT_WORK(&host->cd_wq, esdhc_cd_callback);

使用request_irq函数申请卡检测中断:

if (host->detect_irq)//lqm changed

{

ret = request_irq(host->detect_irq, sdhci_cd_irq, 0,pdev->name, host);//响应检测SD卡中断

if (ret)//失败

goto out4;

}

sdhci_cd_irq函数为中断顶半部:

static irqreturn_t sdhci_cd_irq(int irq, void *dev_id)

{

struct sdhci_host *host = dev_id;

schedule_work(&host->cd_wq);

return IRQ_HANDLED;

}

当卡检测中断产生后,中断顶半部调用schedule_work函数调度工作队列执行。这里的传入参数host->cd_wq和前面工作队列初始化的第一个传入参数必须一致。工作队列初始化的第二个参数esdhc_cd_callback为卡检测中断的底半部,产生中断后需要做的工作全在这个函数里面。schedule_work执行后该函数马上会执行:

static void esdhc_cd_callback(struct work_struct *work)

{

unsigned long flags;

unsigned int cd_status = 0;

struct sdhci_host *host = container_of(work, struct sdhci_host, cd_wq);

do

{

if (host->detect_irq == 0)

break;

cd_status = host->plat_data->status(host->mmc->parent);//读取SD卡状态

if (cd_status)//如果卡槽内没有卡,则设置为下降沿触发,否则为上升沿触发

set_irq_type(host->detect_irq, IRQF_TRIGGER_FALLING);

else

set_irq_type(host->detect_irq, IRQF_TRIGGER_RISING);

} while (cd_status != host->plat_data->status(host->mmc->parent));

cd_status = host->plat_data->status(host->mmc->parent);//获得卡状态

printk(KERN_INFO"cd_status=%d %s/n",cd_status, cd_status ? "removed" : "inserted");//lqm added.

/* If there is no card, call the card detection func immediately. */

if (!cd_status) // 当没卡时插入卡,开启定时器

{

if (host->flags & SDHCI_CD_TIMEOUT)

host->flags &= ~SDHCI_CD_TIMEOUT;

else

{

mod_timer(&host->cd_timer, jiffies + HZ / 4);

return;

}

}

cd_status = host->plat_data->status(host->mmc->parent);

if (cd_status)//cd_status=1表示没有卡

host->flags &= ~SDHCI_CD_PRESENT;

else

host->flags |= SDHCI_CD_PRESENT;

/* Detect there is a card in slot or not */

spin_lock_irqsave(&host->lock, flags);//自旋锁第三步:获得自旋锁,保护临界区

if (!(host->flags & SDHCI_CD_PRESENT)) //当卡拨出时执行下面程序

{

printk(KERN_INFO"%s: Card removed and resetting controller./n",mmc_hostname(host->mmc));

if (host->mrq)

{

struct mmc_data *data;

data = host->data;

host->data = NULL;

printk(KERN_ERR"%s: Card removed during transfer!/n",mmc_hostname(host->mmc));

printk(KERN_ERR"%s: Resetting controller./n",mmc_hostname(host->mmc));

if ((host->flags & SDHCI_USE_EXTERNAL_DMA) && (data != NULL))

{

dma_unmap_sg(mmc_dev(host->mmc), data->sg,

host->dma_len, host->dma_dir);

host->dma_size = 0;

}

sdhci_reset(host, SDHCI_RESET_CMD);

sdhci_reset(host, SDHCI_RESET_DATA);

host->mrq->cmd->error = -ENOMEDIUM;

tasklet_schedule(&host->finish_tasklet);

}

if (host->init_flag > 0)

host->init_flag--;

else

sdhci_init(host);

}

spin_unlock_irqrestore(&host->lock, flags);//自旋锁第四步:解锁

if (host->flags & SDHCI_CD_PRESENT)

{

printk(KERN_ERR"SDHCI_CD_PRESENT.../n");// lqm added.

del_timer(&host->cd_timer);

mmc_detect_change(host->mmc, msecs_to_jiffies(100));// lqm masked for test.

}

else

{

printk(KERN_ERR"no SDHCI_CD_PRESENT.../n");

mmc_detect_change(host->mmc, 0);

}

}

由于卡状态发生了改变,因此函数的第一步即先读取卡状态,根据不同的状态设置对应的卡中断方式。如果是卡插入造成的中断,则打开定时器,进而执行卡挂载等操作,如果是卡拨出造成的中断,则复位SD卡模块。注意在卡拨出执行的代码段添加了自旋锁,正因为它,前面才使用了spin_lock_init函数初始化自旋锁。

MX25上SD卡的插拨检测机制相关推荐

  1. SD卡结构、检测方式

    SD卡检测方式 方法之一,使用DAT3(pin1)作为卡在位检测信号:DAT3在sd 卡内部有90k的上拉电阻.Host与sd card之间对DAT3做外部下拉.这样卡没插入时host读DAT为低,卡 ...

  2. sd卡linux错误检测,android系统正在准备SD卡正在检测是否有错误且SD卡无法读取解决办法...

    手机android系统,也许您会碰到这样的情况. 错误提示:正在准备SD卡 正在检测是否有错误.这时sd卡(即内存卡)不能正常使用,不管手机自带的程序,还是通过usb口连接到电脑都无法识别sd卡. 这 ...

  3. 索尼android sd卡上,SD卡各个文件夹功能详解 入手必看经验!!!!

    对于初次使用Android系统的新手来说,当打开SD开一看,里面那些林林总总的文件夹总会让自己不知所措,有些看文件夹名称,还能猜到点作用来,但是大部分的都不知道是做什么的 1..android_sec ...

  4. 读卡器(8年前的)插上SD卡提示未插入修复教程,仅适用于放置较久的读卡器。

    前提:SD能够正常使用 1.插入SD卡的读卡器,在电脑中弹出如下提示: 2.此时排除了SD损坏的原因,直接对读卡器下手了,拆解图如下,构造还是比较简单的. 3.由于放置时间较长可能是电路板上发生了氧化 ...

  5. 三星android sd卡,神乎其技:大神让三星S7 Edge同时用上SD卡和双SIM卡

    IT之家讯 3月22日消息 三星在今年的S7/S7 Edge手机上增加了支持microSD卡扩展的功能,对于那些手机重度用户而言无疑是一项福音,不过三星S7的microSD卡功能有个尴尬的地方,就是和 ...

  6. cube sdio fatfs 初始化sd卡_SD卡读卡器检测——硬盘检测软件Hard Disk Sentinel Pro介绍

    在本教程中,将介绍如何使用硬盘检测软件Hard Disk Sentinel Pro查看相应的行业标准(微型)SD卡,USB设备的完整状态. 尽管大多数SD / microSD卡不提供状态信息,并且只能 ...

  7. SD卡与SD卡座电路以及TF卡(Micro SD Card,原名Trans-flash Card(TF卡))插拔式卡座和自弹出的卡座的引脚定义详细

    Micro SD Card,原名Trans-flash Card(TF卡),2004年正式更名为Micro SD Card,由SanDisk(闪迪)公司发明,主要用于移动电话. 在Micro SD面市 ...

  8. 苹果电脑更改sd卡只读_SD卡变为只读系统

    2.使用用fsck – y 来修复文件系统 转自:http://blog.chinaunix.net/uid-20753645-id-1877931.html 问题: 将上述这些存储设备插入USB端口 ...

  9. android u盘自动挂载点,Android2.3实现SD卡与U盘自动挂载的方法

    本文实例讲述了Android2.3实现SD卡与U盘自动挂载的方法.分享给大家供大家参考,具体如下: 在 s3c6410平台上移植android2.3 过程中SD卡总是不能自动挂载. 查阅相关资料,知道 ...

最新文章

  1. GIt本地相关操作(一)
  2. Java中JRE、JDK和JVM的区别
  3. Angularjs 开始之Hello world
  4. java中elements_Java中的提供程序elements()方法
  5. 内部简单二进制编码(SBE)
  6. 将字符串中的字符按Z字形排列,按行输出
  7. mysql Innodb参数配置
  8. Bokeh 使用Basic Glyphs做图
  9. android library使用,Android:Library module的使用
  10. 20200217:下一个排列(leetcode31)
  11. ubuntu-16.04安装程序报错 you might want to run 'apt-get -f install' to correct these
  12. oracle xtts 测试,XTTS 跨平台表空间迁移测试
  13. TensorFlow 训练单特征和多特征的线性回归
  14. TransposonPSI——转座子分析的入门自学
  15. 【情感分析】基于Aspect的情感分析模型总结(PART IV)
  16. VMware vSphere 5.x 与 vSphere 6.0各版本功能特性对比
  17. NMDS非度量多维尺度分析
  18. centos 7.6安装WeADMIN ITOSS步骤
  19. 守望先锋地图英文和英雄英文
  20. Flexsim Rack设置最底层Level不放货物

热门文章

  1. Oracle中 Alter Table 语句的使用
  2. switch组件设置大小
  3. 什么是解析解和数值解?
  4. Myeclipse之回退版本
  5. echarts学习笔记1
  6. 一个10年符号主义学者的深度讨论:如何理性看待ChatGPT?
  7. select函数何时返回?
  8. 【CSDN下载】下载热门资源一周精选
  9. 【青少年编程】【三级】接苹果
  10. VPN的搭建与使用--CentOS7.9(OpenVpn环境配置)