作者 | 小南瓜地瓜
责编 | 郭芮

最近在调试项目的亮屏速度,我们希望在按下power键后到亮屏这个时间能达到500MS以内,在Rockchip 3399和3288上面的时间都不能达到要求,因此引发了一系列的调试之路。

计算按下power键到亮屏的时间

Android 唤醒时间统计

刚开始的时候,我只在android阶段统计时间,也能看到时间的差异,但是不是最准确的,我统计的时间日志如下:

01-18 09:13:40.992 683 772 D SurfaceControl: Excessive delay in setPowerMode(): 743ms01-18 09:13:45.304 683 772 D SurfaceControl: Excessive delay in setPowerMode(): 757ms01-18 09:13:49.559 683 772 D SurfaceControl: Excessive delay in setPowerMode(): 725ms01-18 09:18:27.461 683 772 D SurfaceControl: Excessive delay in setPowerMode(): 741ms01-18 09:18:32.766 683 772 D SurfaceControl: Excessive delay in setPowerMode(): 743ms01-18 09:18:35.861 683 772 D SurfaceControl: Excessive delay in setPowerMode(): 745ms01-18 09:18:38.345 683 772 D SurfaceControl: Excessive delay in setPowerMode(): 733ms

Kernel从Power到亮屏的时间统计

后来同事中的精英古总在他的代码上加入了从按下Power键到亮屏的时间,直接通过printk打印,代码如下:

diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.cold mode 100644new mode 100755index 17c3b94..2b39662--- a/drivers/gpu/drm/panel/panel-simple.c+++ b/drivers/gpu/drm/panel/panel-simple.c@@ -504,6 +504,7 @@ static int panel_simple_enable(struct drm_panel *panel)        }

        p->enabled = true;+       printk("%s exit\n", __func__);

        return 0; }diff --git a/drivers/input/keyboard/rk_keys.c b/drivers/input/keyboard/rk_keys.cold mode 100644new mode 100755index fed5ced..537b599--- a/drivers/input/keyboard/rk_keys.c+++ b/drivers/input/keyboard/rk_keys.c@@ -134,6 +134,10 @@ static void keys_timer(unsigned long _data)                key_dbg(pdata, "%skey[%s]: report event[%d] state[%d]\n",                        button->type == TYPE_ADC ? "adc" : "gpio",                        button->desc, button->code, button->state);+               if(strcmp(button->desc, "power") == 0)+               printk("%skey[%s]: report event[%d] state[%d]\n",+                       button->type == TYPE_ADC ? "adc" : "gpio",+                       button->desc, button->code, button->state);                input_event(input, EV_KEY, button->code, button->state);                input_sync(input);        }

统计每个驱动的resume函数调用时间

上面的时间对我们调试非常有用,然后就需要细分到每个驱动的resume函数执行的时间,用的方法是我之前写过的,大概统计了下TP,LCD,sensor的resume时间,发现TP和LCD占用的时间非常多,然后跟同事一起看了下,同事把TP resume里面的代码用工作队列实现后速度明显有了提升。

然后有很长一段时间不知道干嘛,想打印其他每个驱动的resume时间,一直没找到方法,后面看到一个代码,非常有用。

kernel/drivers/base/power/main.c

static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info)                                                       {                    ktime_t calltime;    u64 usecs64;    int usecs;

    calltime = ktime_get();    usecs64 = ktime_to_ns(ktime_sub(calltime, starttime));    do_div(usecs64, NSEC_PER_USEC);    usecs = usecs64;    if (usecs == 0)        usecs = 1;     pr_info("PM: %s%s%s of devices complete after %ld.%03ld msecs\n",        info ?: "", info ? " " : "", pm_verb(state.event),        usecs / USEC_PER_MSEC, usecs % USEC_PER_MSEC);}   

这个函数用来打印resume的函数消耗的时间,但是如何去触发打印这个函数呢?

  • 一定保证设备进入深度睡眠,串口也进入深度睡眠,没有任何打印后。

  • 执行以下命令:

echo N > /sys/module/printk/parameters/console_suspend//使控制台在suspend最后才关闭,这样可以打印出休眠过程完整信息echo 1 > /sys/power/pm_print_times//使能调试变量

打印的LOG类似下面的:

[ 37.031413] bcmsdh_sdmmc_resume Exit[ 37.082174] PM: resume of devices complete after 78.589 msecs[ 37.085277] [BT_RFKILL]: ** disable irq[ 37.087645] Restarting tasks ... 

修改Lcd配置减小resume时间

古总在调试过程中展现了非常厉害的功底,第一步就是修改了LCD的参数,让亮屏时间加快。修改如下:

--- a/arch/arm/boot/dts/rk3288-pad.dts+++ b/arch/arm/boot/dts/rk3288-pad.dts@@ -169,10 +169,10 @@                dsi,lanes = <4>;

                prepare-delay-ms = <20>;-               init-delay-ms = <20>;-               enable-delay-ms = <100>;-               disable-delay-ms = <20>;-               unprepare-delay-ms = <20>;+               //init-delay-ms = <20>;+               enable-delay-ms = <1>;+               disable-delay-ms = <1>;+               unprepare-delay-ms = <1>;                panel-init-sequence = [                        15 32 02 8F A5                        15 01 02 83 00

修改DRM 超时时间减小唤醒时间

这是最关键的,DRM框架非常复杂,RK也是从开源的DRM移植过来使用,在DRM部分有个时间超时导致问题,最终跟RK拿到最新的patch让唤醒时间直接加速500MS。

我们在日志下发现问题,并给询问了RK,最终发现这部分代码没有更新到最新的部分。

hi rk:为什么亮屏的时候有时候会打印这句VOP等待超时?请问下这是什么意思。

[ 1211.293492] rockchip-vop ff930000.vop: wait win close timeout

[ 1211.293514] rockchip-vop ff930000.vop: [drm:vop_crtc_enable] Update mode to 1200*1920, close all win

有时候却不会打印。

[ 1216.423283] rockchip-vop ff930000.vop: [drm:vop_crtc_enable] Update mode to 12001920, close all win [ 1223.899741] rockchip-vop ff930000.vop: [drm:vop_crtc_enable] Update mode to 12001920, close all win

[ 1234.386252] rockchip-vop ff930000.vop: [drm:vop_crtc_enable] Update mode to 1200*1920, close all win

patch代码如下:

--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c@@ -139,6 +139,9 @@ #define to_vop_win(x) container_of(x, struct vop_win, base) #define to_vop_plane_state(x) container_of(x, struct vop_plane_state, base)

+/*add by VENDOR_PATCH for seep up the drm vop driver at 2018/1/18 for RK Defect #191554, VENDOR_PATCH PAD100-193*/+#define VENDOR_PATCH+ struct vop_zpos {        int win_id;        int zpos;@@ -868,9 +871,15 @@ static void vop_disable_all_planes(struct vop *vop)

        vop_disable_allwin(vop);        vop_cfg_done(vop);+#ifdef VENDOR_PATCH        ret = readx_poll_timeout_atomic(vop_is_allwin_disabled,                                        vop, active, active,+                                       0, 100 * 1000);+#else+       ret = readx_poll_timeout_atomic(vop_is_allwin_disabled,+                               vop, active, active,                                        0, 500 * 1000);+#endif        if (ret)                dev_err(vop->dev, "wait win close timeout\n"); }@@ -2215,20 +2224,36 @@ static size_t vop_crtc_bandwidth(struct drm_crtc *crtc,        u16 htotal = adjusted_mode->crtc_htotal;        u16 vdisplay = adjusted_mode->crtc_vdisplay;        int clock = adjusted_mode->crtc_clock;+#ifndef VENDOR_PATCH        struct vop *vop = to_vop(crtc);        const struct vop_data *vop_data = vop->data;+#endif        struct vop_plane_state *vop_plane_state;        struct drm_plane_state *pstate;        struct vop_bandwidth *pbandwidth;        struct drm_plane *plane;        u64 bandwidth;        int i, cnt = 0;+#ifdef VENDOR_PATCH+       int plane_num = 0;+#endif

        if (!htotal || !vdisplay)                return 0;

