前几天解决一个嵌入式Linux驱动问题,做为一个案例进行记录。

本案例是一个CPU通过LocalBus总线訪问外围一个设备,详细设备是一个DSP器件。在实际应用中,性能要求非常高,对数据訪问速度提出比較高的要求。

既然是通过LocalBus总线来訪问。实际上也就是在CPU的IO寻址空间。原来的做法是通过ioremap的方式将这个空间进行重映射。然后CPU对其进行读写訪问。读取DSP的一个数据须要经过写地址,读数据两个步骤。

现象描写叙述:

发现不管怎样。在写完地址之后一定要等待一段时间,或者一定要先读取一下DSP的Ready寄存器。这个操作在大数据处理时消耗相当可观。而实际应用上对性能要求非常高,这个等待或者读取Ready寄存器的动作必须清除。

原因分析:

本系统中採用的CPU是Powerpc。对LocalBus进行读写操作,那么读和写操作两个之间进行切换是有一个过程的,先写后读,转换太快可能写会不成功。问题的根本是驱动中採用的是ioremap之后的操作方式。

解决方法:

改变ioremap的方式,使用Linux 内核中对IO的操作接口out和in的方式。

调用函数为in_be16和out_le16。定义例如以下:

inline void out_8(volatile unsigned char *addr, int val)

{

__asm__ __volatile__("stb%U0%X0 %1,%0; sync"

    : "=m" (*addr) : "r" (val));

}





 inline unsigned in_le16(const volatile u16 *addr)

{

unsigned ret;





__asm__ __volatile__("lhbrx %0,0,%1; twi 0,%0,0; isync"

    : "=r" (ret) : "r" (addr), "m" (*addr));





return ret;

}

能够看出是用汇编实现的,当中有一个指令sync,表示同步操作。应该是类似于cache操作的原理,加上同步操作之后数据能够完毕读和写的所有操作过程。

经过改动。问题得到解决。不须要等待也不须要在写和读的切换过程中添加其他操作。最后,整个系统比原来使用ioremap的方式在实时性上有非常大的提高,并且CPU占用率大大减少。

总结:

在Linux驱动开发中。对于IO的操作应该使用内核提供的IO接口函数。最好是參照内核其他驱动的样例,平时多阅读内核代码是最好的学习方法。

最新文章

  1. 关于使用iframe嵌套页面的跳转方式
  2. jquery基础事件
  3. Appium移动自动化测试(二)--安装Android开发环境
  4. linux架构图
  5. 条款20:以const-reference传递替换by-value传递
  6. Delta-wave
  7. Python扩展模块——调用WindowsAPI(pywin32的简单使用)
  8. BAT面试技巧
  9. windows update error 0x8024401c
  10. ActiveMQ后台使用
  11. WORD2010如何把全角字母和数字批量转换成半角
  12. Python3 tkinter基础 Entry validatecommand 获取输入框的值
  13. 日志备份的shell脚本
  14. System.in的用法
  15. 解决:百度编辑器UEditor,怎么将图片保存到图片服务器,或者上传到ftp服务器的问题(如果你正在用UE,这篇文章值得你看下)
  16. HDU 1358
  17. 【题解】CF#229 E-Gifts
  18. 【Python基础】装饰器的解释和用法
  19. 20145201 《Java程序设计》第一周学习总结
  20. Python之freshman08 Socket

热门文章

  1. request.getHeader("referer")
  2. js 抓取页面数据
  3. 【bzoj1954】Pku3764 The xor-longest Path Trie树
  4. 【Luogu】P2805植物大战僵尸(拓扑排序+最大流)
  5. SiteMapPath控件的使用(ASP.NET)
  6. 刷题总结——(一道很妙的题)Resistance(ssoj 欧几里得 )
  7. 使用 SOAPUI 测试Web Service
  8. 如何回答“线上CPU100%排查”面试问题
  9. 2017-2018-2 20179204《网络攻防实践》linux基础
  10. Distinct Substrings(spoj 694)