设为首页 加入收藏

TOP

Linux设备驱动工程师之路——硬件访问及混杂设备LED驱动
2014-11-24 11:55:09 来源: 作者: 【 】 浏览:1
Tags:Linux 设备驱动 工程师 硬件 问及 混杂 设备 LED 驱动

一、重要知识点


1.I/O端口和I/O内存


寄存器和常规内存的区别:寄存器和RAM主要不同在于寄存器有边际效果,读取某个地址时可能导致该地址的内容发生变化,比如说很多设备的中断状态寄存器只要一读取,便自动清0。所以硬件寄存器不能直接访问,而要通过I/O端口和I/O内存两种方式访问。


在硬件层,I/O内存区域和I/O端口区域没有概念上的区别:它们都是通过向地址总线和控制总线发生电平信号进行访问,再通过数据总线读写数据。


a.I/O端口:


一些CPU制造厂在它们的芯片中使用单一的地址空间,而一些则为外设保留独立的地址空间,以便和内存区间分开来,这段独立与内存地址空间的地址空间就叫I/O端口。在/proc/ioport中可以看到。嵌入式处理器大部分不支持I/O端口。


访问I/O端口有两步:1.申请I/O端口2.读写I/O端口


申请I/O端口:


structresource *request_region(unsigned long first, unsigned long n, const char *name)


申请从first开始的n个端口。参数name为设备名称。如果分配成功则返回非NULL值。


释放I/O端口:


voidrelease_region(unsigned long start, unsigned long n)


读写I/O端口:


读写一个字节


unsignedinb(unsigned port)


voidoutb(usigned char byte, unsigned port)


读写二个字节


unsignedinb(unsigned port)


voidoutb(usigned short byte, unsigned port)


读写四个字节


unsignedinb(unsigned port)


voidoutb(usigned long byte, unsigned port)



b.I/O内存


通过将外设寄存器映射到内存空间来进行访问叫做I/O内存,嵌入式大多只支持这种操作。


访问I/O内存有三步:1.申请I/O内存区域2.映射I/O内存区域3.读写I/O内存


申请I/O内存区域


structresource *request_mem_region(unsigned long start, unsigned long len, char *name)


申请访问从start(I/O物理地址)开始的len长度的I/O内存区域,如成功则返回非NULL值。在/proc/iomem中可可以查看到已经被申请的I/O内存区域。在后面的我写的驱动程序中并没用使用申请这一步,是因为我使用的GPIO内存区域已经被申请,如果在申请会导致失败。但是这样做法是不安全的做法,因为同一I/O内存区域域被多个模块使用。


释放I/O内存区域


voidrelease_mem_region(unsigned long start, unsigned long len)


映射I/O内存区域


void*ioremap(unsigned long phy_addr, unsigned long size)


映射从物理地址phy_addr开始的size长度的的地址空间。返回可以访问I/O内存地址。由ioreamp返回的地址不应该直接引用,必须通过下面一些列的读写函数完成。


读写操作I/O内存


读1、2、4个字节:


unsignedint read8(void *addr);


unsignedint read16(void *addr)


unsignedint read32(void *addr)


写读1、2、4个字节:


voidiowrite8(u8 value, void *addr)


voidiowrite16(u8 value, void *addr)


voidiowrite32(u8 value, void *addr)



2.混杂设备驱动


在Linux系统中,存在一类字符设备,他们共享一个主设备号(10),但此设备号不同,我们称这类设备为混杂设备(miscdeivce),查看/proc/device中可以看到一个名为misc的主设备号为10。所有的混杂设备形成一个链表,对设备访问时内存根据次设备号找到对应的miscdevice设备。


Linux内核使用structmiscdeivce来描述一个混杂设备


structmiscdevice{
int minor;


conststruct file_opreations *fops;


structlist_head list;


structdevice *parent;


structdevice *this_device;


}


使用时只需填写minor次设备号,*name设备名,*fops文件操作函数集即可。


Linux内核使用misc_register函数注册一个混杂设备。注册成功后,linux内核为自动为该设备创建设备文件。


intmisc_register(struct miscdevice *misc)



二、驱动代码



1.驱动代码一


这段LED驱动代码采用手动I/O内存映射的方式访问。没有使用申请内存区域函数,这样使不安全的。直接访问I/O内存地址而不是通过读写函数访问也是不安全。同时驱动代码包含硬件相关代码也是移植性不好的。写这段代码是为了帮助理解I/O内存映射的过程。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Linux设备驱动工程师之路——内核.. 下一篇Linux设备驱动工程师之路——Linu..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·如何从内核协议栈到 (2025-12-27 03:19:09)
·什么是网络协议?有哪 (2025-12-27 03:19:06)
·TCP/ IP协议有哪些 (2025-12-27 03:19:03)
·怎样用 Python 写一 (2025-12-27 02:49:19)
·如何学习python数据 (2025-12-27 02:49:16)