Linux物理设备驱动,主要有几种类型,如:IO类、内存类、总线类。IO类我们平时接触的最多,其主要特点是,通过IO设备的寄存器操作硬件,具体需要去查看硬件手册。

1. IO端口和IO内存

在硬件层,内存区和 IO区域没有概念上的区别: 它们都是通过向在地址总线和控制总线发出电平信号来进行访问,再通过数据总线读写数据。Linux 在所有的计算机平台上实现了 IO端口。但不是所有的设备都将寄存器映射到 IO端口。虽然ISA(很古老的设备总线)设备普遍使用 IO端口,但大部分 PCI 设备则把寄存器映射到某个内存地址区,这种 IO内存方法通常是首选的。

side effect(边际效应):是指读取某个地址时可能导致该地址内容发生变化,比如,有些设备的中断状态寄存器只要一读取,便自动清零。IO寄存器和 RAM 的主要不同就是 IO寄存器操作有side effect, 而内存操作没有。驱动程序必须确保在操作IO寄存器时,不使用高速缓存,且不能重新编排读/写指令顺序。

解决硬件缓存问题:禁止硬件缓存即可。

硬件指令重新排序问题:设置内存屏障。具体API函数暂不罗列了,LDD3书上都有。

2.使用IO端口

IO端口使用在嵌入式系统中非常普遍,或者说大部分嵌入式开发,都是在做GPIO端口的开发,因此必须掌握。

(1)IO端口分配

在尚未取得端口的独占访问前,不应对端口进行操作。内核提供了一组端口注册及释放函数:

#include

struct resource *request_region(unsigned long first, unsigned long n, const char *name);

void release_region(unsigned long start, unsigned long n);

int check_region(unsigned long first, unsigned long n); /*检查一个给定的 IO端口集是否可用,不推荐使用,因为多CPU未必准确*/

(2)操作 IO端口

硬件会把8、16和32位端口区分开,不能像访问系统内存那样混淆使用。在64位系统上,最大也就是32位端口,没有64位端口。驱动必须调用不同的函数来存取不同大小的端口。下面是端口操作函数:

unsigned inb(unsigned port);

void outb(unsigned char byte, unsigned port);

读/写字节端口( 8 位宽 )

unsigned inw(unsigned port);

void outw(unsigned short word, unsigned port);

访问 16位 端口( 一个字宽 )

unsigned inl(unsigned port);

void outl(unsigned longword, unsigned port);

访问 32位 端口

(3)在用户空间访问 IO端口

以上函数主要提供给设备驱动使用,但它们也可在用户空间使用,至少在 PC上可以。 GNU C 库在 中定义了它们。但是会有一些限制条件,较为复杂,平时开发时候很少这样使用。

(4)串操作

一次传输一个数据的I/O操作非常低效,一些处理器实现了一次传输一个数据序列的特殊指令,序列中的数据单位可以是字节、字或双字,这是所谓的串操作指令。

void insb(unsigned port, void addr, unsigned long count);

void outsb(unsigned port, voidaddr, unsigned long count);

void insw(unsigned port, void addr, unsigned long count);

void outsw(unsigned port, voidaddr, unsigned long count);

void insl(unsigned port, void addr, unsigned long count);

void outsl(unsigned port, voidaddr, unsigned long count);

注意: 它们直接将字节流从端口中读取或写入。当端口和主机系统有不同的字节序时,会导致不可预期的结果。 使用 inw 读取端口应在必要时自行转换字节序,以匹配主机字节序。

(5)暂停式 I/O

为了匹配低速外设的速度,有时若 IO指令后面还紧跟着另一个类似的I/O指令,就必须在 IO指令后面插入一个小延时。在这种情况下,可以使用暂停式的I/O函数代替通常的I/O函数,事实上,现在处理器已经不需要了,因此不再介绍该函数组。

3.使用 IO内存

和设备通讯另一种主要机制是通过使用映射到内存的寄存器或设备内存,统称为 IO内存。因为寄存器和内存之间的区别对软件是透明的。IO内存仅仅是类似 RAM 的一个区域,处理器通过总线访问这个区域,以实现设备的访问。在实际开发中,这种方式使用的最多。

根据平台和总线的不同,IO内存可以就是否通过页表访问分类。若通过页表访问,内核必须首先安排物理地址使其对设备驱动程序可见,在进行任何 IO之前必须调用 ioremap,绝对不能使用实际的物理地址,否则会因为内核无法处理地址而出现oops。若不通过页表,IO内存区域就类似IO端口,可以使用适当形式的函数访问它们。因为“side effect”的影响,不管是否需要 ioremap ,都不鼓励直接使用 IO内存的指针,应使用内核提供的 accessor 函数。而使用专用的 IO内存操作函数,不仅在所有平台上是安全,而且对直接使用指针操作 IO内存的情况进行了优化。

