LED 设备驱动
目的是熟悉内存映射
一、地址映射
-
裸机LED灯实验就是操作6ULL的寄存器。
-
Linux驱动开发也可以操作寄存器,Linux不能直接对寄存器物理地址进行读写操作,比如寄存器A物理地址为0X01010101。裸机的时候可以直接对0X01010101这个物理地址进行操作,但是linux下不行,因为linux会使能MMU。
-
在linux里面操作的都是虚拟地址,所以需要先得到0X01010101这个物理地址对应的虚拟地址。linux初始化MMU后,就会设置好内存映射,设置好之后cpu访问的都是虚拟地址
写数据必须获得物理物理地址对应的虚拟地址使用ioremap函数。
第一个参数就是物理地址其实大小,第二个参数就是要转化的字节数量。0X01010101,开始10个地址进行转换va=ioremap(0X01010101, 10).
卸载驱动的时候:
iounmap(va);
二、LED灯字符设备驱动框架搭建
- uboot下载系统失败,以前都能成功,突然不能下载怎么解决?
首先,保证整个网段内开发板的IP地址和ubuntu的IP地址是唯一的,测试哪个IP地址有冲突,比如ubuntu的192.168.1.66有被其他设备占用,如果有占用就改一个没被占用的IP地址。
三、驱动程序编写
- 初始化时钟、IO、GPIO等等。
- 初始化完成以后进行测试,但是如果你烧写/用的是正点原子提供的linux内核,这个时候LED灯默认被配置为了心跳灯,必须关闭心跳灯。
四、应用程序编写
五、测试
-
加载驱动
-
创建设备节点
mknod /dev/led c 200 0
新字符设备驱动
目的是 使用新的注册字符函数(自动指定主设备号,更新次设备号)
一、新字符设备驱动原理
- 原来的:
使用register_chrdev
函数注册字符设备,浪费了很多次设备号,而且需要手动指定主设备号。 - 新的:
使用alloc_chrdev_region
申请,原型:
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)
指定设备号注册:
int register_chrdev_region(dev_t from, unsigned count, const char *name)
参数 from
是要申请的起始设备号,也就是给定的设备号;参数 count
是要申请的数量,一般都是一个;参数 name
是设备名字。
注销字符设备之后要释放掉设备号 , 不管是通alloc_chrdev_region
函数还是
register_chrdev_region
函数申请的设备号,统一使用如下释放函数
卸载驱动使用:
void unregister_chrdev_region(dev_t from, unsigned count)
- 实际驱动编写
无论给不给定,要适配两种情况 - 字符设备注册
cdev
结构体表示字符设备,然后使用cdev_init
函数来初始化cdev
, 初始化完成后,使用cdev_add
添加到linux内核
二、自动创建设备节点
- 在之前的实验中,需要手动使用
mknod
创建设备节点,为此,linux2.6内核引入了udev
机制替换devfs
,udev
提供热插管理,可以在加载驱动时自动创建/dev/xx
设备文件。busybox
会创建一个简化版本的udev
->mdev
三、文件私有数据
- 在open函数里面设置的file->private_Data 为设置变量
- 在read,write里面要访问设备的时候,直接读取私有数据