留言板

路过的蜗牛们,在这里留个脚印吧~

蜗窝欢迎各种言论,谈天说地、技术交流、问题求救、跳槽招聘、牢骚抱怨……哈哈。

评论:

wpch315
2016-03-22 14:23
@wowo
请教一个问题,最近调串口驱动时发现使用dma的方式接收数据有问题,目前的现象是:

在系统的线程都处于休眠状态的时候,dma接收有问题,我建立了一个线程一直进行while循环,这时dma接收就是OK的

分析后发现可能是dma驱动中中断里调度一个tasklet时,在系统的线程都处于休眠状态的时候会有较大的延迟,我想请问一下:
1.是否还有其他可能性较大的原因
2.如果确实是tasklet调度的问题,什么地方的问题会导致这种情况?

谢谢!
wpch315
2016-03-22 17:30
@wpch315:我把tasklet里的事放到中断里做,发现现象一样,所以排除之前的推测,现在看上去就是线程的状态会影响dma的硬件行为,搞不清楚为什么会这样,请教各位
wowo
2016-03-22 18:28
@wpch315:DMA接收有问题?具体什么表现呢?中断没有产生?还是产生了没有被响应?
系统是不是进低功耗状态了?而DMA中断无法唤醒?
wpch315
2016-03-23 10:15
@wowo:中断产生并响应了,中断调度的tasklet里有打印错误信息,而且串口的中断方式接收是没有问题的
wowo
2016-03-23 13:59
@wpch315:中断产生了,那在中断里面可以接收到数据吗?你说数据不对,怎么个不对法呢?我还是怀疑是因为系统进低功耗了,没有来得及接收串口数据,而你的串口没有流控,所以数据丢了。
wpch315
2016-03-23 15:16
@wowo:中断里可以接收部分数据,同时报错,有两个错误,一个是dma传输错误,检测出这错误后读串口的状态寄存器报了第二个错误,rxfifo overrun,我也怀疑是系统进入低功耗状态后中断的响应不及时。
为了验证,我把电源管理相关的选项都关闭了,比如CPUidle,dvfs,包括底层的实现也都关了,但现象一样,不确定这样做是不是可以阻止系统进入低功耗状态?我用的imx53平台,单核A8,内核是2.6
wowo
2016-03-23 15:38
@wpch315:我觉得的可以从如下的思路去查找原因:
1)打开系统电源管理有关的日志输出,确认出错的这段时间内,系统的状态到底如何,是否进行了低功耗状态的切换,是哪个低功耗状态?
2)根据你描述的现象,直接使用UART中断Okay,但DMA不Okay,则说明UART中断可以使系统从“这个低功耗状态”返回,而DMA中断不可以。看看CPU那些低功耗状态有可能这样做。
3)试试打开uart的流控功能,应该就可以解决。
jordonwu
2016-03-14 19:49
@wowo & all,

请教一个遇到的问题,一个lvds屏接imx6,这个lvds除了要配置timing之外,在工作之前需要通过spi接口执行一段初始化code,搜索了下参考代码,在imx_linux-3.0.35及之前的版本里有类似spi初始化lvds/lcd屏的代码(如http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/drivers/video/mxc/mxcfb_epson_vga.c?h=imx_3.0.35_4.1.0)
static int __init epson_lcd_init(void)
{
    int ret;
    ret = platform_driver_register(&lcd_plat_driver);
    if (ret)
        return ret;
    return spi_register_driver(&lcd_spi_dev_driver);
}

但是在新版本的kernel中,这些代码都被移除掉了,我想请问下:在引入device tree之后,如果要执行spi初始化lvds panel的代码,这个是在lvds的dts部分配置还是在spi的dts部分配置? 另外kernel中是否已经存在有类似的code? 谢谢
wowo
2016-03-15 08:47
@jordonwu:我觉得,只要需要SPI操作,注册一个spi driver是不可少的啊。你这里说代码被移除了,无外乎两种可能:
1)放到其它位置了。
2)不再需要SPI初始化操作了。
你再看看代码,spi的操作方式没有改变。
fancy
2016-03-11 14:58
WoWo你好,
请教一个问题, 我目前碰到系统在刚唤醒的时候,通过get_monotonic_boottime获取的时间没有包含系统sleep的时间,如果等待大约300ms左右,此时通过get_monotonic_boottime就能获取到包含了系统sleep的时间。
请问在系统刚被唤醒的时候,通过什么接口能够获取到包含了睡眠的时间?不甚感激!
wowo
2016-03-11 16:48
@fancy:我对这个应用场景也不是很熟悉,不过可以提供一些思路,供你参考:
首先你用的这个接口应该是对的,问题是为什么会delay了300ms?
从timekeeping的resume流程来看(timekeeping_resume),有两个方法更新suspend的时间:
1)你所使用的clocksource支持suspend nonstop(CLOCK_SOURCE_SUSPEND_NONSTOP)。
2)rtc_resume的时候调用timekeeping_inject_sleeptime更新。
那么问题来了,你的平台使用的是什么方法?你在什么时机调用get_monotonic_boottime获取boot time呢?
fancy
2016-03-14 15:33
@wowo:谢谢wowo的回复。

