Drive learning-daily notes day4

[1] Review
1. The use of
ioctl function ioctl(fd,100,100)
---------------------
unlocked_ioctl(file,cmd,args)
{ printk("cmd D% =, args =% D \ n-", cmd, args); // cmd args = 100 = 100; } command codes via ===> _ IO _IOR _IOW _IORW package 2. automatic device nodes class_create device_create class_destroy device_destroy








[2] The frame of the character device driver
user:
open("the name of the device file", the opening method); write(fd,buf,sizeof(buf));
|
device file name---->ls -i --- -->inode number (file system identification method)
|
------------------------------------- -|-----------------
kernel: |
--------------|
|
struct inode{ //All information in the file is in the inode Recorded umode_t i_mode; //File permission uid_t i_uid; //User id gid_t i_gid; //Group id unsigned long i_ino; //Inode number dev_t i_rdev; //Device number union { struct block_device *i_bdev; //Block device driver struct cdev *i_cdev; //Character device driver }; }












设备号1			  设备号2		       设备号n	
字符设备驱动1    字符设备驱动2       字符设备驱动n
---------         ---------            ---------
|  		|        |  	   |           |  		|
|  		|        |  	   |           |  		|
|  		|        |  	   |           |  		|
---------        ----------     ...    ----------

1.字符设备驱动的结构体
struct cdev {
	const struct file_operations *fops;
	//操作方法结构体
	struct list_head list;
	//内核链表
	dev_t dev;
	//设备号
	unsigned int count;
	//同种设备的个数
};

问:在应用程序中read write ioctl close如何通过
fd找到驱动的fops并调用里面对应的函数的?

1.open read write ioctl close函数是在哪里执行的?
	在进程中,进程的结构体对象是task_struct
	
2.既然fd是在进程中产生的,那么它就会在进程
	结构体中有记录
	struct task_struct {
		volatile long state;
		//进程的状态
		int prio, static_prio, normal_prio;
		unsigned int rt_priority;
		//进程的优先级
		pid_t pid;
		//进程号
		struct thread_struct thread;
		//进程中的线程
		struct files_struct *files;
		//打开文件时|候产生的各种信息
	}               |
				    |
	struct file  * fd_array[NR_OPEN_DEFAULT];
	
	这是fd的数组,
	fd_array[fd]===>struct file *

	struct file每打开一次文件,就问产生一个file结构体
	对象,将这个file结构体放大fd_array中,这个数组的
	下标就是这个文件的文件描述符。这个file结构体就是
	描述本次打开文件时候的各种信息的(打开方式,游标等)。
	struct file {
		const struct file_operations	*f_op;
		//操作方法结构体是从inode结构体获取的
		unsigned int 		f_flags;
		fmode_t			f_mode;
		loff_t			f_pos;
	}
	
通过fd访问到驱动中的read write close的流程如下:	
fd-->fd_array[fd]--->file-->fops-->read write close;
	

编写字符设备驱动的流程?(register_chrdev)
1.定义结构体
	struct cdev cdev;
	struct cdev *cdev = cdev_alloc(); 
	//使用cdev_alloc在内核空间分配内存

2.结构体成员的初始化
	void cdev_init(struct cdev *cdev, 
		const struct file_operations *fops)
	功能:初始化cdev的结构体,没有初始化设备号和设备的个数
	参数:
		@cdev:刚才分配好的结构体指针
		@fops:操作方法结构体
3.申请设备号
	1.静态申请(直接指定)
	int register_chrdev_region(dev_t from,
	unsigned count, const char *name)  
	功能:静态申请(直接指定)
	参数:
		@from :设备号的起始值
		@count:设备的个数
		@name :名字cat /proc/devices
	返回值:成功返回0 ,失败返回错误码
	
	2.动态申请(操作系统分配)
	int alloc_chrdev_region(dev_t *dev, 
		unsigned baseminor, unsigned count,                     
        const char *name)
	功能:.动态申请(操作系统分配)
	参数:
		@dev:返回申请到的第一个设备号
		@baseminor:次设备号的起始值 3
		@count:设备的个数
		@name :名字cat /proc/devices
	返回值:成功返回0 ,失败返回错误码
	
4.注册
	int cdev_add(struct cdev *p, dev_t dev, 
				unsigned count) 
	功能:注册字符设备驱动
	参数:
		@p:cdev结构体指针
		@dev:设备号
		@count:设备的个数
	返回值:成功返回0 ,失败返回错误码
	
-----------------------------------------------
void cdev_del(struct cdev *p)	
功能:注销字符设备驱动
参数:
	@p:cdev的结构体指针
	
	
void unregister_chrdev_region(dev_t from, unsigned count)
功能:释放设备号
参数:
	@from:设备号的起始的值
	@count:设备的个数
	
void kfree(void *p)
功能:释放cdev_alloc分配的内存
参数:
	@p:申请的内存的首地址。


练习:
	1.字符设备驱动分步实现流程(20分钟)

[3] What is the difference between a step-by-step character device driver and a character device completed by a function?
Register_chrdev allocates 256 device numbers at a time when registering a character device driver. The
user cannot specify it. If the number of devices required to be allocated in the company is 3 or 500
, this function cannot complete the corresponding function. Based on the above reasons, when the company is doing
character device driver development, the function register_chrdev is generally not used to
complete the registration of character device drivers.

[4] The problem of the device number
1. The range of the major device number is
0-2^12
0-4096
2. Question:
How to store the device number when using cat /proc/devices to view

	主设备号采用哈希表的形式存储
	
	主设备号%255 ==作为哈希表数组的下标。
	
3.问:自动分配设备号的时候为什么每
	次分配的都是250	?
	自动分配设备号的时候采用的是倒叙分配,从
	254往前查找,直到找到没有被使用过的主设备
	号为止,并将这个设备号分配给你。

4.问:自动申请主设备号的范围
	自动申请设备号的范围:	1-254
	其他的主设备号如何使用,只能采用静
	态申请设备号的方式完成

[5] to achieve the following functions
by writing a 1 to the red light myled0
writing 0 to myled0 off red
to a green light myled1 Write
Write 0 to green off myled1
write a bright blue light myled2 to
write to the blue lamp myled2 0

echo 1 >/dev/myled0  红灯亮
echo 0 >/dev/myled0  红灯灭

Guess you like

Origin blog.csdn.net/weixin_48430195/article/details/108671800