当前位置: 首页 > news >正文

cnzz统计代码如何添加到网站上去seo岗位培训

cnzz统计代码如何添加到网站上去,seo岗位培训,写作网站大全,wordpress写博客流行吗原文网址#xff08;转载请注明出处#xff09;#xff1a; 链接#xff1a;http://t.csdnimg.cn/VxZsA 源码基于#xff1a;Android Q 文章目录 1.USB驱动介绍2.charger-manager拔插事件分发 在展锐8541平台上加载了extcon-usb-gpio 驱动#xff0c;这个驱动可以检测…原文网址转载请注明出处 链接http://t.csdnimg.cn/VxZsA 源码基于Android Q 文章目录 1.USB驱动介绍2.charger-manager拔插事件分发 在展锐8541平台上加载了extcon-usb-gpio 驱动这个驱动可以检测USB 的插拔动作。 1.USB驱动介绍 USB驱动文件 bsp/kernel/kernel4.14/drivers/extcon/Makefile... obj-$(CONFIG_EXTCON_USB_GPIO) extcon-usb-gpio.o ...代码 bsp/kernel/kernel4.14/drivers/extcon/extcon-usb-gpio.cstatic const struct of_device_id usb_extcon_dt_match[] {{ .compatible linux,extcon-usb-gpio, },{ /* sentinel */ } };static struct platform_driver usb_extcon_driver {.probe usb_extcon_probe, // probe 函数驱动匹配到了对应的设备后会调用此函数.remove usb_extcon_remove, // 设备移除后会调用此函数.driver {.name extcon-usb-gpio,.pm usb_extcon_pm_ops,.of_match_table usb_extcon_dt_match, // 用于匹配dts文件里的设备如果有compatible 相同的设备后才会调用probe 函数},.id_table usb_extcon_platform_ids, };module_platform_driver(usb_extcon_driver); // 该驱动的入口函数接着查看probe 函数里面有两个中断分别是id-gpio和 vbus-gpio bsp/kernel/kernel4.14/drivers/extcon/extcon-usb-gpio.cstatic int usb_extcon_probe(struct platform_device *pdev) {...info-id_gpiod devm_gpiod_get_optional(pdev-dev, id, GPIOD_IN);info-vbus_gpiod devm_gpiod_get_optional(pdev-dev, vbus, GPIOD_IN);...if (info-id_gpiod)// 用于防抖的ret gpiod_set_debounce(info-id_gpiod, USB_GPIO_DEBOUNCE_MS * 1000);if (!ret info-vbus_gpiod)ret gpiod_set_debounce(info-vbus_gpiod, USB_GPIO_DEBOUNCE_MS * 1000);...if (info-id_gpiod) {info-id_irq gpiod_to_irq(info-id_gpiod); // 将id-gpio 口设置为中断模式...// 设置中断条件发生中断是调用usb_irq_handler() 方法当GPIO 上拉或者下拉时触发中断ret devm_request_threaded_irq(dev, info-id_irq, NULL,usb_irq_handler,IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING | IRQF_ONESHOT,pdev-name, info);...}if (info-vbus_gpiod) {info-vbus_irq gpiod_to_irq(info-vbus_gpiod); // 将vbus-gpio 口设置为中断模式...// 设置中断条件发生中断是调用usb_irq_handler() 方法当GPIO 上拉或者下拉时触发中断ret devm_request_threaded_irq(dev, info-vbus_irq, NULL,usb_irq_handler,IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING | IRQF_ONESHOT,pdev-name, info);...}... }当id-gpio 和 vbus-gpio 口上拉或者下拉时触发中断调用usb_irq_handler() 中断上拉或者下拉代表USB 的插入和拔出。 bsp/kernel/kernel4.14/drivers/extcon/extcon-usb-gpio.cstatic irqreturn_t usb_irq_handler(int irq, void *dev_id) {struct usb_extcon_info *info dev_id;queue_delayed_work(system_power_efficient_wq, info-wq_detcable,info-debounce_jiffies);return IRQ_HANDLED; }static int usb_extcon_probe(struct platform_device *pdev) {...INIT_DELAYED_WORK(info-wq_detcable, usb_extcon_detect_cable); // 初始化工作队列wq_detcable 为usb_extcon_detect_cable() 方法... }static void usb_extcon_detect_cable(struct work_struct *work) {int id, vbus;struct usb_extcon_info *info container_of(to_delayed_work(work),struct usb_extcon_info,wq_detcable);/* check ID and VBUS and update cable state */id info-id_gpiod ?gpiod_get_value_cansleep(info-id_gpiod) : 1;vbus info-vbus_gpiod ?gpiod_get_value_cansleep(info-vbus_gpiod) : id;/* at first we clean states which are no longer active */if (id)extcon_set_state_sync(info-edev, EXTCON_USB_HOST, false);if (!vbus)extcon_set_state_sync(info-edev, EXTCON_USB, false);if (!id) {extcon_set_state_sync(info-edev, EXTCON_USB_HOST, true);} else {if (vbus)extcon_set_state_sync(info-edev, EXTCON_USB, true);} }在USB插拔触发中断时会调用info-wq_detcable 工作队列即会调用usb_extcon_detect_cable() 方法之后会通过extcon_set_state_sync() 方法设置USB 的状态 bsp/kernel/kernel4.14/drivers/extcon/extcon.cint extcon_set_state_sync(struct extcon_dev *edev, unsigned int id, bool state) {int ret, index;unsigned long flags;index find_cable_index_by_id(edev, id);if (index 0)return index;/* Check whether the external connectors state is changed. */spin_lock_irqsave(edev-lock, flags);ret is_extcon_changed(edev, index, state); // 检查USB状态是否发生了变化spin_unlock_irqrestore(edev-lock, flags);if (!ret)return 0;ret extcon_set_state(edev, id, state); // 设置USB 的连接状态但是不会通知USB 状态的改变if (ret 0)return ret;return extcon_sync(edev, id); // 设置USB 的连接状态并通知其他模块 } EXPORT_SYMBOL_GPL(extcon_set_state_sync);int extcon_sync(struct extcon_dev *edev, unsigned int id) {...// 通过这个方法通知某个注册了USB 状态改变的模块raw_notifier_call_chain(edev-nh[index], state, edev);// 通过这个方法通知所有注册了USB 状态改变的模块raw_notifier_call_chain(edev-nh_all, state, edev);...kobject_uevent_env(edev-dev.kobj, KOBJ_CHANGE, envp); // 通过UEvent 通知用户空间USB发生了改变free_page((unsigned long)prop_buf);return 0; } EXPORT_SYMBOL_GPL(extcon_sync);bsp/kernel/kernel4.14/kernel/notifier.cint raw_notifier_call_chain(struct raw_notifier_head *nh,unsigned long val, void *v) {return __raw_notifier_call_chain(nh, val, v, -1, NULL); } EXPORT_SYMBOL_GPL(raw_notifier_call_chain);int __raw_notifier_call_chain(struct raw_notifier_head *nh,unsigned long val, void *v,int nr_to_call, int *nr_calls) {return notifier_call_chain(nh-head, val, v, nr_to_call, nr_calls); } EXPORT_SYMBOL_GPL(__raw_notifier_call_chain);static int notifier_call_chain(struct notifier_block **nl,unsigned long val, void *v,int nr_to_call, int *nr_calls) {int ret NOTIFY_DONE;struct notifier_block *nb, *next_nb;nb rcu_dereference_raw(*nl);// 循环读取所有的notifier_block, 然后调用它的notifier_call() 方法while (nb nr_to_call) {next_nb rcu_dereference_raw(nb-next);...ret nb-notifier_call(nb, val, v);if (nr_calls)(*nr_calls);if (ret NOTIFY_STOP_MASK)break;nb next_nb;nr_to_call--;}return ret; } NOKPROBE_SYMBOL(notifier_call_chain);从log分析可以看到nb-notifier_call() 方法会调用sprd_hsphy_vbus_notify() 方法 [14:53:40:749] [ 51.173699] c2 [c0111ebc] (unwind_backtrace) from [c010ced0] (show_stack0x20/0x24)␍␊ [14:53:40:757] [ 51.181677] c2 [c010ced0] (show_stack) from [c0b13884] (dump_stack0xa4/0xd8)␍␊ [14:53:40:761] [ 51.189129] c2 [c0b13884] (dump_stack) from [c06c8f18] (sprd_hsphy_vbus_notify0x48/0x30c)␍␊ [14:53:40:774] [ 51.197722] c2 [c06c8f18] (sprd_hsphy_vbus_notify) from [c014f0a0] (notifier_call_chain0x74/0xac)␍␊ [14:53:40:779] [ 51.207006] c2 [c014f0a0] (notifier_call_chain) from [c014f12c] (raw_notifier_call_chain0x28/0x30)␍␊ [14:53:40:792] [ 51.216371] c2 [c014f12c] (raw_notifier_call_chain) from [c0880468] (extcon_sync0x78/0x1e4)␍␊ [14:53:40:801] [ 51.225137] c2 [c0880468] (extcon_sync) from [c0880bcc] (extcon_set_state_sync0x7c/0x90)␍␊ [14:53:40:806] [ 51.233639] c2 [c0880bcc] (extcon_set_state_sync) from [c0881e60] (usb_extcon_detect_cable0xa8/0xac)␍␊ [14:53:40:815] [ 51.243185] c2 [c0881e60] (usb_extcon_detect_cable) from [c0147d40] (process_one_work0x290/0x4a8)␍␊ [14:53:40:825] [ 51.252466] c2 [c0147d40] (process_one_work) from [c0148590] (worker_thread0x2f8/0x478)␍␊ [14:53:40:833] [ 51.260887] c2 [c0148590] (worker_thread) from [c014d564] (kthread0x148/0x164)␍␊ [14:53:40:844] [ 51.268519] c2 [c014d564] (kthread) from [c0108814] (ret_from_fork0x14/0x20)接着查看sprd_hsphy_vbus_notify() 方法的流程 bsp/kernel/kernel4.14/drivers/usb/phy/phy-sprd-sharkle.cstatic int sprd_hsphy_vbus_notify(struct notifier_block *nb,unsigned long event, void *data) {struct usb_phy *usb_phy container_of(nb, struct usb_phy, vbus_nb);struct sprd_hsphy *phy container_of(usb_phy, struct sprd_hsphy, phy);...// event 的值是我们传入的USB 状态(state),state 1 表示USB 插入否则没有插入if (event) {/* usb vbus valid */reg readl_relaxed(phy-base REG_AP_AHB_OTG_PHY_TEST);reg | (MASK_AP_AHB_OTG_VBUS_VALID_EXT |MASK_AP_AHB_OTG_VBUS_VALID_PHYREG);writel_relaxed(reg, phy-base REG_AP_AHB_OTG_PHY_TEST);usb_phy_set_charger_state(usb_phy, USB_CHARGER_PRESENT);} else {/* usb vbus invalid */reg readl_relaxed(phy-base REG_AP_AHB_OTG_PHY_TEST);reg ~(MASK_AP_AHB_OTG_VBUS_VALID_PHYREG |MASK_AP_AHB_OTG_VBUS_VALID_EXT);writel_relaxed(reg, phy-base REG_AP_AHB_OTG_PHY_TEST);usb_phy_set_charger_state(usb_phy, USB_CHARGER_ABSENT);}return 0; }bsp/kernel/kernel4.14/drivers/usb/phy/phy.cvoid usb_phy_set_charger_state(struct usb_phy *usb_phy,enum usb_charger_state state) {...usb_phy-chg_state state;if (usb_phy-chg_state ! USB_CHARGER_PRESENT)usb_phy-chg_type UNKNOWN_TYPE;schedule_work(usb_phy-chg_work); } EXPORT_SYMBOL_GPL(usb_phy_set_charger_state);static void usb_charger_init(struct usb_phy *usb_phy) {usb_phy-chg_type UNKNOWN_TYPE;usb_phy-chg_state USB_CHARGER_DEFAULT;usb_phy_set_default_current(usb_phy);INIT_WORK(usb_phy-chg_work, usb_phy_notify_charger_work); // 初始化usb_phy-chg_work 工作队列 }调用usb_phy_set_charger_state() 方法后会调用usb_phy_notify_charger_work() 方法 bsp/kernel/kernel4.14/drivers/usb/phy/phy.cstatic void usb_phy_notify_charger_work(struct work_struct *work) {...// 判断USB的插入状态如果是插入状态则走USB_CHARGER_PRESENT 分支switch (usb_phy-chg_state) {case USB_CHARGER_PRESENT:if (usb_phy-chg_type UNKNOWN_TYPE)usb_phy-chg_type usb_phy-charger_detect(usb_phy);usb_phy_get_charger_current(usb_phy, min, max);atomic_notifier_call_chain(usb_phy-notifier, max, usb_phy); //调用usb_phy中注册的回调方法snprintf(uchger_state, ARRAY_SIZE(uchger_state),USB_CHARGER_STATE%s, USB_CHARGER_PRESENT);break;case USB_CHARGER_ABSENT:usb_phy_set_default_current(usb_phy);atomic_notifier_call_chain(usb_phy-notifier, 0, usb_phy); //调用usb_phy中注册的回调方法snprintf(uchger_state, ARRAY_SIZE(uchger_state),USB_CHARGER_STATE%s, USB_CHARGER_ABSENT);break;default:...// 使用ueven 通知方法通知用户kobject_uevent_env(usb_phy-dev-kobj, KOBJ_CHANGE, envp); }bsp/kernel/kernel4.14/kernel/notifier.cint atomic_notifier_call_chain(struct atomic_notifier_head *nh,unsigned long val, void *v) {return __atomic_notifier_call_chain(nh, val, v, -1, NULL); }int __atomic_notifier_call_chain(struct atomic_notifier_head *nh,unsigned long val, void *v,int nr_to_call, int *nr_calls) {...ret notifier_call_chain(nh-head, val, v, nr_to_call, nr_calls);...return ret; }static int notifier_call_chain(struct notifier_block **nl,unsigned long val, void *v,int nr_to_call, int *nr_calls) {...nb rcu_dereference_raw(*nl); // 这个nb 是usb_phy 通知块的头部块// 回调所有注册的notifier_call 函数while (nb nr_to_call) {next_nb rcu_dereference_raw(nb-next);...ret nb-notifier_call(nb, val, v);if (nr_calls)(*nr_calls);if (ret NOTIFY_STOP_MASK)break;nb next_nb;nr_to_call--;}return ret; }从usb_phy_notify_charger_work() 方法传入的nh是usb_phy。 2.charger-manager拔插事件分发 以charger-manager 为例在charger-manager.c 的charger_manager_policy_init() 方法中注册了usb_phy.notifier_call 方法 bsp/kernel/kernel4.14/drivers/power/supply/charger-manager.cstatic int charger_manager_policy_init(struct charger_manager *cm) {...cm-policy.usb_notify.notifier_call policy_usb_change_callback;ret usb_register_notifier(cm-policy.usb_phy, cm-policy.usb_notify);... }bsp/kernel/kernel4.14/include/linux/usb/phy.hstatic inline int usb_register_notifier(struct usb_phy *x, struct notifier_block *nb) {return atomic_notifier_chain_register(x-notifier, nb); }bsp/kernel/kernel4.14/kernel/notifier.cint atomic_notifier_chain_register(struct atomic_notifier_head *nh,struct notifier_block *n) {...ret notifier_chain_register(nh-head, n);... }// 将usb_notify 通知块添加到usb_phy 里通知块的头部 static int notifier_chain_register(struct notifier_block **nl,struct notifier_block *n) {while ((*nl) ! NULL) {if (n-priority (*nl)-priority)break;nl ((*nl)-next);}n-next *nl;rcu_assign_pointer(*nl, n);return 0; }所以在我们插入USB时会调用到charger-manager.c::policy_usb_change_callback() 方法
http://www.w-s-a.com/news/854617/

