我们知道,三星Android手机将USB读卡器通过OTG线插入Micro USB插口后,插拔读卡器里的SD卡,文件管理器也能够识别卡的插拔;而很多手机的OTG连上USB读卡器也来插拔SD卡,会发现文件管理器无法加载SD卡。而将USB读卡器放到Windows上或者桌面Linux上,我们发现插拔读卡器里的SD卡也是有效的。

  究其原因是Android的用户空间或者内核空间没有处理好SCSI 的TUR(Test Unit Ready)命令

  由于项目需要,我实现了Android OTG支持读卡器里的SD卡插拔,需要修改的地方分为两部分,一部分是kernel,一部分是vold。

对于kernel部分:

当用户空间打开诸如/dev/block/sda的设备节点时,kernel会调用到kernel/fs/block_dev.c里的__blkdev_get()函数,该函数会向USB读卡器发送TUR命令来测试读卡器里的media是否已插入,如果插入返回1,否则是0,当Kernel发现media状态从1->0或者0->1转换时,就会设置bdev->bd_invalidated为true,这样到1185行:

if (bdev->bd_invalidated) {

if (!ret) {

rescan_partitions(disk, bdev);

} else if (ret == -ENOMEDIUM){

invalidate_partitions(disk, bdev);

}

}

该函数会重新无效或者扫描分区,但事实上无论你怎么插拔SD卡,这两个函数都没有执行完毕,关键原因是有一个打开计数没有清空,把上面函数改成如下的形式:

if (bdev->bd_invalidated) {

if (!ret) {

bdev->bd_part_count = 0;

rescan_partitions(disk, bdev);

} else if (ret == -ENOMEDIUM){

bdev->bd_part_count = 0;

invalidate_partitions(disk, bdev);

}

}

配合用户空间周期性打开/dev/block/sda设备节点,你再插拔SD卡就会发现,插入SD卡时,/dev/block/sda1设备节点会出现,拔除SD卡时,/dev/block/sda1设备节点消失。代码跳到1125行,将无效或者扫描分区前同样加上bdev->bd_part_count = 0,即解决了内核无法扫描读卡器SD卡插拔的问题。

对于vold部分:

在vold进程中需要加入周期性打开和关闭/dev/block/sda设备节点的轮训线程,才能使内核周期性向读卡器发送TUR命

令来检查读卡器中的SD卡是否存在,我们可以将该轮训线程放于DirectVolume.cpp中,示例函数如下:

我们的OTG U盘是挂载在/storage/UsbDriveA、/storage/UsbDriveB、/storage/UsbDriveC、/storage/UsbDriveD、

/storage/UsbDriveE、/storage/UsbDriveF目录下的。

同时需要在DirectVolume.cpp中加入其它几个函数,由于代码保护问题,在本文中就不粘贴代码了,有需要的人可以向我索取源代码。

增加的几个函数名如下:

int DirectVolume::adjustDiskPartNum(int diskNumParts, int pendingPartMap);

bool DirectVolume::isUsbDrive(const char *tag);

bool DirectVolume::isUsbDrive();

void DirectVolume::diskRemoved(int major, int minor);

void DirectVolume::diskRemoved();

