作者:gzshun. 原创作品,转载请标明出处!
来源:http://blog.csdn.net/gzshun
OTG是on-the-go的简称,是2001年由USB Implementers Forum公布,主要应用于各种不同的设备或移动设备间的联接,进行数据交换。特别是PDA、移动电话、消费类设备。改变如数码照相机、摄像机、打印机等设备间多种不同制式连接器,多达7种制式的存储卡间数据交换的不便。
对OTG介绍比较详细的在USB的官网,详细请见英文文档:
http://www.usb.org/developers/onthego/。以下是官网的一个简要的介绍,贴出来看看:
USB On-The-Go and Embedded Host
Virtually every portable device now uses USB for PC connectivity. As these products increase in popularity, there is a growing need for them to communicate both with USB peripherals and directly with each other when a PC is not available. There is also an increase
in the number of other, non-PC hosts (Embedded Hosts) which support USB in order to connect to USB peripherals.
The USB On-The-Go and Embedded Host Supplements addresses these scenarios by allowing portable devices and non-PC hosts to have the following enhancements:
Targeted host capability to communicate with selected other USB peripherals
Support for direct connections between OTG devices
Power saving features to preserve battery life
Revision 2.0 of the USB On-The-Go and Embedded Host Supplement to the USB 2.0 Specification applies to products operating at low-speed, full-speed and high-speed and is released, including applicable ECNs and errata, as part of the USB 2.0 Specification package.
The corresponding OTG Adopters Agreement is also available.
Revision 1.0 of the USB On-The-Go and Embedded Host Supplement to the USB 3.0 Specification enhances these scenarios by adding SuperSpeed capability to USB On-The-Go and is released as part of the USB 3.0 Specification package. The corresponding Adopters Agreement
for USB OTG 3.0 is the USB 3.0 Adopters Agreement.
这里写得很清楚,OTG主要是实现可移动设备点对点的数据共享,不需要再依赖于PC机第三方的识别或者操作。平时经常从电脑下载MP3格式的音乐到phone or Pad,都是经过USB线来连接电脑,电脑可以识别到设备里面的存储设备,或者手机与手机的连接,这就是OTG功能。
这是一个在线浏览Linux内核源码的网站:http://lxr.linux.no/。
Linux内核早就提供了OTG的驱动,在http://lxr.linux.no/linux+v3.1.6/drivers/usb/gadget/目录下,Linux将usb与otg两个功能模块给独立开了,主要的驱动是file_storage.c,该驱动主要负责终端设备的存储设备节点的操作,比如,从电脑,在该终端的磁盘上面创建文件,都会通过这个驱动来完成存储任务。另外一个驱动主要是负责USB通信的,是结尾为"_udc.c"的驱动源码,该目录下有好几个以"_udc.c"结尾的文件,这是针对不同型号的处理器而增加的,不同厂家提供不同的驱动。
这里只是简单的介绍,Android在vold中处理otg,就是将要共享的磁盘设备写到一个标志文件里面,再广播一下大容量存储连接的状态。
一、连接电脑;先来看看源码:
else if (!strcmp(argv[1], "share")) {
if (argc != 4) {
cli->sendMsg(ResponseCode::CommandSyntaxError,
"Usage: volume share <path> <method>", false);
return 0;
}
rc = vm->shareVolume(argv[2], argv[3]);
}
进入shareVolume函数中,该函数判断一下sd卡的状态,如果不存在设备,或者sd卡不是出于空闲状态,那么就返回失败。
int VolumeManager::shareVolume(const char *label, const char *method) {
Volume *v = lookupVolume(label);
if (!v) {
errno = ENOENT;
return -1;
}
/*
* Eventually, we'll want to support additional share back-ends,
* some of which may work while the media is mounted. For now,
* we just support UMS
*/
if (strcmp(method, "ums")) {
errno = ENOSYS;
return -1;
}
if (v->getState() == Volume::State_NoMedia) {
errno = ENODEV;
return -1;
}
if (v->getState() != Volume::State_Idle) {
// You need to unmount manually befoe sharing
errno = EBUSY;
return -1;
}
/*getDiskDevice函数直接返回sd卡的设备号。*/
dev_t d = v->getDiskDevice();
if ((MAJOR(d) == 0) && (MINOR(d) == 0)) {
// This volume does not support raw disk access
errno = EINVAL;
return -1;
}
int fd;
char nodepath[255];
snprintf(nodepath,
sizeof(nodepath), "/dev/block/vold/%d:%d",
MAJOR(d), MINOR(d));
/*比较重要的在这里,想要实现让电脑识别到Android系统中的sd卡,
那么就必须将sd卡的设备节点路径写到以下文件中去,这样才能打开
大容量存储的功能,也就是OTG*/
if ((fd = open("/sys/devices/platform/usb_mass_storage/lun0/file",
O_WRONLY)) < 0) {
SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
return -1;
}
if (write(fd, nodepath, strlen(nodepath)) < 0) {
SLOGE("Unable to write to ums lunfile (%s)", strerror(errno));
close(fd);
return -1;
}
close(fd);
/*handleVolumeShared函数在Volume中,是一个虚函数,在子类DirectVolume中
实现,也就是广播一些ums的状态。*/
v->handleVolumeShared();
return 0;
}
如果有Android手机的用户,可以看到系统中存在/sys/devices/platform/usb_mass_storage/lun0/file这么一个文件,Java层可能没有权限访问该文件。最近发现,Java想要访问系统的文件,或者操作命令都要赋以最高权限(0777)才能访问或执行,真是麻烦。
void DirectVolume::handleVolumeShared() {
setState(Volume::State_Shared);
}
二、断开连接;
int VolumeManager::unshareVolume(const char *label, const char *method) {
Volume *v = lookupVolume(label);
if (!v) {
errno = ENOENT;
return -1;
}
if (strcmp(method, "ums")) {
errno = ENOSYS;
return -1;
}
if (v->getState() != Volume::State_Shared) {
errno = EINVAL;
return -1;
}
int fd;
if ((fd = open("/sys/devices/platform/usb_mass_storage/lun0/file", O_WRONLY)) < 0) {
SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
return -1;
}
char ch = 0;
/*如果要断开连接,可以在电脑安全删除,然后Android系统会提示用户点击挂载sd卡,因为
在电脑使用sd卡的情况下,手机是不能对sd卡操作的,多处操作磁盘,会造成数据同步错误。
就在断开电脑,进入手机使用模式时,将/sys/devices/platform/usb_mass_storage/lun0/file
写为空了*/
if (write(fd, &ch, 1) < 0) {
SLOGE("Unable to write to ums lunfile (%s)", strerror(errno));
close(fd);
return -1;
}
close(fd);
/*再广播otg断开状态*/
v->handleVolumeUnshared();
return 0;
}
void DirectVolume::handleVolumeUnshared() {
setState(Volume::State_Idle);
}
这里已经分析完在CommandListener::VolumeCmd::runCommand函数的实现的所有操作了,然后程序将命令的执行结果通知Framework,源码:
if (!rc) {
cli->sendMsg(ResponseCode::CommandOkay, "volume operation succeeded", false);
} else {
int erno = errno;
rc = ResponseCode::convertFromErrno();
cli->sendMsg(rc, "volume operation failed", true);
}
磁盘操作的命令圆满结束,下一篇文章继续分析Framework与vold的通信。待续。
分享到:
相关推荐
Android-vold源码分析
android-vold架构[收集].pdf
android中vold代码分析,主要用来自动挂载设备
android系统vold透析 Vold的全称是 Volume Daemon
在Android 系统中所有的热插拔设备都是通过Vold 进程挂载的。通过kernel–>vold–>StorageManagerService这样的架构去逐级上报热插拔事件。 一、Vold 入口 --> /system/vold/main.c int main(int argc, char** ...
USB之android_Vold分析.pdf
此篇文章详细描述了USB之android_Vold_分析
android中VOLD代码框架的讲解和分析,设计到存储管理
主要目录 1 Vold简介 2 Vold功能介绍 3 Vold通信 4 USB Storage Framework结构分析
USB之android_Vold分析,分析了linux udev与android vold的关系由来,vold的功能、架构,使用netlink的通信过程。kernel的uevent发送,framework层的处理、磁盘的挂载等等。
本文档详细地介绍了android系统挂载中的vold,对vold的由来、功能、内部架构以及通信等方面进行了较为详细的介绍与较为深入的分析,是学习android挂载方面知识的一份比较好的材料。
android系统vold架构与流程透析
android平台移植ntfs-3g使支持ntfs格式tf卡、U盘、stat硬盘挂载,解压文件到external目录下,mm编译成功后,可手动指行 ntfs-3g /dev/block/vold/* /storage/sdcard1 或者添加 Ntfs.cpp Ntfs.h到system/vold目录实现...
解析android中Vold进程,让大家更好更快的掌握Vold
Android系统启动过程分析 本文主要介绍Android系统的启动过程,以Androidinit进程之后部分为主,init之前部分同标准Linux内核启动完全相同。于Android启动过程复杂,涉及C、C++及java部分内容,本文以流程分析为主线...
Android vold 多U盘多分区挂载实现 可以对比原生的vold代码查看修改
android 对插入设备后产生的反应,诉说连接的响应与挂载
Uevent 简介 NetLink 简介 MountService 功能介绍: MountService 同 StroageManager 的交互 MountService 同 Vold 的交互