linux字符设备驱动程序框架

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/cdev.h>
#include <linux/types.h>

#define	xxx_DEVICE_COUNT	1	

/*xxx字符设备结构体*/
struct xxx_dev
{
	struct cdev 	cdev;
	unsigned char 	*sth_of_xxx;	//预留
};
struct xxx_dev 	*xxx_dev;

/*自动创建设备节点类*/
static struct class *xxx_dev_class;
static struct class_device *xxx_dev_class_dev;

/*
	xxx设备相关的相关操作函数:open、read、write、close、ioctl等
*/
static int xxx_dev_open(struct inode *inode, struct file *filp)
{
	printk("Open xxx device OK.\n");
	return 0;
}

static int xxx_dev_close(struct inode *inode, struct file *filp)
{
	printk("Close xxx device OK.\n");
	return 0;
}

static int xxx_dev_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
	printk("Write xxx device OK.\n");
	return 0;
}

static int xxx_dev_read(struct file *file, const char __user *buf, size_t count, loff_t ppos)
{
	printk("Read xxx device OK.\n");
	return 0;
}

static int xxx_dev_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
	//struct xxx_dev *dev = filp->private_data;
	printk("DRIVER : Get cmd %d.\n", cmd);
	return 0;
}

/*
	xxx设备操作函数结构体
*/
struct file_operations xxx_fops = {
	.owner = THIS_MODULE,
	.open = xxx_dev_open,
	.release = xxx_dev_close,
	.read = xxx_dev_read,
	.write = xxx_dev_write,
	.ioctl = xxx_dev_ioctl,
};

/*
	xxx设备驱动模块的注册和卸载
*/
dev_t xxx_devno = 0;
int xxx_major = 0;
int xxx_minor = 0;
static int __init initialization_xxx_dev(void)
{
	int ret = 0;

	/* 申请设备号 */
	printk("Before register xxx Major = %d\n", xxx_major);
	if (xxx_major) {
		/*指定主设备号*/
		xxx_devno = MKDEV(xxx_major, xxx_minor);
		ret = register_chrdev_region(xxx_devno, xxx_DEVICE_COUNT, "xxx");
	} else {
		/*系统自动分配主设备*/
		ret = alloc_chrdev_region(&xxx_devno, xxx_minor, xxx_DEVICE_COUNT, "xxx");
		xxx_major = MAJOR(xxx_devno);
		xxx_minor = MINOR(xxx_devno);
	}
	if (ret < 0) {
		printk("Can‘t get xxx Major %d\n", xxx_major);
		return ret;
	}
	printk("After register xxx Major = %d\n", xxx_major);

	/* 申请设备结构体内存 */
	xxx_dev = kmalloc(sizeof(struct xxx_dev), GFP_KERNEL);
	if (NULL == xxx_dev) {
		printk("kmalloc failed.\n");
		unregister_chrdev_region(xxx_devno, xxx_DEVICE_COUNT);
		return -ENOMEM;
	}

	/* 字符设备注册 */
	cdev_init(&xxx_dev->cdev, &xxx_fops);
	xxx_dev->cdev.owner = THIS_MODULE;
	xxx_dev->cdev.ops = &xxx_fops;
	ret = cdev_add(&xxx_dev->cdev, xxx_devno, xxx_DEVICE_COUNT);
	if (ret < 0)
	{
		printk("Cdev add failed.\n");
		kfree(xxx_dev);
		unregister_chrdev_region(xxx_devno, xxx_DEVICE_COUNT);
		return ret;
	}

	/* 自动生成设备节点 */
	xxx_dev_class = class_create(THIS_MODULE, "xxx_dev");
	xxx_dev_class_dev = class_device_create(xxx_dev_class, NULL, xxx_devno, NULL, "xxx%d", xxx_minor);	// "/dev/xxx0"

	/* 模块初始化成功必须返回0 */
	printk("Module register OK.\n");
	return 0;
}

static void __exit cleanup_xxx_dev(void)
{
	/* 删除设备文件 */
	cdev_del(&xxx_dev->cdev);
	kfree(xxx_dev);
	unregister_chrdev_region(xxx_devno, xxx_DEVICE_COUNT);
	class_device_unregister(xxx_dev_class_dev);
	class_destroy(xxx_dev_class);

	printk("Module unregister OK.\n");
}

/*
	模块注册与卸载
*/
module_init(initialization_xxx_dev);
module_exit(cleanup_xxx_dev);