Linux驱动无硬件设备,Linux设备驱动与硬件通信相关推荐

  1. linux服务器无网络确认,Linux服务器故障排查实用指南

    [2013年3月25日 51CTO外电头条]由于造成网络问题的因素多种多样,因此网络故障排查技能就成了每位服务器或网络服务负责人必不可少的重要素质.Linux为我们提供了大量网络故障排查工具,在本文中 ...

  2. linux下无对应分辨率,linux mint 向“显示(display)”面板添加没有提供的分辨率选项,使虚拟机中的linux mint可以全屏显示...

    最近使用VM player安装linux mint,运行后不能铺满全屏.在设置分辨率时,发现没有1440×900.1920x1080等的选项,何其的蛋疼啊. 尝试谷歌一下,看能不能修改.果然找到,有两 ...

  3. linux 安装无界面系统,linux系统安装异常,无法进入GUI安装界面 - 量子化学 - 小木虫 - 学术 科研 互动社区...

    很简单的问题. 遇到过一次. 图形界面没有, 是该系统 在安装过程中不能识别你的显示卡; 磁盘选择错误, 问题在于你的光驱的毛病. 不能加载分区, 很简单. 你win的分区至少是NTFS的(除了C盘之 ...

  4. linux底层硬件需求,Linux系统的硬件设备驱动的底层结构讲解

    什么是驱动?最通俗的解释就是"驱使硬件设备行动" 作用?设备驱动与底层硬件直接打交道,按照硬件设备的具体工作方式读写设备寄存器,完成设备的轮询.中断处理.DMA通信,进行物理内存向 ...

  5. linux wc -l 对io,linux设备驱动归纳总结(五):2.操作硬件——IO内存

    linux设备驱动归纳总结(五):2.操作硬件--IO内存 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  6. linux设备usb节点和硬件接口,所谓设备驱动即驱使硬件设备行动,带你深入理解linux的设备驱动......

    原标题:所谓设备驱动即驱使硬件设备行动,带你深入理解linux的设备驱动... 设备驱动最通俗的解释就是"驱使硬件设备行动".操作系统是通过各种驱动程序来驾驭硬件设备的,它为用户屏 ...

  7. Linux 有/无设备树下 platform_driver 驱动框架

    文章目录 platform 驱动框架 platform 设备框架 有设备树下驱动开发注意事项 宏___一行代码创建 platform_driver platform 驱动框架 首先,定义一个 plat ...

  8. linux中giep命令作用,Linux查看硬件信息以及驱动设备的命令

    用硬件检测程序kuduz探测新硬件:service kudzu start ( or restart) 查看CPU信息:cat /proc/cpuinfo 查看板卡信息:cat /proc/pci 查 ...

  9. linux查看驱动设备,linux查看硬件信息及驱动设备相关整理(留存验证)

    在LINUX环境开发驱动程序,首先要探测到新硬件,接下来就是开发驱动程序. 常用命令整理如下: 用硬件检测程序kuduz探测新硬件:service kudzu start ( or restart) ...

最新文章

  1. 通过Mellanox ConnectX NIC使用XDP加速
  2. Mantis 缺陷管理系统配置与安装
  3. 哨兵机器人钢力士_哨兵胳膊都被卸了?巴西厂X战警钢力士正式公布
  4. 微服务和SOA架构的区别
  5. GlassFish 3.1.2充满了MOXy(EclipseLink JAXB)
  6. hihoCoder #1143 : 骨牌覆盖问题·一
  7. Android之记住密码与自动登陆实现
  8. 厉害!苏宁通过citus打造分布式数据库抗住DB高负载
  9. js 判断对象是否是Array
  10. 【Kafka】kafka的安装以及部署的详细描述
  11. 几道查询树上点之间的路径的题目
  12. InnoDB与Myisam的六大区别
  13. 373.查找和最小的K对数字
  14. java开发简历专业技能怎么写,附赠复习资料
  15. 文件编码 ANSI、GBK、GB2312、MS936、MS932、SJIS、Windows-31 、EUC-JP 、EBCDIC 等等之间的区别与联系
  16. Django报错异常django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without
  17. 基于SSM的高校学生宿舍报修管理系统
  18. android 拨号盘按键移位,手机拨号盘的隐藏功能!这两个键的作用,99%的人不知道!...
  19. 如何恢复删除的微信记录?恢复删除记录的方法
  20. 计算机硬件及编程语言

热门文章

  1. QTP---Recovery Scenario没有被触发的原因汇总
  2. thinkphp5.1嵌套关联预载入的写法
  3. 给2019前端的5个建议
  4. HDU 2300 Crashing Robots
  5. 学习笔记TF064:TensorFlow Kubernetes
  6. 查找二叉树中出现次数最多的数 Find Mode in Binary Search Tree
  7. ffmpeg-20160526-git-bin
  8. 【学神-RHEL7】1-4-1-Linux文件管理和恢复误删除的文件
  9. 2021年2月反思与总结
  10. React学习笔记4: React脚手架配置代理