Android OTG支持USB读卡器的更多相关文章

  1. Android OTG之USB转串口模块通讯

    微信公众号:CodingAndroid CSDN:http://blog.csdn.net/xinpengfei521 1.背景简介 我们公司开发了一款室内机平板APP应用,要求平板能去控制智能门锁. ...

  2. Android开启OTG功能/USB Host API功能

    Android USB 模式简介 设备模式 当计算机或其他USB主机需要连接安卓设备时,此时安卓设备是作为"USB设备"角色的,在计算机上显示为 USB 外设.现在的安卓设备已经被 ...

  3. android OTG【转】

    本文转载自:http://blog.csdn.net/xubin341719/article/details/7707056 一.OTG的概念 OTG是On-The-Go的缩写,是近年发展起来的技术, ...

  4. 【转】Android Service创建USB HOST通信

    之前做了一个关于Android USB通信的Case,通过Android的USB总线给Zigbee供电,和板载的Zigbee(基于Zigbee的自组网)进行通信.要使用Android的USB Host ...

  5. Android Service创建USB HOST通信

    之前做了一个关于Android USB通信的Case,通过Android的USB总线给Zigbee供电,和板载的Zigbee(基于Zigbee的自组网)进行通信.要使用Android的USB Host ...

  6. 如何让老Mac机支持USB安装Windows

    一些老Mac机的用户想装Windows,却发现自己的系统上的Boot Camp Assistant(以下简称BCA)没有USB安装Windows的选项. 下面以我的MacBook Pro (13-in ...

  7. 手机支持USB功能、驱动文件对应关系

    手机支持USB功能: 1.UMS(USB MASS Stronge) : 连接PC作为存储盘使用 2.ADB : 用于调试 3.MTP :连接PC作为存储盘使用(win XP需要安装WMP10 以上 ...

  8. Android 自定义支持快速搜索筛选的选择控件(一)

    Android 自定义支持快速搜索筛选的选择控件 项目中遇到选择控件选项过多,需要快速查找匹配的情况. 做了简单的Demo,效果图如下: 源码地址:https://github.com/whieenz ...

  9. Android recovery支持adb shell

    Android recovery支持adb shell 近期开发过程注意到recovery不支持adb shell.为了便于调试方便,决定添加此功能. 刚開始我们採用的是user版本号系统,进入rec ...

随机推荐

  1. 本地缓存下载文件,download的二次封装

    来源:http://ask.dcloud.net.cn/article/524 源码下载链接 说明: (1)由于平时项目中大量用到了附件下载等功能,所以就花了一个时间,把plus的downlaod进行 ...

  2. GestureDetector类及其用法

    转载子:http://www.cnblogs.com/rayray/p/3422734.html 项目中有需求:针对一个imageview,点击需要查看大图,左右滑动能执行翻页. 自己对手势这一块并不 ...

  3. Acitivity间数据的传递

    使用startActivityForResult方法进行数据传递.    MainActivity.java: public class MainActivity extends Activity { ...

  4. Oracle、DB2、SQLSERVER、Mysql、Access分页SQL语句梳理

    最近把平时在项目中常用到的数据库分页sql总结了下.大家可以贴出分页更高效的sql语句.sqlserver分页 第一种分页方法 需用到的参数: pageSize 每页显示多少条数据 pageNumbe ...

  5. IOS之swift第一课基础代码

    import Foundation //import Foundation 导入模块,专业术语也是导入 包,库的 意思. var str = "Hello World" //声明一 ...

  6. C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是TAP(Task-based Asynchronous Pattern, 基于任务的异步模式)

    学习书籍: <C#本质论> 1--C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是 ...

  7. mybatis关联查询

    场景:一个人有多个手机号,一个手机号对应一个人 CREATE TABLE test.mobile ( mid INT NOT NULL auto_increment, tel ), pid INT, ...

  8. 基于SMB共享文件夹的上传于下载

    需要用到的jar包   http://pan.baidu.com/s/1skQFk77 1.首先在一台电脑上设置共享文件夹 ----上传下载的方法类 package com.strongit.tool ...

  9. 【nodemailer】 初试

    nodemailer 是什么? 简单的讲nodemailer就是用来发送邮件的.最近的一个项目需要向客户的注册邮箱发送验证连接,研究了一下. 刚开始我以为nodemailer还可以用来接收邮件,看了好 ...

  10. 最近用到的Linux常用命令总结

    最近用到的Linux常用命令总结 - ls :显示当前目录文件信息 `ls -a -l` - cd :目录跳转 cd .. 上级目录 cd ~ home目录 cd - 最近目录 - cat :在屏幕上 ...