Linux 驱动开发学习笔记03

主题:    1. char/block/网络驱动的简介
               2. VFS的核心结构体
               3. char驱动的设计
               4. 基于缓冲区的char驱动例子
1.char/block/网络驱动的简介
==============================
讨论linux世界中如何对设备进行分类;
为什么用char/block/网络来分类设备?还有哪些分类方式
三类驱动最主要的区别就是数据的交互模式:
通过字节流,数据块和数据包交互
在实际的工作中,我们接触的char设备是最多的
2.vfs的核心结构体
==========================
在char驱动之上,是内核的VFS。也就是说,char驱动包含的函数由VFS调用。因此,在写char驱动之前,需要先了解vfs的一些核心结构体。
vfs以及char驱动的核心结构体都定义在
vfs在调用char驱动函数之前,会准备好一些特定的结构体;
(1)inode
记录文件的属主、访问时间等信息。当第一次打开文件的时候由VFS创建并初始化。当文件的所有引用都退出后,释放inode; 如果用户态有多个人同时打开一个文件,则VFS只需要分配一个inode.
在linux中有7种类型的文件,打开时VFS都会创建对应的inode。但不同类型文件会初始化inode中不同的成员。如果用户态打开的是char类型的文件,则inode中和char驱动相关的成员为:
i_rdev: 设备的设备号
i_cdev: 指向设备对应的cdev结构体
(2)file
对应用户态的open操作。如果多次打开同一个文件,内核会生成多个file
file中记录文件的打开方式,文件内部指针等。
当文件彻底关闭时,释放file
(3)file_operations
file_operations包含若干函数指针,这些函数由驱动来实现,并集中到file_operations中,注册到VFS
驱动一般要实现的函数有:
open
release
read
write
unlocked_ioctl
驱动可能会实现的有:
poll
mmap
fasync
(参考LDD3的对应章节)
3.char驱动的设计
=========================
(1)确定硬件信息
要确定硬件的数量,物理地址,中断号等信息;
比如今天用内存缓冲区做硬件,明天利用开发板上的LED灯做一个完整的char驱动

(2)为要支持的设备准备一个私有结构体
内核并不要求必须有私有结构体,但如果驱动支持多个设备,最好设计一个。
私有结构体完全由驱动人员自行设计,一般来说,会把和设备相关的信息写入该结构体,比如设备的地址等。

(3)为要支持的每个设备分配对应的设备号
设备号由char驱动分配,要求唯一
一般来说,如果char驱动可支持多个类似的设备,则应该为这些设备选择一个主设备号,然后为每个设备选择一个特定的次设备号。
尽量挑选和其他驱动不一样的主设备号。
可以看/proc/devices,文件中记录了其他驱动选择的主设备号;
也可以向内核申请,由内核分配一个主设备号;

(4)准备file_operations
函数集中包括open/release/read/write/unlocked_ioctl等函数,如果驱动支持多个设备,在函数中必须能区分自己访问的是哪个设备

(5)注册cdev
利用cdev结构体,将设备号和file_operations注册到VFS
一般来说,将cdev结构体包含到私有结构体中
上述的过程比较适合较简单的设备,比如看门狗,led灯,各种传感器等。较复杂设备的char驱动,常常要利用内核提供的驱动子系统代码进行设计。
4. 基于缓冲区的char驱动例子
=============================
参考03char/char_test01.c
该例子支持单缓冲区,支持ioctl
ioctl命令需要写用户态的测试程序03char/user_buf01.c
尝试写一个支持多缓冲区的例子
参考03char/char_test02.c

你可能感兴趣的:(嵌入式Linux,linux)