+#ifndef VENDOR_PATCH        pbandwidth = kmalloc_array(vop_data->win_size, sizeof(*pbandwidth),                                   GFP_KERNEL);+#else+       for_each_plane_in_state(state, plane, pstate, i) {+               if (pstate->crtc != crtc || !pstate->fb)+                       continue;+               plane_num++;+       }+       pbandwidth = kmalloc_array(plane_num, sizeof(*pbandwidth),+                                  GFP_KERNEL);+#endif+        if (!pbandwidth)                return -ENOMEM;

@@ -2421,7 +2446,10 @@ static void vop_crtc_enable(struct drm_crtc *crtc)        rockchip_set_system_status(sys_status);        mutex_lock(&vop->vop_lock);        vop_initial(crtc);-+#ifdef VENDOR_PATCH+       vop_disable_allwin(vop);+       VOP_CTRL_SET(vop, standby, 0);+#endif        VOP_CTRL_SET(vop, dclk_pol, 1);        val = (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ?                   0 : BIT(HSYNC_POSITIVE);@@ -2549,8 +2577,9 @@ static void vop_crtc_enable(struct drm_crtc *crtc)        /*         * enable vop, all the register would take effect when vop exit standby         */+#ifndef VENDOR_PATCH        VOP_CTRL_SET(vop, standby, 0);-+#endif        enable_irq(vop->irq);        drm_crtc_vblank_on(crtc);        mutex_unlock(&vop->vop_lock);

修改QOS相关代码

QOS为Quality Of Service(服务质量)的简称,对PM QoS而言,表示Linux kernel电源管理相关的服务质量。那到底什么是服务质量呢?

我们知道,Linux PM的主要功能,是节省功耗,但同时,会付出一定的性能代价,例如延迟(latency)增加、吞吐量(throughput)下降。可以把PM当作一种服务,把它对性能的影响,类比为服务的质量(QoS)。对性能的影响越大,QoS越低,反之越高。

我们可以这么认为,我们在某个时候需要增加代码的执行速度,就通过这个去控制CPU的运行策略,这样确保代码可以快速执行。

不过这个方法没有使用到,如果对某个resume时间不是十分满意,可以尝试这个方法。

休眠唤醒流程图

从网上拷贝了个休眠唤醒的流程图,如果以后有问题需要分析的话,可以跟进这个流程去排查。

作者简介:韦启发,从事十余年嵌入式领域学习与工作,曾就职于TCL、中兴,从0开始创业开发过产品。目前在500强企业从事嵌入式系统软件开发工作。

本文系作者投稿,版权归作者所有。


 热 文 推 荐 

☞ 拼多多否认损失 200 亿;董明珠回应再拼三年;特斯拉称“未来艰难” | 极客头条

为什么物联网产品迫切需要良好的 UI/UX 设计?

☞ 写高质量的代码,永不言晚!

☞ V神说,解释以太坊2.0最好的文章就是这篇了

☞ 黄鳝门”视频女主播一审宣判!

☞ Kafka学习笔记

☞ 12306能扛住明星出轨这种流量冲击吗?

☞ 心疼!能为程序员男友做些什么吗?

print_r('点个好看吧!');
var_dump('点个好看吧!');
NSLog(@"点个好看吧!");
System.out.println("点个好看吧!");
console.log("点个好看吧!");
print("点个好看吧!");
printf("点个好看吧!");
cout << "点个好看吧!" << endl;
Console.WriteLine("点个好看吧!");
fmt.Println("点个好看吧!");
Response.Write("点个好看吧!");
alert("点个好看吧!")
echo "点个好看吧!"

点击“阅读原文”,打开 CSDN App 阅读更贴心!

喜欢就点击“好看”吧

