arm-linux

http://armboard.taobao.com/

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  515 随笔 :: 0 文章 :: 45 评论 :: 0 引用

Adb源码学习

关于 init_transport_registration函数
在初始化 transport注册系统时,创建一对 sockpair( transport_registration_send, transport_registration_recv)用于异步处理注册事件 , 并在 transport_registration_recv上安装一个异步事件回调函数 transport_registration_func. 当向 adb系统中注册 /删除一个 transport时,会调用 transport_write_action将一个 tmsg写入到 transport_registration_send端,那么 transport_registration_recv端上的回调函数 transport_registration_func就会被触发。

transport_registration_func的主要工作是异步处理 transport的注册和删除操作:

删除一个 transport:删除与该 transport相关的异步 IO,更新 adb系统中 transport列表,运行 disconnect操作,最后释放 memory。如果是 host端, 还要更新 device tracker???
注册一个新的 transport: 为这个新的 transport对象创建一对 socketpair用来做线程间通信,安装异步 IO事件,然后创建 output thread和 input thread用于做异步 IO。根据 adb的文档说明, output线程和 input线程的引人主要是为了解决 USB endpoint不支持非阻塞读写,所以就专门为 usb读操作开一个 output线程,为 usb写操作创建一个 input线程。所以,数据流方向是远程连接 ->output线程 ->主线程 ->input线程 ->远程连接。刚开始时, output线程会发一个 SYNC消息给 input线程,启动这个 transport。
关于 usb_vendors_init函数
初始化 usb vendor的信息,有一些是内置的 ID号,如 Google, HTC, SAMSUNG等厂家的 ID,其他的可以从 $HOME/.android/adb_usb.ini文件中读取。

关于 usb_init函数
PC host端和 android device端有不同的实现:

device端 (usb_linux_client.c): usb_init首先试着以 RDWR的方式打开 /dev/android_adb_enable设备文件告诉 kernel要开始启用 adb的 USB调试功能了。一旦 kernel成功启用了 adb的 usb功能,就会一个新的线程 usb_open_thread每隔 1000ms扫描一次,判断 adb是否就绪了。在 Android中,当 device通过 usb线连接到 host端, kernel就会加载相应的 usb驱动 (???)并创建设备文件 /dev/android_adb,反复读取这个文件就可以判断 device是否连接到 pc端了。如果返回的 fd大于 0,那么说明已经连接好了,这个时候调用 register_usb_transport将 usbtransport注册到 adb系统中,等候在 transport_registration_recv的异步 IO事件发生了。如上所述, init_registration_func中的 output线程会首先发送 A_SYNC消息启动 device和 host的握手协商过程。整个 adb系统将会按照既定的协议运作起来。 host端也是这样一个过程。此时, host端会首先调用 send_connect给 device端发送 A_CNNX消息告诉自己能够接受多大的 payload, device收到这个消息后,也会调用 send_connect给 host端发送 A_CNNX消息告诉自己能够接受多大的 payload,,一来一回,完成了传输的握手协议了。

host端的 usb_init: 支持 FreeBSD, MAC OSX, Windows平台。大致流程与 device端的相仿,都创建一个专门扫描 usb端口的线程判断是否有 device连接,如果有,就调用 register_usb_transport函数启动整个 adb系统。 linux是通过 libusb来读取 usb endpoint中的信息, windows平台上是通过 Android系统提供的 API来读取的。

 

posted on 2011-02-15 17:18  arm-linux  阅读(4807)  评论(0编辑  收藏