Linux cpufreq framework(2)_cpufreq driver

本文从平台驱动工程师的角度出发,详细介绍了如何为特定平台编写cpufreq驱动。内容覆盖了驱动的编写步骤、关键API及功能分析,包括频率表的定义、cpufreq_driver结构体的解析及其回调函数的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 前言

本文从平台驱动工程师的角度,介绍怎么编写cpufreq驱动。

注1:本文基于linux-3.18-rc4内核,其它版本内核可能会稍有不同。

2. cpufreq driver的编写步骤

cpufreq driver主要完成平台相关的CPU频率/电压的控制,它在cpufreq framework中是非常简单的一个模块,编写步骤包括:

1)平台相关的初始化动作,包括CPU core的clock/regulator获取、初始化等。

2)生成frequency table,即CPU core所支持的频率/电压列表。并在初始化时将该table保存在policy中。

3)定义一个struct cpufreq_driver变量,填充必要的字段,并根据平台的特性,实现其中的回调函数。

4)调用cpufreq_register_driver将driver注册到cpufreq framework中。

5)cpufreq core会在CPU设备添加时,调用driver的init接口。driver需要在该接口中初始化struct cpufreq_policy变量。

6)系统运行过程中,cpufreq core会根据实际情况,调用driver的setpolicy或者target/target_index等接口,设置CPU的调频策略或者频率值。

7)系统suspend的时中,会将CPU的频率设置为指定的值,或者调用driver的suspend回调函数;系统resume时,调用driver的resume回调函数。

具体请参考后面的分析。

3. cpufreq driver有关的API即功能分析

3.1 frequency table

frequency table是CPU core可以正确运行的一组频率/电压组合,一般情况下,会在项目启动的初期,通过“try频点”的方法,确定出稳定性、通用性都符合要求的频点。

frequency table之所以存在的一个思考点是:table是频率和电压之间的一个一一对应的组合,因此cpufreq framework只需要关心频率,所有的策略都称做“调频”策略。而cpufreq driver可以在“调频”的同时,通过table取出和频率对应的电压,进行修改CPU core电压,实现“调压”的功能。这简化了设计。

cpufreq framework以cpufreq_frequency_table抽象frequency table,如下:

   1: /* Special Values of .frequency field */
   2: #define CPUFREQ_ENTRY_INVALID   ~0u
   3: #define CPUFREQ_TABLE_END       ~1u
   4: /* Special Values of .flags field */
   5: #define CPUFREQ_BOOST_FREQ      (1 << 0)
   6:  
   7: struct cpufreq_frequency_table {
   8:         unsigned int    flags;
   9:         unsigned int    driver_data; /* driver specific data, not used by core */
  10:         unsigned int    frequency; /* kHz - doesn't need to be in ascending
  11:                                     * order */
  12: };

frequency,频率值,单位为kHz,不需要特别的排序。这里定义了两个特殊的频率值:CPUFREQ_ENTRY_INVALID,用来表示table中的一个无效频率值;CPUFREQ_TABLE_END,用于表示table的结束。

driver_data,由名字就可以知道,这个字段由driver使用,具体意义由driver定义,可以是电压,也可以是其它(如OPP index,后续文章会详细描述)。

flags,现在只有一个----CPUFREQ_BOOST_FREQ,表示这个频率值是一个boost频率。

注2:Boost表示智能超频技术,是一个在x86平台上的功能,具体可参考“turbo-boost-technology.html”,本文不做过多描述。

假设CPU device的OPP 列表已经由cpu subsystem driver调用of_init_opp_table解析出来了,cpufreq driver可以借助dev_pm_opp_init_cpufreq_table将OPP列表转换为frequency table。

of_init_opp_table接口请参考“Linux电源管理(15)_PM OPP Interface”,dev_pm_opp_init_cpufreq_table接口的声明如下:

   1: /* include/linux/cpufreq.h */
   2: int dev_pm_opp_init_cpufreq_table(struct device *dev,
   3:                                   struct cpufreq_frequency_table **table);

该接口的逻辑很简单,根据传入的设备指针,遍历OPP列表,转换为frequency table,并通过table返回给调用者。具体请参考后面的文章。

3.2 struct cpufreq_driver

struct cpufreq_driver是cpufreq driver的核心数据结构,我们在“linux cpufreq framework(1)_概述”中有简单介绍过,这里再详细分析一下:

   1: struct cpufreq_driver {
   2:     char            name[CPUFREQ_NAME_LEN];
   3:     u8            flags;
   4:     void            *driver_data;
   5:  
   6:     /* needed by all drivers */
   7:     int    (*init)        (struct cpufreq_policy *policy);
   8:     int    (*verify)    (struct cpufreq_policy *policy);
   9:  
  10:     /* define one out of two */
  11:     int    (*setpolicy)    (struct cpufreq_policy *policy);
  12:  
  13:     /*
  14:      * On failure, should always restore frequency to policy->restore_freq
  15:      * (i.e. old freq).
  16:      */
  17:     int    (*target)    (struct cpufreq_policy *policy,    /* Deprecated */
  18:                  unsigned int target_freq,
  19:                  unsigned int relation);
  20:     int    (*target_index)    (struct cpufreq_policy *policy,
  21:                  unsigned int index);
  22:     /*
  23:      * Only for drivers with target_index() and CPUFREQ_ASYNC_NOTIFICATION
  24:      * unset.
  25:      *
  26:      * get_intermediate should return a stable intermediate frequency
  27:      * platform wants to switch to and target_intermediate() should set CPU
  28:      * to to that frequency, before jumping to the frequency corresponding
  29:      * to 'index'. Core will take care of sending notifications and driver
  30:      * doesn't have to handle them in target_intermediate() or
  31:      * target_index().
  32:      *
  33:      * Drivers can return '0' from get_intermediate() in case they don't
  34:      * wish to switch to intermediate frequency for some target frequency.
  35:      * In that case core will directly call ->target_index().
  36:      */
  37:     unsigned int (*get_intermediate)(struct cpufreq_policy *policy,
  38:                      unsigned int index);
  39:     int    (*target_intermediate)(struct cpufreq_policy *policy,
  40:                        unsigned int index);
  41:  
  42:     /* should be defined, if possible */
  43:     unsigned int    (*get)    (unsigned int cpu);
  44:  
  45:     /* optional */
  46:     int    (*bios_limit)    (int cpu, unsigned int *limit);
  47:  
  48:     int    (*exit)        (struct cpufreq_policy *policy);
  49:     void    (*stop_cpu)    (struct cpufreq_policy *policy);
  50:     int    (*suspend)    (struct cpufreq_policy *policy);
  51:     int    (*resume)    (struct cpufreq_policy *policy);
  52:     struct freq_attr    **attr;
  53:  
  54:     /* platform specific boost support code */
  55:     bool                    boost_supported;
  56:     bool                    boost_enabled;
  57:     int     (*set_boost)    (int state);
  58: };

1)init回调函数

init回调函数是cpufreq driver的入口,由cpufreq core在CPU device添加之后调用,其主要功能就是初始化policy变量(把它想象成cpufreq device)。

