驱动初步

驱动分为:字符设备驱动,块设备驱动和网络设备驱动。

字符设备驱动是操作字节流,不允许随机访问。

块设备允许随机访问。

字符设备比较基础,下面给出编写字符驱动的方法。

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

MODULE_LICENSE ("GPL");

static int __init hello_2_init (void)
{
printk (KERN_INFO "Hello world\n");
return 0;
}

static void __exit hello_2_exit (void)
{
printk (KERN_INFO "Goodbye world\n");
}

module_init (hello_2_init);
module_exit (hello_2_exit);

最简单的驱动模型:1.加载模块 2.卸载模块 3.许可证声明

以下是典型的字符设备驱动的编写:

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/init.h>

#include <linux/fs.h>

#include <linux/cdev.h>



MODULE_LICENSE ("GPL");



int hello_major = 250;

int hello_minor = 0;

int number_of_devices = 1;



struct cdev cdev;

dev_t dev = 0;



struct file_operations hello_fops = {

.owner = THIS_MODULE

};



static void char_reg_setup_cdev (void)

{

int error, devno = MKDEV (hello_major, hello_minor);

cdev_init (&cdev, &hello_fops);

cdev.owner = THIS_MODULE;

// cdev.ops = &hello_fops;

error = cdev_add (&cdev, devno , 1);

if (error)

printk (KERN_NOTICE "Error %d adding char_reg_setup_cdev", error);



}



static int __init hello_2_init (void)

{

int result;

dev = MKDEV (hello_major, hello_minor);

result = register_chrdev_region (dev, number_of_devices, "hello");

if (result<0) {

printk (KERN_WARNING "hello: can't get major number %d\n", hello_major);

return result;

}



char_reg_setup_cdev ();

printk (KERN_INFO "Registered character driver\n");

return 0;

}



static void __exit hello_2_exit (void)

{

dev_t devno = MKDEV (hello_major, hello_minor);



cdev_del (&cdev);



unregister_chrdev_region (devno, number_of_devices);



printk (KERN_INFO "char driver cleaned up\n");

}



module_init (hello_2_init);

module_exit (hello_2_exit);

 

 

第一步:在加载函数中首先申请设备

dev = MKDEV (hello_major, hello_minor);

这是个宏函数#define MKDEV(major,minor) (((major) << MINORBITS) | (minor))

返回一个dev_t类型的数据,它是主设备号和此设备号的拼接,内核中定义前12位是主设备号,后20位是次设备号。

第二步:注册设备节点号

result = register_chrdev_region (dev, number_of_devices, "hello");静态申请

alloc_chrdev_region动态创建节点。

第一个参数是链接的设备号,第二个是有几个设备,第三个参数数设备的名称

第三步:注册设备

char_reg_setup_cdev ();

static void char_reg_setup_cdev (void)
{
int error, devno = MKDEV (hello_major, hello_minor);
cdev_init (&cdev, &hello_fops);
cdev.owner = THIS_MODULE;
error = cdev_add (&cdev, devno , 1);
if (error)
printk (KERN_NOTICE "Error %d adding char_reg_setup_cdev", error);

 }

首先初始化cdev结构体,初始化结构体的函数里面的第二个参数是一个结构体,在此初始化前

要先把这个结构体填充,然后add来注册设备。

struct file_operations hello_fops = {
.owner = THIS_MODULE
};

file_operations类型里有很多操作,包括read,write等

通过这些操作基本上的功能就会实现。

 

 

你可能感兴趣的:(驱动)