linux

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  202 随笔 :: 13 文章 :: 51 评论 :: 0 引用

最近在调试关于视频监控相关应用的时候,需要将在接收端接收的数据切换至TVOUT上显示,但切换过去之后,执行某一次的tvout刷新的过程中,某一次的memset动作会使dma停止工作,如果把memset的区域长度减少则没有问题,将需要memset区域分成两次执行,中间加入一个小延时也无问题,如果把libc的memset替换为自己实现的memset也没问题。当摄像头采集时,将环境变暗也无问题。

这里涉及了两个问题:

1、为什么用户态执行的函数能使工作在内核态的硬件工作不正常了呢?

2、自己写的memset和glibc里实现的有何差别,为何自己实现的不会出问题?

后来发现问题出在DMA的优先级配置上,芯片默认的优先级配置是arm核(cpu)对AHB的优先级是高于所有DMA优先级的,包括LCD、camera、L2等,降低CPU的AHB优先级至最低,则可以解决问题。

关于第二个问题,标准C库的memset为何如此高效呢?

后发现c库里面的memset是经过优化的,使用的都是ldm/stm指令的,该指令会访问内存中的连续地址数据,这些访问操作会被CPU合并成一个较长的内存原子访问操作(16bytes),这就有可能造成lcd dma在一段时间内不能获得内存的访问权限,而自己写的memset采用的是ldr/str指令,每次只会访问4byte的数据,这么短的操作对lcd dma的影响就很小了。

posted on 2012-11-23 12:37  h13  阅读(...)  评论(...编辑  收藏