T-Flash卡热插拔案例分析
来源:互联网 发布:插画软件sai 编辑:程序博客网 时间:2024/05/22 00:39
转载时请注明出处和作者联系方式
文章出处:http://blog.csdn.net/Victor_1
作者联系方式:冰心明悦 <mingfucui at gmail dot com>
【摘要】
本文主要分析和讨论在智能手机中实现T-Flash卡热插拔的三种方法:单线热插拔、带检测信号线的四线热插拔和不带检测信号线的四线热插拔。其中单线热插拔,使用数据线3作为卡的检测口,数据线的传输宽度为1,此种方法简单、方便容易实现,但其速度受到限制。带检测信号线的四线热插拔方式,使用的是卡槽中的一个检测位来检测卡的存在与否,此种方法在实现热插拔的同时最大限度的提高了卡的读写速度,但其需要额外的机械装置和硬件支持。第三种方法,使用不带检测信号线的四线热插拔方法,综合考虑了第一种和第二种方法的优点,避免了其缺点,动态使用数据线3的卡检测功能和数据传输功能,使其综合性能达到最优。
一、问题的提出
现在的手机不仅仅满足其通话和短消息的功能,其娱乐性和可扩展性越来越多的受到人们的重视,例如:audio、video、gps和移动办公等等。在这种广大的需求面前同时对手机的性能提出了更高的要求,要求其处理速度要快,存储容量要大,安全性要好。对于存储容量的要求,最佳的方法就是使用外接的扩展卡,其中T-Flash卡是一种很好的选择,其成本较低,安全性好,同时可以通过读卡器和PC机交互,从而得到了很好的应用。但我们现有的智能手机,如***虽然支持T-Flash卡,但并不能满足其热插拔的要求,不方便用户使用。而其同类的产品,如moto系列、多普达系列等等都是支持T-Flash卡的热插拔功能,所以为了提高公司产品的竞争力,我们在今后的产品中必须添加T-Flash卡的热插拔功能。
二、解决思路
卡的插入和拔出是通过连接在检测位上GPIO的电平状态来通知系统的。系统根据其具体的状态来判别是插入还是拔出,然后通过设置标志位,调用系统脚本hotplug来实现卡的mount和umount操作,更新文件系统的状态,实现卡的热插拔操作。其处理流程如下图1所示:
1. 定义检测GPIO口,通过该位的状态来标识卡的插入或拔出操作。
2. 设置GPIO口开中断标志,设置上升沿和下降沿中断触发,其中上升沿触发表示插入操作,下降沿触发表示拔出操作。
3. 在系统中注册中断函数来具体响应中断过程。
4. 中断处理函数的实现,判断是否是有效中断和区别插入还是拔出,然后设置标志。其具体实现还要根据原来卡槽中的状态和当前卡槽中的状态来判定:(如下表所示)
原来
现在
无卡
0
有卡
1
无卡
0
无卡
00
拔出
10
有卡
1
插入
01
有卡
11
原来卡槽的状态通过记录标识符而产生,每次插入或者拔出时进行改变;现在是否有卡通过GPIO检测位的电平状态产生,然后通过原来状态和当前状态的组合,来判断是卡的插入还是拔出,或者无变化。
5. 调用hotplug系统脚本,来具体实现看的mount和umount操作,实现卡的插入和拔出操作。
三、实践情况
首先定义热插拔的处理模块,如下图2所示,其中注册中断函数是在设备初始化的时候进行注册;然后分别介绍三种在现有平台上实现T-Flash卡的热插拔操作的具体处理流程:
1. 单线热插拔模式:使用T-Flash卡的Data3引脚来检测卡的状态,此时Data3为通用GPIO口,用来产生中断,告知系统卡的状态,数据传输的宽度为1位。如图3所示
2. 带检测信号线的四线热插拔模式:即另外配置一个检测中断位,来代替方法1的Data3功能。这个中断位一般是安装在卡槽上的机械装置,同样系统要根据该位的状态来确定是否有卡的插入和拔出操作。此种情况的数据宽度可以为4位。如图4所示
3. 不带检测信号线的四线热插拔模式:即动态使用Data3的检测功能和数据传输功能。其基本思路是,当没有命令传输时将Data3设置为通用检测gpio口,此时在等待检测热插拔;当有命令传输时将data3关闭检测功能作为数据线,传输数据。此种方法的数据宽度为4位。如图5所
四、效果评价
试验证明分时使用Data3的检测功能和数据传输功能,既可以实现热插拔的检测又可以满足其速度的要求,使手机的功能和性能都得到了满足。
五、推广建议
以往T-Flash卡的热插拔操作,要么使用方法一,单线热插拔,但其速度受到影响;要么使用方法二,速度虽然得到了保证,但其多了一个结构件,增加了硬件成本。使用文中介绍的第三种方法,在不影响速度和不增加成本的情况下,最大程度的满足了功能和性能的要求。这不仅仅在智能手机平台中得到很好的使用,其他平台也有其借鉴意义。最大限度的在满足功能和性能的要求下,用软件代替硬件,节约成本。
参考资料
1. Intel® PXA27x Processor Family Developer’s Manual January 2006
2. SanDisk Secure Digital Card Product Manual Version 1.9 Document No. 80-13-00169
December 2003
3. SD Memory Card Specification Version 1.0 March 2000
4. Moto A1200 代码
—— 完 ——
附录:部分实现代码
下面以linux的代码为例介绍其具体实现:
- 公共部分
a.设置检测GPIO口
#define GPIO_HOTPLUG_DETECT ***
b.开中断
set_GPIO_IRQ_edge(GPIO_HOTPLUG_DETECT, GPIO_FALLING_EDGE | GPIO_RISING_EDGE);
c.注册中断函数
retval = request_irq(GPIO_2_80_TO_IRQ(GPIO_HOTPLUG_DETECT), mstone_detect_int,
SA_INTERRUPT | SA_SAMPLE_RANDOM,
"MMC card detect", (void *)1);
if (retval) {
printk(KERN_ERR "MMC/SD: can't request MMC card detect IRQ/n");
bvd_mmc_slot_cleanup();
return -1;
}
d.中断处理函数的实现
static int mstone_mmc_slot_is_empty(int slot)
{
/* Check MSCRD for MMC card detection ([1], 3.2.2.7) */
#ifdef HOTPLUG_MMC
GPDR(GPIO_HOTPLUG_DETECT) &= ~GPIO_bit(GPIO_HOTPLUG_DETECT);
GAFR(GPIO_HOTPLUG_DETECT) &= 0x3FFFFFFF;//~(3<<((111%16)<<1));
udelay(50);
/* set it in, gpio func */
printk( (GPLR3 & 0x8000)!=0? "Card inserted/n": "Card empty/n");
mmc_not_inserted = ((GPLR3 & 0x8000)!=0)?0:1;
#endif
return mmc_not_inserted;
}
static void mstone_detect_handler(unsigned long data)
{
int empty;
DEBUG(2, "card detect handler/n");
empty = mstone_mmc_slot_is_empty(0);
if (slot_state == MMC_CARD_INSERTED && empty) {
DEBUG(3, "no card in slot/n");
mstone_mmc_slot_down();
mmc_eject(0);
} else if (slot_state == MMC_CARD_REMOVED && !empty) {
DEBUG(3, "found the card in slot/n");
mstone_mmc_slot_up();
mmc_insert(0);
}
}
static void mstone_detect_int(int irq, void *dev, struct pt_regs *regs)
{
DEBUG(2, "card detect IRQ/n");
mod_timer(&mstone_detection, jiffies + HZ);
}
e.调用hotplug脚本
static void run_sbin_hotplug(struct mmc_dev *dev, int id, int insert)
{
int i;
char *argv[3], *envp[8];
char media[64], slotnum[16];
if (!hotplug_path[0])
return;
DEBUG(0,": hotplug_path=%s id=%d insert=%d/n", hotplug_path, id, insert);
i = 0;
argv[i++] = hotplug_path;
argv[i++] = "mmc";
argv[i] = 0;
/* minimal command environment */
i = 0;
envp[i++] = "HOME=/";
envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
/* other stuff we want to pass to /sbin/hotplug */
sprintf(slotnum, "SLOT=%d", id );
if ( dev->slot[id].media_driver && dev->slot[id].media_driver->name )
sprintf(media, "MEDIA=%s", dev->slot[id].media_driver->name );
else
sprintf(media, "MEDIA=unknown");
envp[i++] = slotnum;
envp[i++] = media;
if (insert)
envp[i++] = "ACTION=add";
else
envp[i++] = "ACTION=remove";
envp[i] = 0;
call_usermodehelper (argv [0], argv, envp);
}
- 各自的具体实现
a. 方法一(单线热插拔)
(1) 初始化数据线的宽度,设置为1位,仅仅初始化数据线0
set_GPIO_mode(92 | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT); //Data0
(2) 同时要设置寄存器来确定是按照1位的数据宽度来传输数据的
mmc_simple_cmd(dev, SET_BUS_WIDTH, 0, RESPONSE_R1);
b. 方法二(带检测信号线的四线热插拔)
(1) 初始化4位数据线宽度
set_GPIO_mode(92 | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT); //Data0
set_GPIO_mode(109 | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT);//Data1
set_GPIO_mode(110 | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT);//Data2
set_GPIO_mode(111 | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT);//Data3
(2) 设置寄存器来确定是按照4位的数据宽度来传输数据的
mmc_simple_cmd(dev, SET_BUS_WIDTH, 2, RESPONSE_R1);
c. 方法三 (不带检测信号线的四线热插拔)
(1) 同方法二配置和初始化相同,唯一的不同在于检测位仍旧使用Data3
(2) 动态配置Data3的检测功能和数据传输功能
a) 函数static int mmc_has_valid_request( struct mmc_dev *dev )中
表示开中断,启动热插拔功能,单线传输
if ( !request ) {
bit_width_flag = 0;
GPDR(111) &= ~GPIO_bit(111);
GAFR(111) &= 0x3FFFFFFF;//~(3<<((111%16)<<1));
GRER3 |= 0x8000;
GFER3 |= 0x8000;
return 0;
}
表示关闭中断检测,四线传输数据
bit_width_flag = 1;
GRER3 &= 0x1FF7FFF;
GFER3 &= 0x1FF7FFF;
set_GPIO_mode(111 | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT);//for 4-bits
b) 函数static void mstone_detect_int(int irq, void *dev, struct pt_regs *regs)
中的修改,表示关闭中断,打开四线传输功能。
bit_width_flag = 1;
GRER3 &= 0x1FF7FFF;
GFER3 &= 0x1FF7FFF;
c) 添加数据宽度的记录标志bit_width_flag,并在函数
static int bvd_mmc_exec_command(struct mmc_request *request)中添加命令
if (bit_width_flag)
cmdat |= MMC_CMDAT_SD_4DAT;
- T-Flash卡热插拔案例分析
- T-flash卡
- 案例分析
- 案例分析
- 案例分析
- R语言t检验,秩和检验,fdr的案例分析
- flash应用:T-shirt制作
- 投票系统(Flash+ASP案例)
- Flash与ASP通信案例
- nand FLASH 驱动分析
- nand flash启动分析
- flash 性能分析工具
- Nand Flash驱动程序分析
- NAND FLASH 驱动分析
- nand flash驱动分析
- DA14580 --- flash分析
- nor flash函数分析
- H.264 can't kill flash ---------
- 大型Java Web系统选型问题探讨
- 在Fedora10下打开.rar文件的方法
- 使用ruby抓取页面内容后发送邮件
- Head First C# 中文版 图文皆译 第五章 封装 page189
- 每日IN语(2009-02-08)别为你自己和别人下定论
- T-Flash卡热插拔案例分析
- 例解 autoconf 和 automake 生成 Makefile 文件
- Lucene 2.4 + Highlighter 2.4 的分页+高亮显示代码例子
- I'm back
- 上海元宵赏灯地图
- ORACLE 常用第三方软件介绍
- 以色列厂商侵权CMMB传闻的背后故事
- oracle数据库开发中的问题纪录收藏
- Sql Server2005 Sql Server 身份验证模式登录失败