我是nexus5的开发平台(高通),在系统休眠后,mcu触发中断唤醒系统,在第一次中断处理函数中去获取boot time的。但是看log, 在“timekeeping_resume”中得到的timekeeping_suspend_time是0。 但是在第二次或第三次中断处理函数中再用get_monotonic_boottime去获取AP time, 这个时间就包含了系统suspend的时间。貌似timekeeping_resume获取到的suspend时间无法及时更新。

[  341.333599] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
[  341.424081] PM: suspend of devices complete after 79.244 msecs
[  341.430902] PM: late suspend of devices complete after 1.896 msecs
[  341.438512] PM: noirq suspend of devices complete after 2.369 msecs
[  341.444145] Disabling non-boot CPUs ...
[  341.454448] msm_pm_enter
[  341.454448] msm_pm_enter: power collapse
[  341.454448] msm_pm_enter collapsed=1
[  341.454465] timekeeping_resume() 0 0-----------------suspend tims is 0 (tv_sec and tv_nsec)
[  341.458198] Enabling non-boot CPUs ...
[  341.467805] CPU1 is up
[  341.471267] PM: noirq resume of devices complete after 1.804 msecs
[  341.477099] Resume caused by IRQ 301, qpnp_rtc_alarm
[  341.481485] Resume caused by IRQ 200, qcom,smd-rpm
[  341.487958] PM: early resume of devices complete after 1.509 msecs
passerby
2016-03-14 18:00
@fancy:高通8939是用non stop sys counterd,不需要RTC做睡眠时间保存。不知道你这个的实现是怎么样的。
wowo
2016-03-15 08:49
@passerby:是的,fancy同学并没有回答我提出的两个疑问。
fancy
2016-03-15 17:10
@passerby:你好,谢谢回复,由于我对这块目前不太熟悉,能否稍微指导一下“non stop sys counterd”在哪部分代码里面实现的?我认真学习一下,我目前是msm8974.谢谢了。
passerby
2016-03-15 17:26
@fancy:static struct clocksource clocksource_counter = {
    .name    = "arch_sys_counter",
    .rating    = 400,
    .read    = arch_counter_read,
    .mask    = CLOCKSOURCE_MASK(56),
    .flags    = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP,
};
在 arm_arch_timer.c
passerby
2016-03-15 17:30
@passerby:这个counter在suspend的时候不会睡眠,所以在timekeeping_resume()中检测到if ((clock->flags & CLOCK_SOURCE_SUSPEND_NONSTOP)就会通过counter中的计数来进行睡眠时间的更新。
fancy
2016-03-17 13:07
@passerby:谢谢,我看了msm8974这部分的代码,还是用的rtc去获取睡眠时间的,我遇到的问题原因是rtc_resume执行得太晚了。目前做了个规避,谢谢你的指导了。
fancy
2016-03-17 13:08
@passerby:你好,我找到问题的原因了,是rtc_resume执行太晚了引起的。谢谢了。
fancy
2016-03-17 13:09
@fancy:你好,我找到问题的原因了,是rtc_resume执行太晚了引起的。谢谢了
wowo
2016-03-17 17:29
@fancy:好消息:-)
madang
2016-03-09 17:51
有没有计划讲讲smmu啊?
wowo
2016-03-09 21:17
@madang:IOMMU用的地方越来越多,有空可以分析一下,不过暂时还没有计划呢。
yun_2106118
2016-03-08 23:31
大家好,我现在遇到一个休眠问题,系统经常性遇到休眠不下去的问题,但是不是必然的,都是在frezz阶段失败,
Freezing of tasks aborted after 0.045 seconds,active wakeup source: alarm,请问下这个怎么去查。系统是5.1系统除此以外,系统没有其他wake_lock。睡眠不下去的时候,就一直重复上述frezz过程,不知道为什么alarm一直阻止,按理说,如果alarm没有执行完毕,不会再次启动睡眠流程啊。请各位帮忙指导下,谢谢
wowo
2016-03-09 14:23
@yun_2106118:建议先检查一下这个wakeup source是kernel driver持有的,还是Android通过wakelock持有的,如果是driver持有的,可能是RTC相关的驱动有问题,如果是Android持有的,用dumpsys alarm,查一下系统是不是有异常的alarm设置。
yun_2106118
2016-03-09 23:03
@wowo:谢谢wowo的回复,我看过wake_lock是没有任何锁的,而wakeup_souce中能够看到仅仅alarm是active状态,因此看起来时的确是kernel 锁,但是kernel里面是没有任何程序去使用rtc的,所以才有点纠结。我还是在查查kernel,如果有好的建议,还请多多指教。谢谢。
wowo
2016-03-10 09:41
@yun_2106118:一般情况下,driver会在有事件要处理的时候,调用pm_wakeup_event等接口,上报wakeup事件。你检查一下RTC有关的driver,是不是有逻辑错误,上报event后没有清除。
madang
2016-03-02 11:43
request_irq可以这样使用吗

