、协议流程
1、整体框图

2、框图描述
从上图可以看出:
(1)设备上电或者设备接收到参数为0的CMD0命令,便会进入idle状态
(2)当设备进入idle状态后,通过CMD1(SEND_OP_COND)命令来判断设备是否处于忙状态,而且可以获取到OCR寄存器的值,即可以获取到emmc支持的电压范围,和控制进行比较,判断是否有匹配的电压

CMD1需要重复发送直到返回不忙状态,设备进入ready状态
(3)进入ready状态后,发送广播命令CMD2(ALL_SEND_CID),该命令请求所有设备发送其唯一设备标识(CID)号,所有
未识别的(即处于Ready状态的)设备同时开始串行地发送其CID号,成功后设备进入Identification状态

(4)主机发送CMD3(SET_RELATIVE_ADDR),给改设备一个相对设备地址(RCA),该地址用于数据传输模式,设备一旦接收到RCA,设备就变为Stand-by状态。设备将其输出驱动器从开漏切换到推拉模式。
RCA寄存器模式是0x0001

二、裸驱配置流程
1、SRS11.SRFA ( Software Reset For All) 复位整个芯片,循环等待该bit为0,为0代表复位成功
2、SRS10.BP=1 SRS10.BVS=101(1.8V)
3、SRS13 使能或者SRS14关闭各种中断
4、phy初始化
5、SRS10.EDTW=0 SRS10.DTW=0 配置位宽为1bit
6、SRS11.SDCFSL=(200M/400KHz)配置clk为400Hz
7、开始发送CMD0,延时2ms
8、发送CMD1,根据应答判断OCR的bit31是否busy,1代表空闲,0代表忙,如果忙,再次发送,连续尝试3次
9、发送CMD2,根据应答获取到CID
10、发送CMD3,分配一个rca值,根据应答获取到rca

三、linux的流程

