新的项目,编译代码,烧写到主板后,主板能起来,但就是进入不了主界面(通过vysor同屏查看)。这是比较少见的,怀疑是编译代码时哪里弄错了,但再三检查也没发现问题,将固件烧写到其他项目的主板上能正常起来,那就不是代码的问题了。

先看内核log,init进程一直在启动camera服务,但到了600s都没启动成功。

查看死掉的进程

root@G480:/home/w# adb  shell  ps  -AT|grep -e "D" -e "Z" -e  "R"
USER           PID   TID  PPID     VSZ    RSS WCHAN            ADDR S CMD
root            69    69     2       0      0 mbox_send_thread    0 D mbox-send-threa
root            72    72     2       0      0 monitor_irqs_change 0 D irqs_change
root           232   232     2       0      0 0                   0 R sugov:0
root           419   689     1 2424672   8708 poll_schedule_timeout 0 S SkDestroyListen
root           420  4678     1 5456024 177276 futex_wait_queue_me 0 S HeapTaskDaemon
root           420  4679     1 5456024 177276 futex_wait_queue_me 0 S ReferenceQueueD
root           420  4680     1 5456024 177276 futex_wait_queue_me 0 S FinalizerDaemon
root           421  1451     1 1768180 161488 futex_wait_queue_me 0 S HeapTaskDaemon
root           421  1452     1 1768180 161488 futex_wait_queue_me 0 S ReferenceQueueD
root           421  1453     1 1768180 161488 futex_wait_queue_me 0 S FinalizerDaemon
cameraserver   427   427     1   71428  18752 sprd_i2c_handle_msg 0 D android.hardwar

刚好有个camerasever用户处在D状态,sprd_i2c_handle_msg应该是正在执行的函数。一下子明白了,i2c卡死导致无法进入系统(之前有遇到类似的case)。查看摄像头代码默认使用了i2c0和i2c1,我们的主板i2c1还接了其他外设,也就可能是设备没上电导致i2c信号被拉低,导致系统初始化话摄像头的时候,引起系统卡死。修改代码,屏蔽i2c1后,系统能进入主界面了。调过qcom,mtk的主板,都没有遇到类似的情况,只有展讯平台才遇到过,遇到过几次了,于是提个cq问下展讯。他们回复是符合协议的,非平台特有。直觉告诉我那里不对,如果是i2c设备共性,那所有的平台都有类似的情况,但调的其他平台就没有遇到,难道是运气好。

找代码看下

i2c-sprd.c « busses « i2c « drivers - kernel/git/torvalds/linux.git - Linux kernel source tree

看下sprd_i2c_handle_msg(ps -AT有看到该函数),看到wait_for_completion函数没

static int sprd_i2c_handle_msg(struct i2c_adapter *i2c_adap,struct i2c_msg *msg, bool is_last_msg)
{struct sprd_i2c *i2c_dev = i2c_adap->algo_data;i2c_dev->msg = msg;i2c_dev->buf = msg->buf;i2c_dev->count = msg->len;reinit_completion(&i2c_dev->complete);sprd_i2c_reset_fifo(i2c_dev);sprd_i2c_set_devaddr(i2c_dev, msg);sprd_i2c_set_count(i2c_dev, msg->len);if (msg->flags & I2C_M_RD) {sprd_i2c_opt_mode(i2c_dev, 1);sprd_i2c_send_stop(i2c_dev, 1);} else {sprd_i2c_opt_mode(i2c_dev, 0);sprd_i2c_send_stop(i2c_dev, !!is_last_msg);}/** We should enable rx fifo full interrupt to get data when receiving* full data.*/if (msg->flags & I2C_M_RD)sprd_i2c_set_fifo_full_int(i2c_dev, 1);elsesprd_i2c_data_transfer(i2c_dev);sprd_i2c_opt_start(i2c_dev);wait_for_completion(&i2c_dev->complete);return i2c_dev->err;
}

那什么时候发complete信号呢