相关文章:

  • 北京网站建设成都微商城app官方下载
  • 网站开发用户登陆的安全wordpress 开发网站
  • 网站建设容易出现的问题四川seo关键词工具
  • 做外单网站有哪些内容服务好的南京网站建设
  • 阜阳微商城网站建设百度网站两两学一做心得体会
  • 建设银行积分网站观光农业规划设计
  • jsp项目个人网站开发用织梦做网站有什么公司会要
  • 和田网站制作无限动力网站
  • 长沙口碑好网站建设企业网站 需求
  • 哪个网站建设公司wordpress陌陌主题
  • 湖滨区建设局网站北京国际建设集团网站
  • 做服装团购有哪些网站wordpress 端口修改
  • 上海礼品定制网站响应式网站模版建站
  • 那种自行提取卡密的网站怎么做网站攻击
  • 洛阳免费网站建设qq是哪家公司开发的软件
  • 怎么做网站网页wordpress网址导航
  • 专业微信网站建设公司首选公司wordpress自动分类插件
  • 网站设计登录界面怎么做网站突然排名没了
  • wordpress 人物页面seo优化公司信
  • 高端网站建设报价网站建设需要硬件设备
  • 做国际物流在哪些网站找客户营销qq怎么申请
  • 网站做推广百度好还是360好科技厅
  • 网站开发工具排名万户网络建一个网站虽要多少钱
  • 用凡科做的网站要钱吗WordPress城市切换
  • 制作一个门户网站需要多少钱营销型网站特征
  • 手机网站 多html中国建设银行网站包头分行
  • 哪个网站做免费广告好招牌图片效果图设计制作
  • 网站建设优化服务机构苏州市做网站
  • 网站如何优化流程企业网站管理系统视频教程
  • 我想克隆个网站 怎么做贵州住房和城乡建设厅官网