/*
	模块传参:insmod char_driver_frame.ko xxx_major=xxx xxx_minor=0
*/
module_param(xxx_major, int, S_IRUGO);
module_param(xxx_minor, int, S_IRUGO);

/*
	模块的相关声明
*/
MODULE_AUTHOR("lhbo");
MODULE_DESCRIPTION("GPIO Driver for xxx");
MODULE_LICENSE("GPL");

linux字符设备驱动程序框架,布布扣,bubuko.com

时间: 2024-10-03 22:42:28

linux字符设备驱动程序框架的相关文章

linux字符设备驱动程序框架(老方法)

#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/delay.h> #include <asm/uaccess.h> #include <asm/irq.h> #include <asm/io.h> #include <asm/a

浅析Linux字符设备驱动程序内核机制

前段时间在学习linux设备驱动的时候,看了陈学松著的<深入Linux设备驱动程序内核机制>一书. 说实话.这是一本非常好的书,作者不但给出了在设备驱动程序开发过程中的所须要的知识点(如对应的函数和数据结构),还深入到linux内核里去分析了这些函数或数据结构的原理.对设备驱动开发的整个过程和原理都分析的非常到位.但可能是因为知识点太多.原理也比較深的原因,这本书在知识点的排版上跨度有些大.所以读起来显得有点吃力,可是假设第一遍看的比較认真的话,再回头看第二次就真的可以非常好地理解作者的写作思

linux字符设备驱动程序源码分析

本文主要分析linux-2.6.28内核版本的字符设备抽象层源码文件char_dev.c.该文件代码量不大,但其为linux应用程序访问实际字符型硬件设备搭建了桥梁,进一步限定了linux字符设备驱动的设计框架. void __init chrdev_init(void) {  cdev_map = kobj_map_init(base_probe, &chrdevs_lock);  bdi_init(&directly_mappable_cdev_bdi); } 该函数在系统初始化启动时

20150216简单的Linux字符设备驱动程序

20150216简单的Linux字符设备驱动程序 2015-02-16 李海沿 关于字符设备驱动程序详细的知识点,本文就不再介绍了,很多同志,看了知识点,还是一头雾水,写不出来,所以,本文从实战出发,带领各位同胞们来实现一个字符设备驱动程序,改程序可作为字符设备的通用模板. 好了废话不多说,先上驱动程序,在驱动程序中加入详细注释: 1 /****************************** 2 linux 字符设备驱动程序 3 *****************************/

Linux字符设备驱动框架

字符设备是Linux三大设备之一(另外两种是块设备,网络设备),字符设备就是字节流形式通讯的I/O设备,绝大部分设备都是字符设备,常见的字符设备包括鼠标.键盘.显示器.串口等等,当我们执行ls -l /dev的时候,就能看到大量的设备文件,c就是字符设备,b就是块设备,网络设备没有对应的设备文件.编写一个外部模块的字符设备驱动,除了要实现编写一个模块所需要的代码之外,还需要编写作为一个字符设备的代码. 驱动模型 Linux一切皆文件,那么作为一个设备文件,它的操作方法接口封装在struct fi

字符设备驱动程序框架

via:http://blog.chinaunix.net/uid-20672257-id-3142809.html 1.写出open.write函数 2.告诉内核 1).定义一个struct file_operations结构并填充好 static struct file_operations first_drv_fops = { .owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */ .open = first_drv_op

字符设备驱动框架

scull from <Linux设备驱动程序> memdev.c /* * memdev.c * create at 2015/01/07 * 字符设备驱动程序框架 */ #include <linux/module.h> #include <linux/types.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/mm.h> #include <

字符设备驱动程序分析

字符设备驱动程序分析 下面是针对jz2440开发板写的一个led驱动程序,重点不在于该程序,而是以此为例,对字符设备驱动程序框架的分析总结: /* * jz2440 leds driver **/ #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> #in

11 Linux 块设备驱动程序

参考:https://www.cnblogs.com/big-devil/p/8590007.html Linux 块设备驱动程序 概念补充: 块 扇区是硬件数据传输的基本单元,块则是虚拟文件系统传输数据的基本单位.Linux内核中,块的大小必须是2的次幂,但不能超过一个页(4K)的大小. 段 同一物理页面中的硬盘存储介质上连续的多个块组成一个段.段的大小与块的个数有关,段包含多个块,块包含多个扇区.段在内核中由bio_vec结构体描述,多个段的信息存放于结构体bio中的biz_io_vec数组