zoukankan      html  css  js  c++  java
  • USB port 如何识别不同的Charger类型

    基于Qualcom 8960/8921平台

    一,软件分析

    1.  USB charger types & Power supply types

    USB_INVALID_CHARGER              Invalid USB charger.

    USB_SDP_CHARGER                       Standard downstream port. Refers to a downstream port  on USB2.0 compliant host/hub.

    USB_DCP_CHARGER                      Dedicated charger port (AC charger/ Wall charger).

    USB_CDP_CHARGER                      Charging downstream port. Enumeration can happen and IDEV_CHG_MAX can be drawn irrespective of USB state.

    USB_ACA_A_CHARGER                                B-device is connected on accessory port with charger connected on charging port. This configuration allows charging in host mode.

    USB_ACA_B_CHARGER                 No device (or A-device without VBUS) is connected on accessory port with charger connected on charging port.

    USB_ACA_C_CHARGER                 A-device (with VBUS) is connected on accessory port with charger connected on charging port.

    USB_ACA_DOCK_CHARGER        A docking station that has one upstream port and one or more downstream ports. Capable of supplying IDEV_CHG_MAX irrespective of devices connected on 
    accessory ports.

    USB_PROPRIETARY_CHARGER   A proprietary charger pull DP and DM to specific voltages between 2.0-3.3v for identification.

     

    POWER_SUPPLY_TYPE_USB,                      /* Standard Downstream Port */

    POWER_SUPPLY_TYPE_USB_DCP,           /* Dedicated Charging Port */

    POWER_SUPPLY_TYPE_USB_CDP,           /* Charging Downstream Port */

    POWER_SUPPLY_TYPE_USB_ACA,           /* Accessory Charger Adapters */

    POWER_SUPPLY_TYPE_BMS,                     /* Battery Monitor System */

     

    2. How to classify or identify charger?

     

    USB_SDP_CHARGER

    POWER_SUPPLY_TYPE_USB

    USB Charger

    USB_CDP_CHARGER

    POWER_SUPPLY_TYPE_USB_CDP

    USB_ACA_DOCK_CHARGER

    POWER_SUPPLY_TYPE_USB_ACA

    USB_ACA_A_CHARGER

    USB_ACA_B_CHARGER

    USB_ACA_C_CHARGER

    USB_DCP_CHARGER

    POWER_SUPPLY_TYPE_USB_DCP

    AC Charger

    USB_PROPRIETARY_CHARGER

     

    As for the DMS, refer to bold font items, so it is USB charger.

     

    3. Analysis about source codes

    *******************************************************************

    ###用户空间的分析如下:

    1. 检查 /sys/class/power_supply/pm8921-dc/online /sys/class/power_supply/usb/online 的值,可以知道是何充电器类型

                    @frameworks/base/services/jni/com_android_server_batteryservice.cpp中有

                    int register_android_server_BatteryService(JNIEnv* env)          

                    

                    if (strcmp(buf, "Mains") == 0) { ///sys/class/power_supply/pm8921-dc/type == Mains

                        snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);

                        if (access(path, R_OK) == 0)

                            gPaths.acOnlinePath = strdup(path);

                    }

                    

       如果/sys/class/power_supply/pm8921-dc/online==1,则插入的充电器是wall
    charger

          /sys/class/power_supply/usb/online==1, 则插入的充电器是usb charger

       调试路径:/sys/kernel/debug/msm_otg

    2. 分析frameworks/base/services/jni/com_android_server_batteryservice.cpp

                    a.函数register_android_server_BatteryService将为被frameworks/base/services/jni/onload.cpp中的JNI_OnLoad调用,用于关联javaC++之间的变量

                    b.jclass clazz = env->FindClass("com/android/server/BatteryService"); //根据java的路径找到batteryservice.java对应的jclass    

                      gFieldIds.mAcOnline = env->GetFieldID(clazz, "mAcOnline", "Z");

                      gFieldIds.mUsbOnline = env->GetFieldID(clazz, "mUsbOnline", "Z"); //用于关联batteryservice.java中变量private
    boolean mAcOnline
    gFieldIds.mAcOnline

                    c. android_server_BatteryService_update

                                    static JNINativeMethod sMethods[] = {

                                         /* name, signature, funcPtr */

                                                    {"native_update", "()V", (void*)android_server_BatteryService_update},

                                    };

                       关联到native_update@frameworks/base/services/java/com/android/server/batteryservice.java

    3. 分析frameworks/base/services/java/com/android/server/batteryservice.java

                    a. mPowerSupplyObserver.startObserving("SUBSYSTEM=power_supply"); //注册监听该uevent

                    b.     private UEventObserver mPowerSupplyObserver = new UEventObserver() {

                                    public void onUEvent(UEventObserver.UEvent event) { //如果就收到来自kerneluevent,触发该函数

                                        update(); //-->native_update();processValues();

                                    }

                           };

                    c. native_update函数会通过JNI调用得到更新的mAcOnlinemUsbOnline

                    d. processValues会根据mAcOnlinemUsbOnlinemPlugType赋值

                                    if (mAcOnline) {

                                        mPlugType = BatteryManager.BATTERY_PLUGGED_AC;

                                    } else if (mUsbOnline) {

                                        mPlugType = BatteryManager.BATTERY_PLUGGED_USB;

                                    } else {

                                        mPlugType = BATTERY_PLUGGED_NONE;

                                    }

                    e. sendIntent函数会准备Intent并且broadcast这个Intent

                                    Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); //public static final String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";@batteryservice.java

                                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY

                                            | Intent.FLAG_RECEIVER_REPLACE_PENDING);

     

                            intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);

                                    ActivityManagerNative.broadcastStickyIntent(intent, null);

    4. 分析vendor/semc/packages/apps/debugmenu/src/com/sonyericsson/debugmenu/battery.java

                    a. 接收intent

                        private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {

                                    @Override

                                    public void onReceive(Context arg0, Intent intent) {

                                        if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {

                                            mPowerInformation.parseIntent(intent);

                                            updateViews();

                                        }

                                    }

                        };

                        public void registerBroadcastReceivers() {

                                    IntentFilter mIntentFilter;

                                    mIntentFilter = new IntentFilter();

                                    mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); //只接收Intent.ACTION_BATTERY_CHANGEDintent

                                    // Register battery receiver.

                                    registerReceiver(mBatteryInfoReceiver, mIntentFilter);

                        }         

                    b. parseIntent 得到最新的"plugged"值赋给mPlugged

                    c. updateViews 更新charger类型显示

    ###内核空间

    1. 插入充电器触发的过程@kernel/drivers/usb/otg/msm_otg.c

                    a. CONFIG_PM_RUNTIME 定义 @kernel/arch/arm/configs/viskan_huashan_defconfig

                    b.msm_otg_runtime_resume-->msm_otg_resume-->??-->msm_otg_sm_work

                    c.msm_otg_sm_work,先进入OTG_STATE_UNDEFINED case,然后进入OTG_STATE_B_IDLE
    case-->motg->chg_state=USB_CHG_STATE_UNDEFINED-->
    启动msm_chg_detect_work

                    d.msm_chg_detect_work 该函数主要完成USB charger类型的识别

                                    USB_CHG_STATE_UNDEFINED //其中psy = power_supply_get_by_name("usb");很关键,表明只是获取usbpower_supply,实际上就是chip->usb_psy@pm8921-charger.c

                                    USB_CHG_STATE_WAIT_FOR_DCD         //Waiting for Data pins contact.

                                    然后多次(MSM_CHG_DCD_MAX_RETRIES=6)检测USB状态,启动queue_delayed_work(motg->wq,
    &motg->chg_work, delay); //motg->chg_work=msm_chg_detect_work

                                    USB_CHG_STATE_DETECTED //最后USB charge类型检测完毕

                    e. 启动queue_work(motg->wq, &motg->sm_work); //motg->sm_work=msm_otg_sm_work

                    f. 由于motg->chg_state==USB_CHG_STATE_DETECTED,

                                    motg->chg_type==USB_DCP_CHARGER -->msm_otg_notify_charger(motg,IDEV_CHG_MAX);//IDEV_CHG_MAX=1500

    2. 发送uevent到用户层

                    a. msm_otg_notify_charger@kernel/drivers/usb/otg/msm_otg.c

                    b. -->msm_otg_notify_chg_type@msm_otg.c,该函数中充电类型只归纳成4POWER_SUPPLY_TYPE_USB,POWER_SUPPLY_TYPE_USB_CDP,POWER_SUPPLY_TYPE_USB_DCP,POWER_SUPPLY_TYPE_USB_ACA,POWER_SUPPLY_TYPE_BATTERY

                    c. -->power_supply_set_supply_type@power_supply_core.c // set type of
    the power supply

                    d. -->psy->set_property(psy, POWER_SUPPLY_PROP_TYPE,&ret);

                                    那么在用usb_psy.get_propertydc_psy.get_property
    (
    在函数中pm8921_charger_probe)读取property

                                    如果是USB type,则在pm_power_get_property_usb读取POWER_SUPPLY_PROP_ONLINE的值,其中POWER_SUPPLY_TYPE_USBPOWER_SUPPLY_TYPE_USB_CDPPOWER_SUPPLY_TYPE_USB_ACA都被归纳成USB
    charger

                                    如果是AC type,则在pm_power_get_property_mains读取POWER_SUPPLY_PROP_ONLINE的值,只有POWER_SUPPLY_TYPE_USB_DCPAC
    charger
    .

                    e. psy=chip->usb_psy@pm8921-charger.c,所以继续调用的是pm_power_set_property_usb@pm8921-charger.c

                    f. -->pm8921_set_usb_power_supply_type(val->intval)@pm8921-charger.c

                                    -->power_supply_changed(&the_chip->usb_psy);

                                    -->power_supply_changed(&the_chip->dc_psy);

                    g. power_supply_changed@pm8921-charger.c , 就会马上发送ueventuser
    space,
    然后user space通过sysfs得到USB
    type
    变化后的信息,参考用户空间的分析

     

    二、硬件分析

    主要是通过特殊设计的电路,检测不同的pin的状态,从而确定是何种类型的Charger. 更details的内容省略。

  • 相关阅读:
    网站测试中如何做好安全性测试
    Web安全性测试总结
    文件上传验证绕过技术总结
    Burp Suite使用介绍
    Burpsuite教程与技巧之HTTP brute暴力破解
    burpsuite绕过本地javascripte上传文件
    文件上传漏洞演示脚本之js验证
    上传验证绕过
    Burp Suite详细使用教程
    关于post和get传递参数的区别
  • 原文地址:https://www.cnblogs.com/LoongEmbedded/p/5298180.html
Copyright © 2011-2022 走看看