字符驱动

1.什么是驱动程序
使硬件工作的软件
驱动程序为操作硬件提供良好内部接口,驱动程序为应用程序提供了访问设备的机制
2.驱动程序的两大任务
作为系统调用的一部分而执行,运行在进程上下文。
负责中断处理,运行在中断上下文
3.文件系统
1)文件系统是操作系统用于明确磁盘或分区上的文件的方法和数据结构;即在磁盘上组织文件的方法。也指用于存储文件的磁盘或分区,或文件系统种类。
2)操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。文件系统由三部分组成:与文件管理有关软件、被管理文件以及实施文件管理所需数据结构。
3)从系统角度来看,文件系统是对文件存储器空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。具体地说,它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,当用户不再使用时撤销文件等。
4.VFS虚拟文件系统
1)VFS的作用就是采用标准的Unix系统调用读写位于不同物理介质上的不同文件系统。
2)VFS是一个可以让open()、read()、write()等系统调用不用关心底层的存储介质和文件系统类型就可以工作的粘合层
5.驱动程序使用
Linux用户程序通过设备文件(又名:设备节点)来使用驱动程序操作字符设备和块设备
6.Linux内核模块的程序结构
1)模块加载函数(必须)module_init();
2)模块卸载函数(必须)module_exit();
3)模块许可证声明(必须)MODULE_LICENSE( “Dual BSD/GPL” );
4)模块参数(可选)。
5)模块导出符号(可选)
6)模块作者等信息声明(可选)
7.Linux字符设备驱动基础
1)驱动注册与初始化
字符设备通过字符设备文件来存取。字符设备文件由使用 ls /dev/ -l 的输出的第一列的“c”标识,主设备号,次设备号
主设备号用来标识与设备文件相连的驱动程序。次编号被驱动程序用来辨别操作的是哪个设备。
2)内核中如何描述设备号
dev_t devno = MKDEV(globalmem_major,0);
dev_t 其实质为unsigned int 32位整数,其中高12位为主设备号,低20位为次设备号。
//MKDEV(主设备号,次设备号);
如何从dev_t中分解出主设备号? MAJOR(dev_t devno);
如何从dev_t中分解出次设备号?MINOR(dev_t devno);
3)Linux内核如何给设备分配主设备号?
静态申请
int result = register_chrdev_region(devno,1,"globalmem");
devno//希望申请使用的设备号
1//希望申请使用设备号数目
globalmem//设备名(体现在/proc/devices)
动态分配
int result = alloc_chrdev_region(&devno,0,1,"globalmem");
4)注销设备号
unregister_chrdev_region(MKDEV(globalmem_major,0),1);
注销设备区域,注销从MKDEV(globalmem_major,0)开始的1个设备
8.创建设备文件
mknod 用法:mknod filename type major minor
9.模块------->驱动
1)注册模块,注销模块module_init()、module_exit()
2)注册设备号
3)字符设备注册,设备注消
字符设备使用 struct cdev 来描述。
struct cdev的分配可使用cdev_alloc函数来完成。
struct cdev的初始化使用cdev_init函数来完成。
struct cdev的注册使用cdev_add函数来完成。
字符设备的注销使用cdev_del函数来完成.4)字符设备的操作
static const struct file_operations globalmem_fops={
 .owner  = THIS_MODULE,
 .llseek = globalmem_llseek,
 .read   = globalmem_read,
 .write  = globalmem_write,
 .ioctl  = globalmem_ioctl,
 .open = globalmem_open,
 .release= globalmem_release,
};
10.操作
1)int (*open)(struct inode *, struct file *) 
在设备文件上的第一个操作,并不要求驱动程序一定要实现这个方法。
如果未初始化,则调用初始化,识别次设备号,如果必要,更新f_op指针,分配并填写被置于filp->private_data的数据结构
2)void (*release)(struct inode *, struct file *)
当设备文件被关闭时调用这个操作。
3)ssize_t (*read)(struct file*,char *,size_t,loff_t*)
用户空间和内核空间数据交互
用户空间指针和内核指针
驱动调用copy_to_user()将数据返回给用户
4)ssize_t(*write)(struct file*,const char*,size_t,loff_t*)
驱动调用copy_from_user()将用户数据读到本地buffer
5)int(*ioctl)(struct inode*,struct file*,unsigned int cmd,unsigned long arg)
驱动程序一般需支持通过Ioctl实现各种控制与参数设置
11.用户空间与内核空间数据传输
1)用户(进程)空间
受保护的空间,执行于“用户模式”
所有地址都是“逻辑”的,不能访问不属于自己的内存
需要转换成物理的(真实的)地址
执行指令时由硬件辅助完成转换
发生页面错误时间接地由操作系统完成
2)内核(系统)空间
不受保护的空间,执行于“超级模式”
能访问任何内存,所有地址都是“逻辑”的
需要转换成物理的(真实的)地址
执行指令时由硬件辅助完成转换
发生页面错误时,间接地由操作系统完成
12.驱动程序使用的内存
获取内存区(kmalloc分配物理内存)
globalmem_devp = kmalloc(sizeof(struct globalmem_dev), GFP_KERNEL);

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值