如何攻克 Android 调试难题?| 技术头条相关推荐

  1. 老代码多=过度耦合=if else?阿里巴巴工程师这样捋直老代码 | 技术头条

    作者 | 紫思 本文经授权转自公众号"闲鱼技术"(ID: XYtech_Alibaba) 在业务开发的过程中,往往存在平台代码和业务代码耦合严重难以分离.业务和业务之间代码交织缺少 ...

  2. android开发常用技术,[转载]Android开发常用调试技术记录

    ANDROID 调试技术: 1)Ps 指令 ls –l /proc/27/ cat /proc/27/cmdline       #cmdline文件表示了这个进程所在的命令行. cat /proc/ ...

  3. 程序员如何搞定前端高频面试难题?附答案汇总 | 技术头条

    作者 | 木易杨 责编 | 伍杏玲 第 1 题:简单讲解一下 HTTP2 的多路复用 在 HTTP/1 中,每次请求都会建立一次TCP连接,也就是我们常说的3次握手4次挥手,这在一次请求过程中占用了相 ...

  4. 从Spark Streaming到Apache Flink: 实时数据流在爱奇艺的演进 | 技术头条

    戳蓝字"CSDN云计算"关注我们哦! 技术头条:干货.简洁.多维全面.更多云计算精华知识尽在眼前,get要点.solve难题,统统不在话下! 作者:陈越晨 转自:高可用架构 本文将 ...

  5. 使用AWS CloudWatch 调优Lambda函数 | 技术头条

    戳蓝字"CSDN云计算"关注我们哦! 技术头条:干货.简洁.多维全面.更多云计算精华知识尽在眼前,get要点.solve难题,统统不在话下! 译者:风车牛马 整理:刘丹 Kyle ...

  6. 滴滴全链路压测解决之道 | 技术头条

    戳蓝字"CSDN云计算"关注我们哦! 技术头条:干货.简洁.多维全面.更多云计算精华知识尽在眼前,get要点.solve难题,统统不在话下! 作者:张晓庆 转自:Java架构沉思录 ...

  7. 微服务落地,我们在考虑什么?| 技术头条

    戳蓝字"CSDN云计算"关注我们哦! 技术头条:干货.简洁.多维全面.更多云计算精华知识尽在眼前,get要点.solve难题,统统不在话下! 作者:李宁 转自: 博云技术社区 导读 ...

  8. 移动开发的跨平台技术发展史 | 技术头条

    作者 | 刘望舒 责编 | 伍杏玲 跨平台技术的诞生 我是2010年开始从事的Android开发,当时会Android和iOS开发的很少,也不火,所有人都在"摸着河底过河".项目更 ...

  9. 什么叫云原生应用?| 技术头条

    戳蓝字"CSDN云计算"关注我们哦! 技术头条:干货.简洁.多维全面.更多云计算精华知识尽在眼前,get要点.solve难题,统统不在话下! 作者:吕建伟 转自:阿朱说 (1)从F ...

最新文章

  1. 中文模糊查询性能优化 by PostgreSQL trgm
  2. 【cisco下针对冗余链路故障备份的处理措施】
  3. maven的pom.xml中repositories的作用
  4. 微信小程序,用户拒绝授权后重新授权;uni-app小程序,用户拒绝授权后点击无效;重新进入后拉起位置授权框;
  5. Mysql数据库Sql语句执行效率-Explain
  6. 嵌入式电路设计(物联网esp32最小电路设计)
  7. TextView属性android:ellipsize实现跑马灯效果
  8. 新手刷杭电-A-2019~2025
  9. 002.FTP配置项详解
  10. Android系统模块编译Makefile编写规则
  11. 记录自己装Ubuntu18.04+Win10 1803双系统,采用UEFI启动模式
  12. 公司要一个网站,是选模板建站还是定制化建站?
  13. python修改图片尺寸和DPI
  14. 短租APP开发定制快速搭建
  15. 2022年葡萄糖基甜菊糖市场前景分析及研究报告
  16. 机器学习服务活体检测算法荣获CFCA权威安全认证
  17. 五大要求让BPM与企业对接
  18. Python入门如何给自己写一个文字小游戏?一只小白的Python游戏
  19. taobao.top.oaid.client.decrypt( 端侧OAID解密 )
  20. 仿大众点评——秒杀系统部分02

热门文章

  1. pythontuple_python:tuple 真是鸡肋吗
  2. python提高——闭包、装饰器
  3. linux 单步启动_Linux内核如何装载和启动一个可执行程序
  4. 中国冷链行业市场供需与战略研究报告
  5. C语言结构体练习-互动粒子仿真
  6. uniac是哪一代计算机的代表,Saint-Uniac
  7. 涉及上千款,2021 Chrome插件性能影响分析报告新鲜出炉
  8. 高性能 Go 日志库 zap 设计与实现
  9. 继云计算巨头失火事件后,微软决定送数据中心去“泡澡”!
  10. Google 高薪争夺 Rust 人才,将用 Rust 重构关键组件!