您的位置:首页 > 其它

简单字符设备驱动程序的操作步骤

2017-09-21 08:51 211 查看
一、Linux驱动程序开发步骤

1.查看原理图,数据手册等

2.找相近的驱动程序作为模板

3.实现驱动程序的初始化

4.设计所要实现的操作:open,read,write,close

5.实现中断(可以不需要)

6.用insmod命令加载驱动

二、驱动框架

驱动是无法直接识别应用程序上的应用层API:read,open,write等,需要对应驱动程序上的led_read,led_open,led_write,这些都是驱动函数。

每个系统调用,驱动程序怎样和它对应起来?

使用file_operations结构,和应用层API对接。

Linux怎么知道去调用哪个驱动程序的file_operations?

根据设备类型和主设备号,需要将注册函数将主设备号和file_operations一起注册到内核

将驱动程序加载到内核,调用驱动初始化函数,像内核注册

module_init(memdev_init);

三、驱动程序的加载和卸载

module_init(memdev_init);

module_exit(memdev_exit);

 四、几种重要的数据结构

struct file

         file结构代表一个打开的文件,它由内核在open时创建,并传递给该文件上进行操作的所有函数,直到最后的close函数。

         file结构private_data是跨系统调用时保存状态信息非常有用的资源。

         file结构的f_ops 保存了文件的当前读写位置。

struct inode

         内核用inode代表一个磁盘上的文件,它和file结构不同,后者表示打开的文件描述符。对于单个文件,可能会有许多个表示打开文件的文件描述符file结构,但他们都指单个inode结构。inode的dev_t i_rdev成员包含了真正的设备编号,struct cdev *i_cdev包含了指向struct cdev结构的指针。

struct file_operations

         file_operations结构保存了字符设备驱动程序的方法。它是一个在 <linux/fs.h> 中定义的 struct file_operations 结构,这是一个内核结构,不会出现在用户空间的程序中,它定义了常见文件 I/O 函数的入口。系统调用函数通过内核,最终调用对应的 struct file_operations 结构的接口函数(例如,open() 文件操作是通过调用对应文件的file_operations 结构的 open 函数接口而被实现)。当然,每个设备的驱动程序不一定要实现其中所有的函数操作,若不需要定义实现时,则只需将其设为
NULL 即可。

驱动程序的简单模板:

#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");//模块开源许可声明

/* 模块加载时的初始化函数 */
// __init的意思是将代码放入特定的初始化内存区域,初始化后空间可以回收
static int __init myinit(void)
{
printk(KERN_CRIT"hello mymodule!\n");
printk(KERN_CRIT"module name :%s\n",THIS_MODULE->name);

return 0;//内核编程,有返回值的一定不要遗漏
}
module_init(myinit);//告知系统哪个是初始化函数

/* 模块清理函数 */
//__exit的意思是如果以后不卸载则不要放入系统
static void __exit myexit(void)
{
printk(KERN_CRIT"goodbye cruel world\n");
}
module_exit(myexit);//告知系统哪个是清理函数设备号和设备类的创建和销毁:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h> //设备号注册相关
#include <linux/device.h> //class和device相关
MODULE_LICENSE("GPL");
dev_t devno;//设备号
struct class *cls; //设备类

static int __init myinit(void)
{//在模块初始化时,动态申请前设备号
alloc_chrdev_region(&devno,10,1,"mydev");
cls=class_create(THIS_MODULE,"myclass");//创建类
device_create(cls,NULL,devno,NULL,"mynewdev");//在类下面创建设备
printk("major is %d, minor is %d\n",MAJOR(devno),MINOR(devno));
return 0;
}
module_init(myinit);
static void __exit myexit(void)
{//模块清理的时候,反注册设备号
device_destroy(cls,devno);//销毁设备
class_destroy(cls);//销毁类
unregister_chrdev_region(devno,1);//反注册设备号
}
module_exit(myexit);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