Android USB gadget框架学习笔记

一 Gadget框架结构

kernel/drivers/usb/gadget,这个目录是android下usbgadget的主要目录。
Gadget功能组织单元:主要文件android.c,usb gadget功能的统领文件,负责组织usb 复合设备的功能,与上层应用提供交互的接口,面向市场需求的产品规划部门。
复合设备逻辑处理单元(复合设备管理单元):主要文件:composite.c,这个文件类似于一个项目管理组,负责各个单元的接口对接,资源整理。针对拥有多个usb功能的复合设备,这部分负责将支持的各个功能组织到一起,协助各个功能与UDC控制器单元建立联系。
具体功能单元:以U盘为例,f_mass_storge.c文件,用来完成具体的功能。这个部分是一个功能性很强的部分,将与UDC控制器单元直接对话,完成数据的传输。

UDC控制器单元:只做一件事情,收发usb数据,将数据透明的传递出去。

通过configfs用户空间对android gadget设备的配置在init.usb.rc文件中。

 

1.Android中通过UEventObserver类来接收内核发出的uevent事件

复制代码
kernel向用户空间发送uevent消息函数:
    kobject_uevent_env(&dev->dev->kobj,KOBJ_CHANGE, uevent_envp);

android层的接收uevent事件:
 
private final UEventObservermUEventObserver = newUEventObserver() {
   @Override
   public void onUEvent(UEventObserver.UEvent event) {
       if (DEBUG) Slog.v(TAG, "USB UEVENT: " +event.toString());
       String state = event.get("USB_STATE");
       String accessory = event.get("ACCESSORY");

       if (state != null) {
           mHandler.updateState(state);
       } else if ("START".equals(accessory)) {
           if(DEBUG) Slog.d(TAG, "got accessory start");
           setCurrentFunction(UsbManager.USB_FUNCTION_ACCESSORY,false);
       }
   }
};

 
在类初始化时会调用mUEventObserver.startObserving(USB_STATE_MATCH)启动监听动作,最终会调用到UEventObserver的addObserver:

privateArrayList<Object> mObservers = newArrayList<Object>();
publicvoid addObserver(String match, UEventObserver observer){
    synchronized(mObservers) {
        mObservers.add(match);
        mObservers.add(observer);
    }

}

private static final String USB_STATE_MATCH = "DEVPATH=/devices/virtual/android_usb/android0";
该函数最终会将”DEVPATH=/devices/virtual/android_usb/android0”增加到匹配序列中,当kernel发送具有该字符串的数据时,就返回匹配成功,然后调用mUEventObserver 的onUEvent函数;

UeventObserver.java    //目前的Android内核中好像不存在这个文件了。
  private static class UEventThreadextends Thread {
       private ArrayList<Object> mObservers= new ArrayList<Object>();
       UEventThread() {
           super("UEventObserver");
       }
       public void run() {
           native_setup();
           byte[] buffer = new byte[1024];
           int len;
           while (true) {
               len = next_event(buffer);
               if (len > 0) {
                   String bufferStr = new String(buffer, 0, len);  //easier to search a String
                   synchronized (mObservers) {
                       for (int i = 0; i < mObservers.size(); i += 2){
                           if (bufferStr.indexOf((String)mObservers.get(i)) != -1){
                               ((UEventObserver)mObservers.get(i+1))
                                       .onUEvent(new UEvent(bufferStr));
                           }
                       }
                   }
               }
           }
       }
}
复制代码

 

posted on   Hello-World3  阅读(1501)  评论(0编辑  收藏  举报

编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示