spin_lock_irqsave( )

request_irq();

spin_unlock_restore();
wowo
2016-03-02 18:46
@madang:可以的,不过应该很少需要这样做。request_irq内部也有很多类似lock,不用我们自己特意保护的。
永恒大帝
2016-02-26 18:11
很不错的一个网站,什么时候可以讲解一下MMC子系统和文件系统哈
郭健
2016-02-26 19:46
@永恒大帝:内核中可以讲的子系统太多,就我们两个人,估计很难照顾到所有的内核模块(其实内核中的任何一块都可以做一辈子的,比如RCU,比如蓝牙,比如Wifi),还需要大家的力量啊!
madang
2016-02-01 12:18
问一个问题:devm_ioremap_resource 接口和 devm_ioremap的区别。
看了一下代码,为一个区别就是一个接口devm_ioremap_resource()接口会调用
devm_request_mem_region()函数来检查 地址重复的问题。
但是看到内核里面 确实也有驱动调用devm_ioremap接口来做ioremap,
所以,想问一下,什么情况下可以调用 devm_ioremap ?

急 。在线等!

2016-02-01 14:22
@madang:举个例子:
小A写了一个内核模块,里面用需要使用一块物理内存空间, 于是他这么写:virt_A = devm_ioremap(phys A , size B);
另外一个部门的小B也写了一个内核模块,virt_B = devm_ioremap(phys B , size B)

但是很不幸,A和B是同一块内存区域,或者他们之间有空间重叠。导致了小A和小B的驱动都不能工作正常。而他们彼此互不知情。
怎么解决这个问题呢?所以得引入resource管理的机制了,小A和小B都使用devm_ioremap_resource()防止conflict.

----------------------------我是分割线----------------------------------

一般SoC的中,各个硬件模块各自的memory region都有严格的划分(比如说USB host的地址空间绝对不会和flash host冲突), 所以一般的driver使用devm_ioremap()也就没问题了。 当然了,你要使用devm_ioremap_resource()也是OK的
wowo
2016-02-01 15:51
@云:是对,云说的非常对。总结来说,就是devm_ioremap可以重复map相同的地址空间,devm_ioremap_resource不可以。有时候几个driver可能真的需要map一些相同的寄存器空间(这是不规范的做法,但可能有一些无可奈何的原因),这时候devm_ioremap_resource就不能用了,只能用devm_ioremap。
madang
2016-02-01 16:34
@wowo:只要做好对同一块物理地址(主要是寄存器之类)的并发访问,应该就没有什么问题。我觉得。你觉得呢?
wowo
2016-02-02 09:35
@madang:是的。应该每个写driver的都干过这事儿:-)
不过尽量少做,因为这样做的原因是有些耦合没有拆开。
爱萝莉
2016-01-21 10:14
每次都默默看你们的评论.....
passerby
2016-01-20 17:00
@linuxer 最近在看进程调度,看到HMP的CPU 的check_for_migration进行task迁移的时候不太懂,rq->capacity 以及cpu能力这些在这里面是怎么体现的
郭健
2016-01-21 08:40
@passerby:我在读linux4.1.10的代码,没有看到check_for_migration这个函数,你是那个版本的?
passerby
2016-01-21 09:34
@郭健:是3.10的,在 /kernel/sched/fair.c 文件里
郭健
2016-01-21 10:21
@passerby:是标准kernel吗?我怎么看不到这个函数?
passerby
2016-01-22 19:50
@郭健:这个不敢确定,有可能是高通自己搞得东西。
passerby
2016-01-27 14:43
@passerby:对比理解了下代码,确实是高通的东西。高通为了增加对HMP的支持,对进程调度进行了很大的修改。所以代码变得不同了,增加了它的rq负载计算的机制。

发表评论:

Copyright @ 2013-2015 蜗窝科技 All rights reserved. Powered by emlog