drivers/mmc/host/sdhci-xxxx.c
sdhci_add_host__sdhci_add_hosthost->complete_wq = alloc_workqueue("sdhci", flags, 0); timer_setup(&host->timer, sdhci_timeout_timer, 0);timer_setup(&host->data_timer, sdhci_timeout_data_timer, 0);sdhci_init(host, 0);sdhci_do_reset(host, SDHCI_RESET_ALL);sdhci_set_default_irqs(host);ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq,IRQF_SHARED,>mmc_hostname(mmc), host);ret = mmc_add_host(mmc);err = device_add(&host->class_dev);mmc_start_host(host);mmc_gpiod_request_cd_irq(host)_mmc_detect_change(host, 0, false);host->detect_change = 1;mmc_schedule_delayed_work(&host->detect, delay); // 触发mmc_rescan
driver/mmc/core/core.c
subsys_initcall(mmc_init);__init mmc_init(void) ret = mmc_register_bus();bus_register(&mmc_bus_type);ret = mmc_register_host_class();class_register(&mmc_host_class);ret = sdio_register_bus(); bus_register(&sdio_bus_type); drivers/mmc/core/host.c
drivers/mmc/host/mmci.c
module_amba_driver(mmci_driver);
#define module_amba_driver(__amba_drv) \module_driver(__amba_drv, amba_driver_register, amba_driver_unregister) static struct amba_driver mmci_driver = {....probe = mmci_probe,...
}static struct mmc_host_ops mmci_ops = {.request   = mmci_request,.pre_req    = mmci_pre_request,.post_req   = mmci_post_request,.set_ios   = mmci_set_ios,.get_ro     = mmc_gpio_get_ro,.get_cd      = mmci_get_cd,.start_signal_voltage_switch = mmci_sig_volt_switch,
};mmci_probemmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev);ret = mmci_of_parse(np, mmc);  alias_id = of_alias_get_id(dev->of_node, "mmc");dev_set_name(&host->class_dev, "mmc%d", host->index); INIT_DELAYED_WORK(&host->detect, mmc_rescan);INIT_DELAYED_WORK(&host->sdio_irq_work, sdio_irq_work);timer_setup(&host->retune_timer, mmc_retune_timer, 0);host->mmc_ops = &mmci_ops;mmc->ops = &mmci_ops;host->clk = devm_clk_get(&dev->dev, NULL);ret = clk_prepare_enable(host->clk);host->mclk = clk_get_rate(host->clk)host->base = devm_ioremap_resource(&dev->dev, &dev->res);host->rst = devm_reset_control_get_optional_exclusive(&dev->dev, NULL);ret = mmc_regulator_get_supply(mmc);ret = devm_request_threaded_irq(&dev->dev, dev->irq[0], mmci_irq,mmci_irq_thread, IRQF_SHARED,DRIVER_NAME " (cmd)", host);mmci_dma_setup(host);mmc_add_host(mmc);
mmc_rescan // 在sdhci_add_host中被触发if (!mmc_card_is_removable(host) && host->rescan_entered) returnif (mmc_card_is_removable(host) && host->ops->get_cd &&  host->ops->get_cd(host) == 0) {mmc_power_off(host);mmc_release_host(host); }for (i = 0; i < ARRAY_SIZE(freqs); i++) {unsigned int freq = freqs[i];if (freq > host->f_max) {if (i + 1 < ARRAY_SIZE(freqs))continue;freq = host->f_max;}if (!mmc_rescan_try_freq(host, max(freq, host->f_min)))break;if (freqs[i] <= host->f_min)break;}mmc_release_host(host);if (!(host->caps2 & MMC_CAP2_NO_SD)) mmc_send_if_cond(host, host->ocr_avail);
static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
{host->f_init = freq;mmc_power_up(host, host->ocr_avail);mmc_pwrseq_pre_power_on(host); mmc_delay(host->ios.power_delay_ms);mmc_pwrseq_post_power_on(host);host->ios.power_mode = MMC_POWER_ON;mmc_set_ios(host);mmc_delay(host->ios.power_delay_ms); // This delay must be at least 74 clock sizes, or 1 ms,mmc_hw_reset_for_init(host);mmc_pwrseq_reset(host);if (!(host->caps2 & MMC_CAP2_NO_SDIO))sdio_reset(host);mmc_go_idle(host);cmd.opcode = MMC_GO_IDLE_STATE;cmd.arg = 0err = mmc_wait_for_cmd(host, &cmd, 0)if (!(host->caps2 & MMC_CAP2_NO_SD))mmc_send_if_cond(host, host->ocr_avail);cmd.opcode = SD_SEND_IF_COND; cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern;err = mmc_wait_for_cmd(host, &cmd, 0);result_pattern = cmd.resp[0] & 0xFF;/* Order's important: probe SDIO, then SD, then MMC */if (!(host->caps2 & MMC_CAP2_NO_SDIO))if (!mmc_attach_sdio(host))return 0;if (!(host->caps2 & MMC_CAP2_NO_SD))if (!mmc_attach_sd(host))return 0;if (!(host->caps2 & MMC_CAP2_NO_MMC))if (!mmc_attach_mmc(host)) // 见下return 0;mmc_power_off(host);return -EIO;
}
static const struct mmc_bus_ops mmc_ops = {.remove = mmc_remove,.detect = mmc_detect,.suspend = mmc_suspend,.resume = mmc_resume,.runtime_suspend = mmc_runtime_suspend,.runtime_resume = mmc_runtime_resume,.alive = mmc_alive,.shutdown = mmc_shutdown,.hw_reset = _mmc_hw_reset,
};mmc_attach_mmcmmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN); host->ios.bus_mode = mode;mmc_set_ios(host);err = mmc_send_op_cond(host, 0, &ocr);cmd.opcode = MMC_SEND_OP_COND;cmd.arg = mmc_host_is_spi(host) ? 0 : ocr; for (i = 100; i; i--) {err = mmc_wait_for_cmd(host, &cmd, 0); if (cmd.resp[0] & MMC_CARD_BUSY)break; mmc_delay(10); // mscmd.arg = cmd.resp[0] | BIT(30);}*rocr = cmd.resp[0];mmc_attach_bus(host, &mmc_ops);host->bus_ops = ops;rocr = mmc_select_voltage(host, ocr);err = mmc_init_card(host, rocr, NULL); mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN); mmc_go_idle(host);err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr);err = mmc_send_cid(host, cid);card = mmc_alloc_card(host, &mmc_type);card->ocr = ocr;card->type = MMC_TYPE_MMC;card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); err = mmc_set_relative_addr(card);cmd.opcode = MMC_SET_RELATIVE_ADDR;cmd.arg = card->rca << 16; mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES)mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);err = mmc_send_csd(card, card->raw_csd);mmc_send_cxd_native(card->host, card->rca << 16,>csd,MMC_SEND_CSD);err = mmc_decode_csd(card);err = mmc_decode_cid(card); err = mmc_select_card(card);_mmc_select_card(card->host, card);cmd.opcode = MMC_SELECT_CARD;cmd.arg = card->rca << 16; mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES)err = mmc_read_ext_csd(card);err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_ERASE_GROUP_DEF, 1,card->ext_csd.generic_cmd6_time); err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG,   card->ext_csd.part_config, card->ext_csd.part_time);err = mmc_select_timing(card);if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES)err = mmc_select_hs400es(card);err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180)err = mmc_select_bus_width(card); err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS,card->ext_csd.generic_cmd6_time, 0,false, true); mmc_set_timing(host, MMC_TIMING_MMC_HS);err = mmc_switch_status(card, true);mmc_set_clock(host, card->ext_csd.hs_max_dtr);val = EXT_CSD_DDR_BUS_WIDTH_8 | EXT_CSD_BUS_WIDTH_STROBE;err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,EXT_CSD_BUS_WIDTH,val,card->ext_csd.generic_cmd6_time);mmc_select_driver_type(card);val = EXT_CSD_TIMING_HS400 | card->drive_strength << EXT_CSD_DRV_STR_SHIFT;err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, val,card->ext_csd.generic_cmd6_time, 0, false, true);mmc_set_timing(host, MMC_TIMING_MMC_HS400);err = mmc_switch_status(card, true);else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)err = mmc_select_hs200(card);mmc_select_driver_type(card);err = mmc_select_bus_width(card);val = EXT_CSD_TIMING_HS200 | card->drive_strength << EXT_CSD_DRV_STR_SHIFT;err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,EXT_CSD_HS_TIMING, val,card->ext_csd.generic_cmd6_time, 0,false, true);mmc_set_timing(host, MMC_TIMING_MMC_HS200);err = mmc_switch_status(card, false);else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS)err = mmc_select_hs(card);err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS,card->ext_csd.generic_cmd6_time, MMC_TIMING_MMC_HS,true, true); if (mmc_card_hs200(card)) {  // card->host->ios.timing == MMC_TIMING_MMC_HS200;err = mmc_hs200_tuning(card);err = host->ops->execute_tuning(host, opcode);err = mmc_select_hs400(card);} else if (!mmc_card_hs400es(card)) {  // card->host->ios.enhanced_strobe;err = mmc_select_bus_width(card); if (err > 0 && mmc_card_hs(card)) { // card->host->ios.timing == MMC_TIMING_SD_HS || card->host->ios.timing == MMC_TIMING_MMC_HS;err = mmc_select_hs_ddr(card);bus_width = host->ios.bus_width;ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4;err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,ext_csd_bits,card->ext_csd.generic_cmd6_time,MMC_TIMING_MMC_DDR52,true, true);err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);}if (card->ext_csd.cmdq_support && host->caps2 & MMC_CAP2_CQE) { err = mmc_cmdq_enable(card);mmc_cmdq_switch(card, true);}mmc_release_host(host);err = mmc_add_card(host->card);mmc_claim_host(host);

05-emmc的识别模式相关推荐

  1. ABBYY软件的PDF识别模式有什么作用

    在使用ABBYY FineReader PDF 15进行OCR文字识别之前,要想快速获得准确的识别效果,需要根据要识别的文件类型以及复杂度,在"设置"里对OCR选项进行设置. 点击 ...

  2. 图片旋转对于识别模式带来的变化

    简 介: 测试了七段数字图片段角度对于识别的影响.可以看到对于6,9两个数字,在旋转过程中他们之间会相互转换.2,5在旋转180°之后,它们与自己相同,会出现两个识别相同.0,8与其他数字自检有着比较 ...

  3. emmc linux 识别分区_EMMC芯片电视主板直写厂家引导程序

    如今智能电视在市场上非常普遍,电视主板维修经常会涉及到数据抄写.使用RT809H编程器可以方便的读取正常机数据进行数据备份或制作量产,写入备份数据或量产数据简单的操作就可以修复机器.但有时遇到没有备份 ...

  4. emmc linux 识别分区_linux下给U盘分区并制作文件系统

    初探 不同于Ubuntu/Win等桌面发行版本,服务器型(非图形化系统)的linux系统通常不主动挂载U盘,因此当U盘插入后是不会有任何提示的,那我们如何知道U盘是否被系统所识别呢? 那就只能查看系统 ...

  5. Java设计模式圣经连载(05)-代理模式

    代理模式是一种非常重要的设计模式,在Java语言中有着广泛的应用,包括Spring AOP的核心设计思想,都和代理模式有密切关系. 代理模式主要分两种:一种是静态代理,一种是动态代理.两种代理方式的实 ...

  6. 05《软件需求模式》阅读笔记

    剩下的两个阅读笔记写第二部分.各类需求模式,共八个领域和它的需求模式,这一次写前四个. 基础需求模式,它是所有种类的系统都可能需要的一些东西.系统间接口需求模式使用系统间接口需求模式定义被定义的系统和 ...

  7. data spring 指定时区_Spring 框架基础(05):Mvc架构模式,执行流程详解

    本文源码:GitHub || GitEE 一.SpringMvc框架简介 1.Mvc设计理念 MVC是一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码,将业务逻辑聚集到一个组件里面, ...

  8. 【设计模式 05】工厂方法模式

    工厂方法模式 define an interface or abstract class for creating an object but let the subclasses decide wh ...

  9. 05设计模式——抽象工厂模式

    前言:以下总结来自龙哥---左潇龙博客. 总结的很到位,附上博客链接:http://www.cnblogs.com/zuoxiaolong/p/pattern6.html 抽象工厂模式算是工厂相关模式 ...

最新文章

  1. android 程序类图,Android模板设计模式之 - 构建整个应用的BaseActivity
  2. Unity4.6.2发布 支持64位iOS
  3. hibernate.cfg.xml hibernate 配置文件模板
  4. Effective Java之优先使用标准的异常(六十)
  5. C++的常量折叠(一)
  6. 20165326 java第四周学习笔记
  7. 信息学奥赛C++语言:十位能被个位和百位之和整除
  8. hadoop 之NullWritable与ObjectWritable
  9. ajax 刷新 保持原位置_JavaEE之Ajax第一课
  10. 嵌入式系统功能概要设计说明_嵌入式软件架构设计实际该怎么做?
  11. linux shell 之 crontab(定时任务)详解
  12. Could not initialize English chunker/Could not load file from classpath: ‘/en-token.bin‘
  13. SAP-MM-代码大全
  14. Fastjson 远程命令执⾏漏洞
  15. Python乌龟吃鱼小游戏
  16. java.awt.eventdispatchthread_大神们,小弟来了!解决办法
  17. 企业邮箱怎么写加密邮件,企业邮箱支持吗?
  18. (二)苏世民:我的经验和教训:追梦(12)
  19. visio2010 去除跨线
  20. /etc/profile和 . profile 文件

热门文章

  1. mysql 身份证 性别_mysql根据身份证查询年龄,地址,性别
  2. emmc挂载,分区及格式化
  3. 模拟系列(二)——模拟闪电
  4. 有1分,2分,5分,10分四种硬币,每种硬币数量无限,给定n分钱,求有多少种组合可以组合成n分钱?
  5. 超码、主码、候选码的概念与区分
  6. 【小程序开发之个人档案功能的实现】如何获取输入框输入值以及如何更新数据库
  7. ubuntu 如何获得管理员权限
  8. 理想国Elasticsearch入门教程
  9. tensorflow2.x向下兼容1.x命令
  10. MouseWithoutBorders 无界鼠标