对driver而言,不需要太关心struct cpufreq_policy的内部实现(其实cpufreq framework也在努力实现这个目标,包括将相应的初始化过程封装成一个API等),为了分析方便,我们再把这个结构贴一次:

   1: struct cpufreq_cpuinfo {
   2:     unsigned int        max_freq;
   3:     unsigned int        min_freq;
   4:  
   5:     /* in 10^(-9) s = nanoseconds */
   6:     unsigned int        transition_latency;
   7: };
   8:  
   9: struct cpufreq_real_policy {
  10:     unsigned int        min;    /* in kHz */
  11:     unsigned int        max;    /* in kHz */
  12:     unsigned int        policy; /* see above */
  13:     struct cpufreq_governor    *governor; /* see below */
  14: };
  15:  
  16: struct cpufreq_policy {
  17:     /* CPUs sharing clock, require sw coordination */
  18:     cpumask_var_t        cpus;    /* Online CPUs only */
  19:     cpumask_var_t        related_cpus; /* Online + Offline CPUs */
  20:  
  21:     unsigned int        shared_type; /* ACPI: ANY or ALL affected CPUs
  22:                         should set cpufreq */
  23:     unsigned int        cpu;    /* cpu nr of CPU managing this policy */
  24:     unsigned int        last_cpu; /* cpu nr of previous CPU that managed
  25:                        * this policy */
  26:     struct clk        *clk;
  27:     struct cpufreq_cpuinfo    cpuinfo;/* see above */
  28:  
  29:     unsigned int        min;    /* in kHz */
  30:     unsigned int        max;    /* in kHz */
  31:     unsigned int        cur;    /* in kHz, only needed if cpufreq
  32:                      * governors are used */
  33:     unsigned int        restore_freq; /* = policy->cur before transition */
  34:     unsigned int        suspend_freq; /* freq to set during suspend */
  35:  
  36:     unsigned int        policy; /* see above */
  37:     struct cpufreq_governor    *governor; /* see below */
  38:     void            *governor_data;
  39:     bool            governor_enabled; /* governor start/stop flag */
  40:  
  41:     struct work_struct    update; /* if update_policy() needs to be
  42:                      * called, but you're in IRQ context */
  43:  
  44:     struct cpufreq_real_policy    user_policy;
  45:     struct cpufreq_frequency_table    *freq_table;
  46:  
  47:     struct list_head        policy_list;
  48:     struct kobject        kobj;
  49:     struct completion    kobj_unregister;
  50:  
  51:     /*
  52:      * The rules for this semaphore:
  53:      * - Any routine that wants to read from the policy structure will
  54:      *   do a down_read on this semaphore.
  55:      * - Any routine that will write to the policy structure and/or may take away
  56:      *   the policy altogether (eg. CPU hotplug), will hold this lock in write
  57:      *   mode before doing so.
  58:      *
  59:      * Additional rules:
  60:      * - Lock should not be held across
  61:      *     __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
  62:      */
  63:     struct rw_semaphore    rwsem;
  64:  
  65:     /* Synchronization for frequency transitions */
  66:     bool            transition_ongoing; /* Tracks transition status */
  67:     spinlock_t        transition_lock;
  68:     wait_queue_head_t    transition_wait;
  69:     struct task_struct    *transition_task; /* Task which is doing the transition */
  70:  
  71:     /* For cpufreq driver's internal use */
  72:     void            *driver_data;
  73: };

对driver而言,需要在init中初始化policy的如下内容:

cpus,告诉cpufreq core,该policy适用于哪些cpu。大多数情况下,系统中所有的cpu core都由相同的硬件逻辑,统一控制cpu frequency,因此只需要一个policy,就可以管理所有的cpu core。“linux cpufreq framework(3)_cpufreq core”中会重点介绍。

clk,clock指针,cpufreq core可以利用该指针,获取当前实际的frequency值。

cpuinfo,该cpu调频相关的固定信息,包括最大频率、最小频率、切换延迟,其中最大频率、最小频率可以通过frequency table推导得出。

min、max,调频策略所对应的最小频率、最大频率,初始化时,可以和上面的cpuinfo中的min、max相同。

freq_table,所对应的frequency table。

除了clk指针外,cpuinfo、min、max、freq_table等都可以通过cpufreq_generic_init接口初始化:

   1: int cpufreq_generic_init(struct cpufreq_policy *policy,
   2:                 struct cpufreq_frequency_table *table,
   3:                 unsigned int transition_latency);

该接口以需要初始化的policy、frequency table以及切换延迟为参数,从table中解析policy初始化所需的信息,初始化该policy。

一般情况下,该接口是enough的,因此在init中调用它即可。

2)verify回调函数

当上层软件需要设定一个新的policy的时候,会调用driver的verify回调函数,检查该policy是否合法。cpufreq core封装了下面两个接口,辅助完成这个功能:

   1: int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
   2:                                    struct cpufreq_frequency_table *table);
   3: int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy);

cpufreq_frequency_table_verify根据指定的frequency table,检查policy是否合法,检查逻辑很简单:policy的频率范围{min,max},是否超出policy->cpuinfo的频率范围,是否超出frequency table中的频率范围。

cpufreq_generic_frequency_table_verify更简单,它以policy中保存的frequency table为参数(policy->freq_table),调用cpufreq_frequency_table_verify接口。

注3:在这里先提一下cpufreq framework中“频率”的几个层次。 
最底层,是frequency table中定义的频率,有限的离散频率,代表了cpu的调频能力。 
往上,是policy->cpuinfo中的频率范围,它对cpu调频进行的简单的限制,该限制可以和frequency table一致,也可以小于table中的范围。必须在driver初始化时给定,之后不能再修改。 
再往上,是policy的频率范围,代表调频策略。对于可以自动调频的CPU,只需要把这个范围告知CPU即可,此时它是调频的基本单位。对于不可以自动调频的CPU,它是软件层面的一个限制。该范围也可以通过sysfs修改。 
最上面,是policy中的频率值,对那些不可以调频的CPU,该值就是CPU的运行频率。

3)setpolicy回调函数

对于可以自动调频的CPU,driver需要提供该接口,通过该接口,将调频范围告知CPU。

4)target回调函数,不建议使用了,就不讲了。

5)target_index回调函数

对于不可以自动调频的CPU,该接口用于指定CPU的运行频率。index表示frequency table中的index。

driver需要通过index,将频率值取出,通过clock framework提供的API,将CPU的频率设置为对应的值。

同时,driver可以调用OPP interface,获取该频率对应的电压值,通过regulator framework提供的API,将CPU的电压设置为对应的值。

6)get_intermediate、target_intermediate,在没有提供target接口的时候使用,希望看这篇文章对的工程师不要使用。不详细介绍了。

7)get回调函数

用于获取指定cpu的频率值,如果可以的话,driver应尽可能提供。如果在init接口中给policy->clk赋值的话,则可以使用cpufreq framework提供的通用接口:

   1: unsigned int cpufreq_generic_get(unsigned int cpu);

该接口会直接调用clock framework API,从policy->clk中获取频率值。

8)exit,和init对应,在CPU device被remove时调用。

9)stop_cpu,在CPU被stop时调用。

10)suspend、resume回调函数