static irqreturn_t sprd_i2c_isr_thread(int irq, void *dev_id)
{....complete(&i2c_dev->complete);...
}

也就是i2c控制器中断来了,就发中complete信号,如果中断信号不过来,那sprd_i2c_handle_msg就一直卡住。

看下wait_for_completion函数实现,也就是没有信号过来,一直schedule(主动让出cpu),直到信号过来。

#define  MAX_SCHEDULE_TIMEOUT    LONG_MAX
void __sched wait_for_completion(struct completion *x)
{wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE);
}static long __sched wait_for_common(struct completion *x, long timeout, int state)
{return __wait_for_common(x, schedule_timeout, timeout, state);
}static inline long __sched
__wait_for_common(struct completion *x,long (*action)(long), long timeout, int state)
{timeout = do_wait_for_common(x, action, timeout, state);
}static inline long __sched do_wait_for_common(struct completion *x,long (*action)(long), long timeout, int state)
{if (!x->done) {DECLARE_WAITQUEUE(wait, current);__add_wait_queue_tail_exclusive(&x->wait, &wait);do {if (signal_pending_state(state, current)) {timeout = -ERESTARTSYS;break;}__set_current_state(state);spin_unlock_irq(&x->wait.lock);timeout = action(timeout);spin_lock_irq(&x->wait.lock);} while (!x->done && timeout);__remove_wait_queue(&x->wait, &wait);if (!x->done)return timeout;}x->done--;return timeout ?: 1;
}signed long __sched schedule_timeout(signed long timeout)
{switch (timeout){case MAX_SCHEDULE_TIMEOUT:/** These two special cases are useful to be comfortable* in the caller. Nothing more. We could take* MAX_SCHEDULE_TIMEOUT from one of the negative value* but I' d like to return a valid offset (>=0) to allow* the caller to do everything it want with the retval.*/schedule();goto out;}out:return timeout < 0 ? 0 : timeout;
}

再看下mtk或qcom的驱动

i2c-mt65xx.c « busses « i2c « drivers - kernel/git/torvalds/linux.git - Linux kernel source tree

i2c-qcom-geni.c « busses « i2c « drivers - kernel/git/torvalds/linux.git - Linux kernel source tree

使用的是wait_for_completion_timeout函数,如

static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,u32 m_param)
{unsigned long time_left;time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);if (!time_left)geni_i2c_abort_xfer(gi2c);return gi2c->err;
}

即使没有信号过来,i2c也不会卡住。

当然,这个bug已提给他们,后续版本会加入超时机制。

Linux下wait_for_completion引起的开机定屏相关推荐

  1. Linux 下安装Ubuntu20.04 启动花屏的解决方法(安装和启动时设置 quite splash nomodeset即可解决)

    Linux 下安装Ubuntu20.04 启动花屏的解决方法(安装和启动时设置 quite splash nomodeset即可解决) 问题:正常安装Ubuntu 20后开机花屏,卡住不动.这是因为u ...

  2. linux能远程开机么,Linux 下如何实现远程开机

    你知道Linux下如何实现远程开机吗?下面小编就根据Linux实现远程开机的内容为大家详细介绍其实现方法,有兴趣的小伙伴们就跟随小编一起去探讨具体内容吧. Linux下实现远程开机的条件,要满足以下两 ...

  3. linux 录屏软件 按键,linux下常用的截图、录屏工具

    linux下常用的截图.录屏工具 (2010-01-05 10:47:21) 由于和老公一起做一个百度俱乐部的小项目,在编写测试文档时要使用截图.录屏的小工具,于是展开搜索什么工具比较好使. 录屏: ...

  4. linux下的外接显示器设置成竖屏

    linux下的外接显示器设置成竖屏 用到的软件 系统设置里的Display xrandr 用到的命令 $: xrandr -o left\right 步骤 1.在Display里选择设置的显示器为主显 ...

  5. Linux下LCD 10分钟自动关屏的问题总结

    记录一下,防止博客丢失.来自:http://blog.csdn.net/mao0514/article/details/46562057 Linux下的LCD驱动默认10分钟后会自动关闭屏幕,我们可以 ...

  6. 计算机开机定屏,电脑主板开机画面定屏解决方法

    原标题:电脑主板开机画面定屏解决方法 关于这个主板开机画面不动的问题该怎么办呢?下面电脑高手网小编给大家分享一篇电脑主板开机画面不动的解决方法,希望可以给大家一些帮助或建议. 主板开机画面不动的解决方 ...

  7. linux数据库实例开机启动不了,linux下Oracle数据库实例开机自启动设置

    linux下数据库实例开机自启动设置 1.改动/oratab [root@org54 ~]# vi/etc/oratab     --把N改为Y,例如以下提示 # This file is used ...

  8. linux下添加简单的开机自启动脚本

    注:博主使用的ubuntu-16.04进行实验,其它版本可能有偏差,但实现原理类似. 一.在rc.local脚本中添加开机自启动程序 1.添加 ubuntu在开机过程之后,会执行/etc/rc.loc ...

  9. 嵌入式linux下如何尽快播放开机音乐

    今天在考虑如何尽快启动一个应用程序,播个开机音乐什么的. 最开始的启动流程是这样的,bootloader 启动kernel,kernel跑完挂载文件系统, 然后会执行/init,而这个init 是指向 ...

