1 概述
1.1 说明
本文是学习rk3568开发板驱动开发的记录,代码依托于rk3568开发板
1.2 字符设备介绍
字符设备是 Linux 驱动中最基本的一类设备驱动,字符设备就是一个一个字节,按照字节流进行读写操作的设备,读写数据是分先后顺序的。比如我们最常见的点灯、按键、IIC、SPI,LCD 等等都是字符设备,这些设备的驱动就叫做字符设备驱动。
Linux应用程序向下调用驱动程序流程如下:
在Linux中,一切皆是文件,驱动加载成功之后,会在dev目录下生成一个相应的文件,应用程序通过对这个名为“/dev/xxx”(xxx 是具体的驱动文件名字)的文件进行相应的操作即可实现对硬件的操作
应用程序运行在用户控件,Linux驱动属于内核的一部分,运行在内核空间。当我们在用户空间想要实现对内核的操作,比如使用 open 函数打开/dev/led 这个驱动,因为用
户空间不能直接对内核进行操作,因此必须使用一个叫做“系统调用”的方法来实现从用户空间“陷入”到内核空间,这样才能实现对底层驱动的操作。open、close、write 和 read 等这些函数是由 C 库提供的,在 Linux 系统中,系统调用作为 C 库的一部分,调用open函数的流程如下:
每一个系统调用,在驱动中都有与之对应的一个驱动函数,在Linux内核文件include/linux/fs.h中有个file_operations的接口提,定义了内核驱动操作函数集合。
1.3 file_operations定义
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
int (*iterate) (struct file *, struct dir_context *);
int (*iterate_shared) (struct file *, struct dir_context *);
__poll_t (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
unsigned long mmap_supported_flags;
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, loff_t, loff_t, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
int (*check_flags)(int);