系统给suspend的时候,clock、regulator等driver有可能被suspend,因此需要在这之前将CPU设置为一个确定的频率值。driver可以通过suspend回调设置,也可以通过policy中的suspend_freq字段设置(cpufreq core会自动切换)。

同理,系统resume后,CPU的运行频率是什么,可以通过resume回调设置,也可以通过policy中的restore_freq字段设置。

11)freq_attr

如果cpufreq driver需要提供一些额外的sysfs attribute,可以通过如下的attribute宏设置,然后保存在cpufreq_driver的attr数组中:

   1: struct freq_attr {
   2:         struct attribute attr;
   3:         ssize_t (*show)(struct cpufreq_policy *, char *);
   4:         ssize_t (*store)(struct cpufreq_policy *, const char *, size_t count);
   5: };
   6:  
   7: #define cpufreq_freq_attr_ro(_name)             \
   8: static struct freq_attr _name =                 \
   9: __ATTR(_name, 0444, show_##_name, NULL)
  10:  
  11: #define cpufreq_freq_attr_ro_perm(_name, _perm) \
  12: static struct freq_attr _name =                 \
  13: __ATTR(_name, _perm, show_##_name, NULL)
  14:  
  15: #define cpufreq_freq_attr_rw(_name)             \
  16: static struct freq_attr _name =                 \
  17: __ATTR(_name, 0644, show_##_name, store_##_name)

3.3 cpufreq_driver flags

注册cpufreq driver时,可以通过flag字段指定一些特性,包括:

   1: /* flags */
   2: #define CPUFREQ_STICKY          (1 << 0)        /* driver isn't removed even if
   3:                                                    all ->init() calls failed */
   4: #define CPUFREQ_CONST_LOOPS     (1 << 1)        /* loops_per_jiffy or other
   5:                                                    kernel "constants" aren't
   6:                                                    affected by frequency
   7:                                                    transitions */
   8: #define CPUFREQ_PM_NO_WARN      (1 << 2)        /* don't warn on suspend/resume
   9:                                                    speed mismatches */
  10:  
  11: /*
  12:  * This should be set by platforms having multiple clock-domains, i.e.
  13:  * supporting multiple policies. With this sysfs directories of governor would
  14:  * be created in cpu/cpu/cpufreq/ directory and so they can use the same
  15:  * governor with different tunables for different clusters.
  16:  */
  17: #define CPUFREQ_HAVE_GOVERNOR_PER_POLICY (1 << 3)
  18:  
  19: /*
  20:  * Driver will do POSTCHANGE notifications from outside of their ->target()
  21:  * routine and so must set cpufreq_driver->flags with this flag, so that core
  22:  * can handle them specially.
  23:  */
  24: #define CPUFREQ_ASYNC_NOTIFICATION  (1 << 4)
  25:  
  26: /*
  27:  * Set by drivers which want cpufreq core to check if CPU is running at a
  28:  * frequency present in freq-table exposed by the driver. For these drivers if
  29:  * CPU is found running at an out of table freq, we will try to set it to a freq
  30:  * from the table. And if that fails, we will stop further boot process by
  31:  * issuing a BUG_ON().
  32:  */
  33: #define CPUFREQ_NEED_INITIAL_FREQ_CHECK (1 << 5)

CPUFREQ_STICKY,表示就算所有的init调用都失败了,driver也不被remove。具体应用场景不明。

CPUFREQ_CONST_LOOPS,表示频率的调整,不影响loops_per_jiffy等kernel常来的计算。

CPUFREQ_PM_NO_WARN,suspend/resume过程相关的flag,后面文章如果分析相应的功能的话,再详细描述。

CPUFREQ_HAVE_GOVERNOR_PER_POLICY,表示不同的CPU,有不同的频率控制方式,因此cpufreq core会为每一个CPU创建一个cpufreq调频接口。否则(也是正常情况下),一个调频接口可以调整所有CPU的频率。

其它flag用到时再分析。

3.4 cpufreq_register_driver

driver的注册接口比较简单,进行一些必要的检查后,将driver保存在一个全局指针(cpufreq_driver)中,如果该指针不为空,则说明已经有driver注册过了,返回错误(-EEXIST)。

最后,会调用subsys_interface_register接口,注册一个subsystem interface(struct subsys_interface cpufreq_interface),有关subsystem interface的介绍,可参考“Linux设备模型(6)_Bus”中的描述。cpufreq与此有关的逻辑,会在下一篇文章详细说明(linux cpufreq framework(3)_cpufreq core)。

 

原创文章,转发请注明出处。蜗窝科技www.wowotech.net

Line 18: 01-01 19:26:37.692480 1 1 E [ 14.908805]is_fastboot_adb_enabled: is_debuggable|cta|allcommode|aging test version,ingore Line 137: 01-01 19:26:38.165411 132 132 I [ 15.381736]wcd937x_codec wcd937x-codec: wcd_mbhc_start: usbc analog enabled Line 139: 01-01 19:26:38.165581 132 132 E [ 15.381906]wcd_mbhc_start: usbc_insert_pin in dt node is missing Line 462: 01-01 19:26:41.245371 902 902 I [ 18.461696]servicemanager: Caller(pid=2254,uid=0,sid=u:r:usbd:s0) Could not find android.hardware.usb.gadget.IUsbGadget/default in the VINTF manifest. No alternative instances declared in VINTF. Line 462: 01-01 19:26:41.245371 902 902 I [ 18.461696]servicemanager: Caller(pid=2254,uid=0,sid=u:r:usbd:s0) Could not find android.hardware.usb.gadget.IUsbGadget/default in the VINTF manifest. No alternative instances declared in VINTF. Line 462: 01-01 19:26:41.245371 902 902 I [ 18.461696]servicemanager: Caller(pid=2254,uid=0,sid=u:r:usbd:s0) Could not find android.hardware.usb.gadget.IUsbGadget/default in the VINTF manifest. No alternative instances declared in VINTF. Line 471: 01-01 19:26:41.384214 1 1 I [ 18.600539]: setusbconfig toadb Line 471: 01-01 19:26:41.384214 1 1 I [ 18.600539]: setusbconfig toadb Line 474: 01-01 19:26:41.397404 1705 1705 I [ 18.613729]msm-usb-hsphy 1613000.hsphy: Avail curr from USB = 2 Line 474: 01-01 19:26:41.397404 1705 1705 I [ 18.613729]msm-usb-hsphy 1613000.hsphy: Avail curr from USB = 2 Line 529: 01-01 19:26:41.659237 2423 2423 E [ 18.875562]: USB cable not connected Line 808: 01-01 19:26:45.895584 10 10 E [ 23.111909][kworke][0x22b3adb6][11:26:45.893158] wlan: [10:E:WMI] send_action_oui_cmd_tlv: Invalid action id Line 870: 01-01 19:26:51.533277 2386 2386 E [ 28.749602]: USB cable not connected Line 925: 01-01 19:26:55.678229 1 1 I [ 32.894554]init: processing action (vendor.sys.usb.adb.disabled=*) from (/system/etc/init/hw/init.usb.rc:23) Line 925: 01-01 19:26:55.678229 1 1 I [ 32.894554]init: processing action (vendor.sys.usb.adb.disabled=*) from (/system/etc/init/hw/init.usb.rc:23) Line 925: 01-01 19:26:55.678229 1 1 I [ 32.894554]init: processing action (vendor.sys.usb.adb.disabled=*) from (/system/etc/init/hw/init.usb.rc:23) Line 1076: 01-01 19:27:00.344412 3121 3121 W [ 37.560737]: stm_core(E) keyevent_handler(E) qcom_pm8008_regulator(E) ocp2130_bias(E) coresight(E) oplus_bsp_rfcablemonitor(E) oplus_secure_common(OE) oplus_security_keventupload(OE) qcom_vadc_common(E) icc_test(E) hung_task_enhance(E) oplus_mm_kevent(E) qti_battery_debug(E) oplus_bsp_fw_update(E) charger_ulog_glink(E) msm_tsens_driver(E) sps_drv(E) debugcc_sm6115(E) msm_geni_serial(E) usb_f_ccid(E) qcom_va_minidump(E) msm_lmh_dcvs(E) qpnp_lcdb_regulator(E) oplus_bsp_tp_custom(E) oplus_bsp_tp_notify(E) qcom_i2c_pmic(E) oplus_resctrl(E) ucsi_glink(E) oplus_bsp_sensor_feedback(E) init_watchdog(E) olc(E) hung_task_enh(E) pmic_glink_debug(E) oplus_exit_mm_optimize(E) bwmon(E) altmode_glink(E) oplus_bsp_mapped_protect(E) oplus_theia(E) phy_msm_qusb_v2(E) memlat(E) core_hang_detect(E) gpucc_sm6115(E) boot_stats(E) pmic_glink(E) rpm_master_stat(E) debugcc_khaje(E) dispcc_khaje(E) rq_stats(E) glink_pkt(E) cdsprm(E) oplus_bsp_dynamic_readahead(E) msm_gpi(E) cdsp_loader(E) eud(E) Line 1076: 01-01 19:27:00.344412 3121 3121 W [ 37.560737]: stm_core(E) keyevent_handler(E) qcom_pm8008_regulator(E) ocp2130_bias(E) coresight(E) oplus_bsp_rfcablemonitor(E) oplus_secure_common(OE) oplus_security_keventupload(OE) qcom_vadc_common(E) icc_test(E) hung_task_enhance(E) oplus_mm_kevent(E) qti_battery_debug(E) oplus_bsp_fw_update(E) charger_ulog_glink(E) msm_tsens_driver(E) sps_drv(E) debugcc_sm6115(E) msm_geni_serial(E) usb_f_ccid(E) qcom_va_minidump(E) msm_lmh_dcvs(E) qpnp_lcdb_regulator(E) oplus_bsp_tp_custom(E) oplus_bsp_tp_notify(E) qcom_i2c_pmic(E) oplus_resctrl(E) ucsi_glink(E) oplus_bsp_sensor_feedback(E) init_watchdog(E) olc(E) hung_task_enh(E) pmic_glink_debug(E) oplus_exit_mm_optimize(E) bwmon(E) altmode_glink(E) oplus_bsp_mapped_protect(E) oplus_theia(E) phy_msm_qusb_v2(E) memlat(E) core_hang_detect(E) gpucc_sm6115(E) boot_stats(E) pmic_glink(E) rpm_master_stat(E) debugcc_khaje(E) dispcc_khaje(E) rq_stats(E) glink_pkt(E) cdsprm(E) oplus_bsp_dynamic_readahead(E) msm_gpi(E) cdsp_loader(E) eud(E) Line 1078: 01-01 19:27:00.344518 3121 3121 W [ 37.560843]: gcc_khaje(E) oplus_bsp_task_sched(E) gcc_sm6115(E) mem_buf(E) qcom_dma_heaps(E) qseecom_dlkm(OE) oplus_kmsg_wb(E) phy_qcom_ufs_qmp_v3_660(E) phy_qcom_ufs_qrbtc_sdm845(E) phy_qcom_ufs_qmp_v4_khaje(E) qrtr(E) qcom_glink(E) qnoc_bengal(E) qcom_soc_wdt(E) ua_cpu_ioctl(E) smp2p(E) ufshcd_crypto_qti(E) usbpd(E) clk_qcom(E) crypto_qti_common(E) dcc_v2(E) device_info(E) icc_rpm(E) mem_buf_dev(E) oplus_bsp_frame_boost(E) mem_offline(E) memory_dump_v2(E) msm_poweroff(E) oplus_phoenix(E) pinctrl_bengal(E) oplus_schedinfo(E) qcom_iommu_util(E) phy_qcom_ufs(E) oplus_pmicwd(E) pinctrl_khaje(E) qcom_ipc_logging(E) qcom_logbuf_vh(E) rpm_smd_regulator(E) qcom_wdt_core(E) boot_mode(E) gdsc_regulator(E) crypto_qti_tz(E) minidump(E) oplus_bsp_sched_assist(E) oplus_project(E) oplus_mdmfeature(E) oplus_uprobe(E) pinctrl_msm(E) phoenix_reboot_speed(E) qcom_cpufreq_hw(E) qcom_spmi_pmic(E) qcom_smd(E) secure_buffer(E) socinfo(E) rpm_smd(E) qpnp_power_on(E) stub_regulator(E) Line 1079: 01-01 19:27:00.344580 3121 3121 W [ 37.560905]: buildvariant(E) bootloader_log(E) debug_regulator(E) cdt_integrity(E) iommu_logger(E) icc_debug(E) horae_shell_temp(E) kernel_fb(E) msm_dma_iommu_mapping(E) last_boot_reason(E) oplus_bsp_eas_opt(E) nvmem_qcom_spmi_sdam(E) nvmem_qfprom(E) oplus_bsp_midas(E) oplus_bsp_task_cpustats(E) oplus_bsp_mm_osvelte(E) oplus_bsp_task_load(E) oplus_storage_log(E) oplus_fdleak_check(E) oplus_power_notifier(E) oplus_omrg(E) oplus_ftm_mode(E) soc_sleep_stats(E) oplus_mdmrst(E) oplusboot(E) proxy_consumer(E) qcom_apcs_ipc_mailbox(E) smem(E) qcom_dcvs(E) qcom_cpu_vendor_hooks(E) qcom_enhance_watchdog(E) qcom_mpm(E) qcom_pmu_lib(E) qcom_scm(E) qnoc_qos_rpm(E) qrng_dlkm(OE) regmap_spmi(E) qti_regmap_debugfs(E) sdcardfs(E) shutdown_speed(E) spmi_pmic_arb(E) slimbus(E) qcom_hwspinlock(E) Line 1546: 01-01 19:27:22.292131 4918 4918 W [ 59.508456]: Modules linked in: camera(OE) machine_dlkm(OE) wcd937x_dlkm(OE) mbhc_dlkm(OE) fsa4480_i2c(E) oplus_chg_symbol(E) wlan(OE) ipa_clientsm(OE) rndisipam(OE) ipanetm(OE) oplus_chg(E) ipam(OE) rx_macro_dlkm(OE) va_macro_dlkm(OE) tx_macro_dlkm(OE) wcd9xxx_dlkm(OE) pinctrl_lpi_dlkm(OE) adsp_loader_dlkm(OE) audio_pkt_dlkm(OE) swr_ctrl_dlkm(OE) audio_prm_dlkm(OE) bolero_cdc_dlkm(OE) coresight_tmc(E) spf_core_dlkm(OE) gpr_dlkm(OE) usb_f_gsi(E) usb_f_qdss(E) q6_notifier_dlkm(OE) oplus_audio_sipa_tuning(OE) leds_qti_flash(E) oplus_bsp_tp_ft3658u_spi(E) oplus_bsp_tp_ft3419u(E) oplus_bsp_tp_td4377_noflash(E) rmnet_wlan(OE) oplus_bsp_tp_ft3518(E) wcd937x_slave_dlkm(OE) qcom_pon(E) oplus_bsp_tp_ilitek7807s(E) oplus_chg_v2(E) tcpc_rt1711h(E) tcpci_late_sync(E) nxp_nci(OE) oplus_audio_aw87xxx(OE) oplus_bsp_tp_focal_common(E) oplus_network_linkpower_module(OE) bt_fm_slim(OE) coresight_hwevent(E) coresight_tpdm(E) icnss2(OE) nq330(E) dump_reason(E) wsa881x_analog_dlkm(OE) Line 1546: 01-01 19:27:22.292131 4918 4918 W [ 59.508456]: Modules linked in: camera(OE) machine_dlkm(OE) wcd937x_dlkm(OE) mbhc_dlkm(OE) fsa4480_i2c(E) oplus_chg_symbol(E) wlan(OE) ipa_clientsm(OE) rndisipam(OE) ipanetm(OE) oplus_chg(E) ipam(OE) rx_macro_dlkm(OE) va_macro_dlkm(OE) tx_macro_dlkm(OE) wcd9xxx_dlkm(OE) pinctrl_lpi_dlkm(OE) adsp_loader_dlkm(OE) audio_pkt_dlkm(OE) swr_ctrl_dlkm(OE) audio_prm_dlkm(OE) bolero_cdc_dlkm(OE) coresight_tmc(E) spf_core_dlkm(OE) gpr_dlkm(OE) usb_f_gsi(E) usb_f_qdss(E) q6_notifier_dlkm(OE) oplus_audio_sipa_tuning(OE) leds_qti_flash(E) oplus_bsp_tp_ft3658u_spi(E) oplus_bsp_tp_ft3419u(E) oplus_bsp_tp_td4377_noflash(E) rmnet_wlan(OE) oplus_bsp_tp_ft3518(E) wcd937x_slave_dlkm(OE) qcom_pon(E) oplus_bsp_tp_ilitek7807s(E) oplus_chg_v2(E) tcpc_rt1711h(E) tcpci_late_sync(E) nxp_nci(OE) oplus_audio_aw87xxx(OE) oplus_bsp_tp_focal_common(E) oplus_network_linkpower_module(OE) bt_fm_slim(OE) coresight_hwevent(E) coresight_tpdm(E) icnss2(OE) nq330(E) dump_reason(E) wsa881x_analog_dlkm(OE) Line 1548: 01-01 19:27:22.292323 4918 4918 W [ 59.508648]: oplus_networks_tuning(OE) pm8941_pwrkey(E) coresight_remote_etm(E) leds_aw2023(E) qti_qmi_sensor(E) usb_f_diag(E) rt_regmap(E) bcl_soc(E) cpu_hotplug(E) cnss_prealloc(OE) qcom_spmi_temp_alarm(E) oplus_security_guard(OE) qcom_spmi_adc_tm5(E) reboot_mode(E) regulator_cdev(E) i2c_msm_geni(E) qcom_iommu_debug(E) oplus_bsp_tp_ilitek_common(E) qrtr_smd(E) thermal_pause(E) ehset(E) msm_mmrm(OE) leds_qpnp_vibrator_ldo(E) ufcs_class(E) cpufreq_ondemand(E) game_opt(OE) coresight_tgu(E) oplus_data_module(OE) stm_console(E) oplus_audio_pa_manager(OE) qcom_pil_info(E) phy_msm_ssusb_qmp(E) msm_sharedmem(E) oplus_stability_helper(OE) phy_msm_qusb(E) iolimit(E) pmic_monitor(E) spi_msm_geni(E) qcom_spmi_adc5(E) oplus_bsp_memleak_detect(OE) ipa_fmwk(E) msm_qmp(E) oplus_bsp_ir_core(E) qfprom_sys(E) cx_ipeak(E) oplus_bsp_dfr_ubt(E) guestvm_loader(E) qcom_cpufreq_hw_debug(E) rpm_smd_debug(E) leds_qpnp_flash_v2(E) tz_log_dlkm(OE) oplus_game_first(OE) shutdown_detect(E) Line 1548: 01-01 19:27:22.292323 4918 4918 W [ 59.508648]: oplus_networks_tuning(OE) pm8941_pwrkey(E) coresight_remote_etm(E) leds_aw2023(E) qti_qmi_sensor(E) usb_f_diag(E) rt_regmap(E) bcl_soc(E) cpu_hotplug(E) cnss_prealloc(OE) qcom_spmi_temp_alarm(E) oplus_security_guard(OE) qcom_spmi_adc_tm5(E) reboot_mode(E) regulator_cdev(E) i2c_msm_geni(E) qcom_iommu_debug(E) oplus_bsp_tp_ilitek_common(E) qrtr_smd(E) thermal_pause(E) ehset(E) msm_mmrm(OE) leds_qpnp_vibrator_ldo(E) ufcs_class(E) cpufreq_ondemand(E) game_opt(OE) coresight_tgu(E) oplus_data_module(OE) stm_console(E) oplus_audio_pa_manager(OE) qcom_pil_info(E) phy_msm_ssusb_qmp(E) msm_sharedmem(E) oplus_stability_helper(OE) phy_msm_qusb(E) iolimit(E) pmic_monitor(E) spi_msm_geni(E) qcom_spmi_adc5(E) oplus_bsp_memleak_detect(OE) ipa_fmwk(E) msm_qmp(E) oplus_bsp_ir_core(E) qfprom_sys(E) cx_ipeak(E) oplus_bsp_dfr_ubt(E) guestvm_loader(E) qcom_cpufreq_hw_debug(E) rpm_smd_debug(E) leds_qpnp_flash_v2(E) tz_log_dlkm(OE) oplus_game_first(OE) shutdown_detect(E) Line 1548: 01-01 19:27:22.292323 4918 4918 W [ 59.508648]: oplus_networks_tuning(OE) pm8941_pwrkey(E) coresight_remote_etm(E) leds_aw2023(E) qti_qmi_sensor(E) usb_f_diag(E) rt_regmap(E) bcl_soc(E) cpu_hotplug(E) cnss_prealloc(OE) qcom_spmi_temp_alarm(E) oplus_security_guard(OE) qcom_spmi_adc_tm5(E) reboot_mode(E) regulator_cdev(E) i2c_msm_geni(E) qcom_iommu_debug(E) oplus_bsp_tp_ilitek_common(E) qrtr_smd(E) thermal_pause(E) ehset(E) msm_mmrm(OE) leds_qpnp_vibrator_ldo(E) ufcs_class(E) cpufreq_ondemand(E) game_opt(OE) coresight_tgu(E) oplus_data_module(OE) stm_console(E) oplus_audio_pa_manager(OE) qcom_pil_info(E) phy_msm_ssusb_qmp(E) msm_sharedmem(E) oplus_stability_helper(OE) phy_msm_qusb(E) iolimit(E) pmic_monitor(E) spi_msm_geni(E) qcom_spmi_adc5(E) oplus_bsp_memleak_detect(OE) ipa_fmwk(E) msm_qmp(E) oplus_bsp_ir_core(E) qfprom_sys(E) cx_ipeak(E) oplus_bsp_dfr_ubt(E) guestvm_loader(E) qcom_cpufreq_hw_debug(E) rpm_smd_debug(E) leds_qpnp_flash_v2(E) tz_log_dlkm(OE) oplus_game_first(OE) shutdown_detect(E) Line 1549: 01-01 19:27:22.292414 4918 4918 W [ 59.508739]: qti_qmi_cdev(E) rpm_smd_cooling_device(E) rtc_pm8xxx(E) uff_fp_driver(E) bcl_pmic5(E) oplus_nfc(E) oplus_bsp_tp_comon(E) oplus_wifismartantenna(OE) qcom_sysmon(E) oplus_camera_wl2868c(E) oplus_stats_calc(OE) msm_performance(E) usb_f_cdev(E) dump_device_info(E) aw_breath_algorithm(E) frpc_adsprpc(E) qcom_lpm(E) phy_msm_snps_hs(E) f_fs_ipc_log(E) phy_qcom_emu(E) oplus_io_monitor(E) oplus_score(OE) coresight_stm(E) coresight_replicator(E) wcd_core_dlkm(OE) test_kit(E) refgen(E) qti_devfreq_cdev(E) wl2866d_regulator(E) oplus_sensor(E) q6_dlkm(OE) aw37004_regulator(E) fan53870(E) lmh_cpu_vdd_cdev(E) oplus_mm_kevent_fb(E) snd_usb_audio_qmi(E) cnss_utils(OE) q6_pdr_dlkm(OE) sg(E) oplus_freeze_process(OE) rdbg(E) oplus_binder_strategy(E) oplus_app_monitor(OE) snd_event_dlkm(OE) oplus_secure_harden(OE) oplus_qr_scan(OE) dispcc_sm6115(E) qcom_ramdump(E) qpnp_pdphy(E) pd_dbg_info(E) usb_bam(E) stm_p_basic(E) ordump(E) cfg80211(E) phy_generic(E) combkey_monitor(E) Line 1549: 01-01 19:27:22.292414 4918 4918 W [ 59.508739]: qti_qmi_cdev(E) rpm_smd_cooling_device(E) rtc_pm8xxx(E) uff_fp_driver(E) bcl_pmic5(E) oplus_nfc(E) oplus_bsp_tp_comon(E) oplus_wifismartantenna(OE) qcom_sysmon(E) oplus_camera_wl2868c(E) oplus_stats_calc(OE) msm_performance(E) usb_f_cdev(E) dump_device_info(E) aw_breath_algorithm(E) frpc_adsprpc(E) qcom_lpm(E) phy_msm_snps_hs(E) f_fs_ipc_log(E) phy_qcom_emu(E) oplus_io_monitor(E) oplus_score(OE) coresight_stm(E) coresight_replicator(E) wcd_core_dlkm(OE) test_kit(E) refgen(E) qti_devfreq_cdev(E) wl2866d_regulator(E) oplus_sensor(E) q6_dlkm(OE) aw37004_regulator(E) fan53870(E) lmh_cpu_vdd_cdev(E) oplus_mm_kevent_fb(E) snd_usb_audio_qmi(E) cnss_utils(OE) q6_pdr_dlkm(OE) sg(E) oplus_freeze_process(OE) rdbg(E) oplus_binder_strategy(E) oplus_app_monitor(OE) snd_event_dlkm(OE) oplus_secure_harden(OE) oplus_qr_scan(OE) dispcc_sm6115(E) qcom_ramdump(E) qpnp_pdphy(E) pd_dbg_info(E) usb_bam(E) stm_p_basic(E) ordump(E) cfg80211(E) phy_generic(E) combkey_monitor(E) Line 1549: 01-01 19:27:22.292414 4918 4918 W [ 59.508739]: qti_qmi_cdev(E) rpm_smd_cooling_device(E) rtc_pm8xxx(E) uff_fp_driver(E) bcl_pmic5(E) oplus_nfc(E) oplus_bsp_tp_comon(E) oplus_wifismartantenna(OE) qcom_sysmon(E) oplus_camera_wl2868c(E) oplus_stats_calc(OE) msm_performance(E) usb_f_cdev(E) dump_device_info(E) aw_breath_algorithm(E) frpc_adsprpc(E) qcom_lpm(E) phy_msm_snps_hs(E) f_fs_ipc_log(E) phy_qcom_emu(E) oplus_io_monitor(E) oplus_score(OE) coresight_stm(E) coresight_replicator(E) wcd_core_dlkm(OE) test_kit(E) refgen(E) qti_devfreq_cdev(E) wl2866d_regulator(E) oplus_sensor(E) q6_dlkm(OE) aw37004_regulator(E) fan53870(E) lmh_cpu_vdd_cdev(E) oplus_mm_kevent_fb(E) snd_usb_audio_qmi(E) cnss_utils(OE) q6_pdr_dlkm(OE) sg(E) oplus_freeze_process(OE) rdbg(E) oplus_binder_strategy(E) oplus_app_monitor(OE) snd_event_dlkm(OE) oplus_secure_harden(OE) oplus_qr_scan(OE) dispcc_sm6115(E) qcom_ramdump(E) qpnp_pdphy(E) pd_dbg_info(E) usb_bam(E) stm_p_basic(E) ordump(E) cfg80211(E) phy_generic(E) combkey_monitor(E) Line 1550: 01-01 19:27:22.292523 4918 4918 W [ 59.508848]: stm_core(E) keyevent_handler(E) qcom_pm8008_regulator(E) ocp2130_bias(E) coresight(E) oplus_bsp_rfcablemonitor(E) oplus_secure_common(OE) oplus_security_keventupload(OE) qcom_vadc_common(E) icc_test(E) hung_task_enhance(E) oplus_mm_kevent(E) qti_battery_debug(E) oplus_bsp_fw_update(E) charger_ulog_glink(E) msm_tsens_driver(E) sps_drv(E) debugcc_sm6115(E) msm_geni_serial(E) usb_f_ccid(E) qcom_va_minidump(E) msm_lmh_dcvs(E) qpnp_lcdb_regulator(E) oplus_bsp_tp_custom(E) oplus_bsp_tp_notify(E) qcom_i2c_pmic(E) oplus_resctrl(E) ucsi_glink(E) oplus_bsp_sensor_feedback(E) init_watchdog(E) olc(E) hung_task_enh(E) pmic_glink_debug(E) oplus_exit_mm_optimize(E) bwmon(E) altmode_glink(E) oplus_bsp_mapped_protect(E) oplus_theia(E) phy_msm_qusb_v2(E) memlat(E) core_hang_detect(E) gpucc_sm6115(E) boot_stats(E) pmic_glink(E) rpm_master_stat(E) debugcc_khaje(E) dispcc_khaje(E) rq_stats(E) glink_pkt(E) cdsprm(E) oplus_bsp_dynamic_readahead(E) msm_gpi(E) cdsp_loader(E) eud(E) Line 1550: 01-01 19:27:22.292523 4918 4918 W [ 59.508848]: stm_core(E) keyevent_handler(E) qcom_pm8008_regulator(E) ocp2130_bias(E) coresight(E) oplus_bsp_rfcablemonitor(E) oplus_secure_common(OE) oplus_security_keventupload(OE) qcom_vadc_common(E) icc_test(E) hung_task_enhance(E) oplus_mm_kevent(E) qti_battery_debug(E) oplus_bsp_fw_update(E) charger_ulog_glink(E) msm_tsens_driver(E) sps_drv(E) debugcc_sm6115(E) msm_geni_serial(E) usb_f_ccid(E) qcom_va_minidump(E) msm_lmh_dcvs(E) qpnp_lcdb_regulator(E) oplus_bsp_tp_custom(E) oplus_bsp_tp_notify(E) qcom_i2c_pmic(E) oplus_resctrl(E) ucsi_glink(E) oplus_bsp_sensor_feedback(E) init_watchdog(E) olc(E) hung_task_enh(E) pmic_glink_debug(E) oplus_exit_mm_optimize(E) bwmon(E) altmode_glink(E) oplus_bsp_mapped_protect(E) oplus_theia(E) phy_msm_qusb_v2(E) memlat(E) core_hang_detect(E) gpucc_sm6115(E) boot_stats(E) pmic_glink(E) rpm_master_stat(E) debugcc_khaje(E) dispcc_khaje(E) rq_stats(E) glink_pkt(E) cdsprm(E) oplus_bsp_dynamic_readahead(E) msm_gpi(E) cdsp_loader(E) eud(E) Line 1552: 01-01 19:27:22.292697 4918 4918 W [ 59.509022]: gcc_khaje(E) oplus_bsp_task_sched(E) gcc_sm6115(E) mem_buf(E) qcom_dma_heaps(E) qseecom_dlkm(OE) oplus_kmsg_wb(E) phy_qcom_ufs_qmp_v3_660(E) phy_qcom_ufs_qrbtc_sdm845(E) phy_qcom_ufs_qmp_v4_khaje(E) qrtr(E) qcom_glink(E) qnoc_bengal(E) qcom_soc_wdt(E) ua_cpu_ioctl(E) smp2p(E) ufshcd_crypto_qti(E) usbpd(E) clk_qcom(E) crypto_qti_common(E) dcc_v2(E) device_info(E) icc_rpm(E) mem_buf_dev(E) oplus_bsp_frame_boost(E) mem_offline(E) memory_dump_v2(E) msm_poweroff(E) oplus_phoenix(E) pinctrl_bengal(E) oplus_schedinfo(E) qcom_iommu_util(E) phy_qcom_ufs(E) oplus_pmicwd(E) pinctrl_khaje(E) qcom_ipc_logging(E) qcom_logbuf_vh(E) rpm_smd_regulator(E) qcom_wdt_core(E) boot_mode(E) gdsc_regulator(E) crypto_qti_tz(E) minidump(E) oplus_bsp_sched_assist(E) oplus_project(E) oplus_mdmfeature(E) oplus_uprobe(E) pinctrl_msm(E) phoenix_reboot_speed(E) qcom_cpufreq_hw(E) qcom_spmi_pmic(E) qcom_smd(E) secure_buffer(E) socinfo(E) rpm_smd(E) qpnp_power_on(E) stub_regulator(E) 这个是对应时间的kernel日志
最新发布
08-13
<think>我们分析日志中与ADB、USB、adbd服务相关的错误或异常信息,以确定设备重启后ADB连接失败的原因。 根据日志,我们注意到以下关键点: 1. **adbd启动过程**: - Line 3511: adbd started - Line 3513: 尝试打开控制端点 `/dev/usb-ffs/adb/ep0` - Line 3514: 等待属性 `persist.adb.tls_server.enable=1`(这通常与网络ADB有关,但我们现在关注USB ADB) - Line 3517: 构造了UsbFfsConnection对象 - Line 3526: 启动了UsbFfs-monitor线程 2. **FUNCTIONFS_BIND超时**: - Line 4331: 第一次超时:`timed out while waiting for FUNCTIONFS_BIND, trying again` - Line 6044: 第二次超时:同样等待FUNCTIONFS_BIND超时 - Line 6726: 第三次尝试启动了UsbFfs-monitor线程 - Line 7858: 第三次尝试中,成功接收到USB事件:`USB event: FUNCTIONFS_BIND` 3. **USB状态变化**: - 在设备启动过程中,USB相关的服务(UsbDeviceManager)也在启动,但出现了一些错误: - Line 29901: `failed to write to /sys/class/android_usb/android0/f_rndis/ethaddr`(可能是由于设备尚未完全初始化) - Line 29915: `connectToProxy: usb gadget hidl hal service not found.`(表明无法连接到USB Gadget HAL服务) - Line 29935: `USB Gadget HAL AIDL/HIDL not present`(再次确认USB Gadget HAL不可用) - 但是,随后UsbPortManager成功连接到了HIDL服务(Line 30082: `USB HAL HIDL present`) 4. **USB端口状态**: - Line 46245: 检测到USB端口已连接(`connected=true`),模式为`ufp`(表示设备处于从设备模式),数据角色为`device`(设备模式)。 - 在boot完成后(Line 77542),UsbDeviceManager广播了USB状态(Line 77621): `Bundle[{host_connected=false, connected=false, unlocked=false, adb=true, configured=false}]` 这里显示`connected=false`和`configured=false`,表明USB连接尚未配置成功。 5. **ADB认证开始**: - Line 77814: `adbd_auth: received a new framework connection` 和 `received new framework fd 16`,这表明adbd已经与框架层建立了连接,用于ADB认证。 6. **后续日志**: - 在boot完成后,我们看到一些与ADB相关的包(com.google.android.adbd)被处理,但并没有明显的错误。 7. **关键问题**: - 在adbd启动初期,连续两次尝试绑定USB FunctionFS都失败了(等待FUNCTIONFS_BIND事件超时),直到第三次尝试才成功。这可能是由于USB子系统初始化较慢,导致adbd在启动时无法立即绑定。 **原因分析**: - 根本原因在于adbd启动时,USB子系统尚未准备好,导致前两次绑定尝试超时。虽然第三次尝试成功,但此时adbd可能已经进入了一个不正确的状态,或者由于前两次失败导致后续处理异常(尽管日志中没有直接体现)。 - 另外,USB Gadget HAL服务在启动初期不可用(`usb gadget hidl hal service not found`),这也表明USB子系统初始化较慢。 - 在设备重启后,USB连接状态被报告为未连接(`connected=false`)和未配置(`configured=false`),尽管物理上可能已经连接(从UsbPortManager的日志看端口是连接的)。这可能是因为USB配置过程尚未完成。 **解决方案**: 1. **延迟adbd的启动**:确保adbd在USB子系统初始化完成后再启动。可以通过修改init.rc脚本,将adbd的启动顺序调整到USB服务之后,或者添加一个等待USB就绪的条件。 例如,在init.rc中,将adbd的启动从`class core`改为`class late_start`,并添加依赖条件: ``` service adbd /system/bin/adbd class late_start disabled oneshot ``` 同时,可以添加一个属性触发器,当USB准备好后再启动adbd: ``` on property:sys.usb.state=configured start adbd ``` 但注意,这可能会延迟ADB的可用时间。 2. **增加重试机制和超时时间**:修改adbd源码,增加对FUNCTIONFS_BIND事件的等待时间,并增加重试次数。目前从日志看,adbd在超时后会重试(共尝试了三次),但前两次间隔1秒(从时间戳看:19:26:38.570启动监控线程,19:26:39.572超时,然后19:26:39.642再次尝试,19:26:40.669超时,19:26:40.815第三次尝试,19:26:41.384成功)。我们可以考虑将超时时间从当前的1秒增加到5秒,并增加重试次数。 3. **确保USB Gadget驱动正确加载**:检查内核配置,确保FunctionFS驱动(CONFIG_USB_CONFIGFS_F_FS)已启用,并确保驱动模块已正确加载。 4. **检查USB物理连接**:虽然重新插拔后可以恢复,但重启后不行,这可能是因为重启过程中USB主机控制器复位导致设备端需要重新枚举,而软件没有正确处理。可以尝试在设备启动完成后,强制复位USB控制器: ``` echo 0 > /sys/class/android_usb/android0/enable echo 1 > /sys/class/android_usb/android0/enable ``` 5. **检查USB权限**:确保adbd有权限访问`/dev/usb-ffs/adb/`下的设备节点。在日志中没有看到权限错误,但需要确认。 **验证方法**: 修改后,重启设备,观察日志中是否还会出现`timed out while waiting for FUNCTIONFS_BIND`。如果不再出现,并且adbd在启动后能够成功绑定USB,则问题解决。 根据提供的日志,我们推测主要原因是adbd启动过早,而USB子系统尚未准备好。因此,延迟adbd启动是最直接的解决方案。 相关问题: 1. 如何修改Android设备的init.rc文件而不影响OTA更新? 2. 在Android系统中,USB子系统的初始化流程是怎样的? 3. adbd的启动顺序如何控制? 4. 如何增加adbd对FUNCTIONFS_BIND事件的等待时间和重试次数? 5. 如何通过内核调试手段诊断USB FunctionFS绑定问题?</think>### 设备重启后ADB连接失败原因分析 通过日志分析,发现重启后ADB连接失败的根本原因是**USB子系统初始化时序问题**导致FUNCTIONFS_BIND超时。以下是详细分析: #### 一、核心问题:FUNCTIONFS_BIND超时 ```log Line 4331: 01-01 19:26:39.572 W adbd timed out while waiting for FUNCTIONFS_BIND Line 6044: 01-01 19:26:40.669 W adbd timed out while waiting for FUNCTIONFS_BIND Line 6726: 01-01 19:26:40.820 I adbd UsbFfs-monitor thread spawned Line 7858: 01-01 19:26:41.384 I adbd USB event: FUNCTIONFS_BIND # 第三次尝试才成功 ``` **关键问题**: 1. **时序冲突**:ADB服务(adbd)启动时($t=19:26:38.543$),USB控制器尚未完成初始化 2. **超时机制**:adbd等待FUNCTIONFS_BIND信号的超时时间仅1秒(从Line 3526到4331) 3. **重试机制**:系统进行了3次尝试(第3次成功),但前两次均失败 数学关系: $$ t_{\text{adbd\_start}} + \Delta t_{\text{timeout}} < t_{\text{usb\_ready}} $$ 其中$\Delta t_{\text{timeout}}=1s$,而实际USB就绪时间为$t=19:26:41.384$(相差约2.8秒) #### 二、根本原因链式分析 ```mermaid graph TD A[设备重启] --> B[adbd过早启动] B --> C[USB控制器未就绪] C --> D[FUNCTIONFS_BIND超时] D --> E[USB资源释放失败] E --> F[后续绑定尝试失败] F --> G[ADB连接不可用] ``` 1. **USB服务初始化延迟** (关键证据) ```log Line 29915: E UsbDeviceManager connectToProxy: usb gadget hidl hal service not found Line 29935: E UsbPortManager USB Gadget HAL AIDL/HIDL not present Line 30082: I UsbPortManager USB HAL HIDL present # 延迟548ms后才就绪 ``` 2. **资源冲突问题** ```log Line 29901: I UsbDeviceManager failed to write to /sys/class/android_usb/android0/f_rndis/ethaddr ``` 表明RNDIS(网络共享)驱动正在占用USB资源,与ADB产生冲突[^1] 3. **权限配置异常** ```log Line 20634: W PackageSettings Couldn't write -1 to /config/sdcardfs/com.google.android.adbd/appid Line 82329: W PackageManager Skipping preparing app data for com.google.android.adbd ``` ADB相关包(com.google.android.adbd)的数据目录准备失败 #### 三、USB状态机异常 ```log Line 77621: D UsbDeviceManager broadcasting Intent... extras: Bundle[{host_connected=false, connected=false, adb=true, configured=false}] ``` **状态机缺陷**: - `adb=true` 表明ADB功能已启用 - `configured=false` 表示USB未完成配置 - 这种矛盾状态导致ADB无法正常响应主机请求 #### 四、解决方案 1. **延迟adbd启动** (最优解) 修改`init.rc`: ```rc service adbd /system/bin/adbd class late_start # 从core改为late_start disabled oneshot ``` 2. **增加超时时间** 修改ADB源码(`system/core/adb/daemon/usb_ffs.cpp`): ```cpp // 默认值1000ms -> 改为5000ms static constexpr uint64_t kBindTimeout = 5000; ``` 3. **强制USB重新枚举** ```shell echo 0 > /sys/class/android_usb/android0/enable echo 1 > /sys/class/android_usb/android0/enable ``` 4. **解决资源冲突** ```shell setprop persist.vendor.usb.config adb # 禁用其他USB功能 stop mtpd # 停止可能冲突的服务 ``` #### 五、验证方法 ```shell # 检查USB状态 adb shell cat /sys/class/android_usb/android0/state # 监控初始化时序 adb logcat -b all | grep -e "UsbPortManager" -e "adbd started" # 检查绑定状态 adb shell ls -l /dev/usb-ffs/adb/ep* ``` --- ### 相关问题 1. 如何在Android系统中精确控制服务的启动顺序? 2. 当USB Gadget HAL不可用时,系统有哪些备用机制? 3. 如何动态调整ADB的FUNCTIONFS_BIND超时参数而不重新编译? 4. 在双系统设备中,USB控制器初始化有哪些特殊挑战? 5. 如何通过内核事件跟踪(ftrace)诊断USB初始化延迟? [^1]: 当多个USB功能同时启用时可能产生资源冲突 [^2]: USB HAL初始化延迟导致关键服务不可用 [^3]: ADB绑定超时机制在系统压力下可能失效
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值