最新文章

  1. R语言unlist函数将复杂数据(list列表、dataframe、字符串String)对象处理成简单向量vector形式:将包含dataframe和字符串的向量列表转换为单个向量(删除数据名称)
  2. GE前董事长伊梅尔特谈数字化转型:制造企业这件事做不好,一定没出路
  3. Spring整合redis,通过sentinel进行主从切换。(何志雄)--转
  4. 精准扶贫谋定产业化-农业大健康·万祥军:东平农业品牌化
  5. matlab二元一次方程求解_2-函数的求解计算
  6. Asp.net ajax、Anthem.net、Ajax pro三大ajax框架论坛网友比较
  7. VSCode代码格式化自动换行问题
  8. 转:PHP中实现非阻塞模式
  9. RabbitMq学习笔记005---登录rabbitmq报错User can only log in via localhost
  10. “围剿”余额宝!微信零钱通能否逆袭成功?| 畅言
  11. 【Maven使用】IDEA使用Maven进行文件打包+命令含义+错误分析
  12. 程序员-这有一份520表白秘笈送给你
  13. 《关于我横扫一线厂的那些面经》拼多多Java岗(附答案)
  14. 极客时间运维进阶训练营第二周作业
  15. 土豪聪要请客(stol)
  16. #读书笔记#《富爸爸窮爸爸》 | Rich Dad Poor Dad 罗伯特.清崎 Robert Kiyosaki
  17. “const wchar_t *“ 类型的实参与 “LPCSTR“ 类型的形参不兼容的原因和解决方法
  18. 海洋静力触探仪(CPT)一次故障记录
  19. Tensorflow模型优化训练思路
  20. grafana可视化

热门文章

  1. 电路基础 01电压、电流和功率
  2. 采购订单限价(包含阶梯价)ME_PROCESS_PO_CUST
  3. 「Adobe国际认证」平面设计师的,终极排版术语综合指南,都包含了哪些设计要点?
  4. 购物网站被劫持跳转返利推广网站的分析过程和解决方法
  5. 顶会速递 | ICLR 2020录用论文之自然语言处理篇
  6. C# 按Button弹出新的窗体 Show()方法 和 ShowDialog()方法
  7. 挂载zookeeper到文件系统 (mount zookeeper)
  8. 【每日新闻】三星电子市值跌至全球第18位,落后中国阿里腾讯 | 中国AI领袖人物吴甘沙:无人驾驶技术距离我们已经不再遥远
  9. 使用 Play Integrity API 来保护您的应用和游戏
  10. w ndows平板插sim卡,HUAWEI MateBookE怎么插入sim卡上网和接收短信?