LDD3-最简字符设备驱动freg (register_chrdev)

设备驱动分层:设备节点,设备驱动相关

设备节点相关:

freg_init()

{      

         ret = register_chrdev(MAJOR_NUM, "freg", &freg_fops);

}

freg_exit()

{

         unregister_chrdev(MAJOR_NUM, "freg");

}

struct file_operations freg_fops = {
.owner = THIS_MODULE,
.write = freg_write,
.read  = freg_read,
};

并简单的将freg_write freg_read 实现,完整如下:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h> 

/* 主设备号 */
#define MAJOR_NUM 250 

static ssize_t freg_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos);
static ssize_t freg_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos);

/* "freg"设备的全局变量 */
static int freg_var = 0; 


static ssize_t freg_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
	/* 将freg_var从内核空间复制到用户空间 */  
	if (copy_to_user(buf, &freg_var, sizeof(int))) { 
		return - EFAULT;
	} 
	printk("freg_read enter ,the data is %d\n",freg_var);
	return sizeof(int);
}

static ssize_t freg_write (struct file *filp, const char *buf, size_t len, loff_t *off)
{
	/* 将用户空间的数据复制到内核空间的freg_var */
	if (copy_from_user(&freg_var, buf, sizeof(int))) {
		return -EFAULT;
	} 
	printk("freg_write enter ,the data is %d\n",freg_var);
	return sizeof(int);
}

/* 初始化字符设备驱动的file_operations结构体 */
struct file_operations freg_fops = {
		.owner = THIS_MODULE,
		.write = freg_write,
		.read  = freg_read,
};

static int __init freg_init(void)
{
	int ret;
	
	printk(KERN_ALERT"Initializing freg device.\n");
	
	/* 注册设备驱动 */
	ret = register_chrdev(MAJOR_NUM, "freg", &freg_fops); 
	if (ret) {
		printk("freg register failure");
	}
	else{
		printk("freg register success");
	}
	return ret;
}

static void __exit freg_exit(void)
{
	printk(KERN_ALERT"Destroy freg device.\n");
	unregister_chrdev(MAJOR_NUM, "freg");
}

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Fake Register Driver");

module_init(freg_init);
module_exit(freg_exit);

编译好后,insmod freg.ko加载驱动。

# cat /proc/devices | grep freg

通过以上命令来查找freg的主设备号

# mknod /dev/freg c 250 0

创建设备节点

应用程序测试:

#include <stdio.h>
#include <sys/stat.h>  //获得文件的属性,它可以返回一个结构,里面包含文件全部属性
#include <fcntl.h>        //设备驱动程序接口是由结构说明,它定义在fcntl.h中
#include <sys/types.h> //类型 clock_t,dev_t,off_t,ptrdiff,size_t,ssize_t,time_t

void main(void)
{
      int fd, num;
  
      fd = open("/dev/freg", O_RDWR, S_IRUSR | S_IWUSR); 
      if (fd != -1 ){

            read(fd, &num, sizeof(int));
            printf("The var of freg is %d\n", num);

            printf("Please input the num written to freg\n");
            scanf("%d", &num);
            write(fd, &num, sizeof(int));
     
            read(fd, &num, sizeof(int));
            printf("The var of freg is %d\n", num);
   
            close(fd);
      }else{
            printf("Device open failure\n");
      }
}

简单总结,这个是最原始的最简单字符设备驱动程序,很多ldd3上都不推荐用了的调用,但是这个练习一下还有很有用的。也是一个极为老的方法,2.4用的,2.6不再用。以后会消失,再起写下只为熟悉一下吧。以后写程序坚决不用.

你可能感兴趣的:(LDD3)