LINUX 设备驱动(完善 版(二))

 

 

dev_fifo.c

#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <asm/uaccess.h>


#define MAJOR_NUM	250

struct _MycDev {
	int len;
	char buff[50];
	struct cdev cdev;
};

static dev_t 	g_pDevNum = {0};
struct _MycDev 	*g_pcDev;
struct class  	*g_pCla;

//register device num
static int 	m_Ndevices = 1;
module_param(m_Ndevices, int, 0644);
MODULE_PARM_DESC(m_Ndevices, "The number of devices for register.\n");


static int 	myDev_fifo_open(struct indoe *inode, struct file *file);
static ssize_t 	mydev_fifo_read(struct file *file, char __user *ubuf, size_t size, loff_t *ppos);
static ssize_t 	mydev_fifo_write(struct file *file, const char __user *ubuf, size_t size, loff_t *ppos);
long 		mydev_fifo_unlocked_ioctl(struct file *file, unsigned int cmd,unsigned long arg);

int     __init 	MyDev_Fifo_Init(void);
void 	__exit	MyDev_Fifo_Exit(void);


static int   	mydev_fifo_open(struct indoe *inode, struct file *file)
{	
	return 0;	
}


static ssize_t 	mydev_fifo_read(struct file *file, char __user *ubuf, size_t size, loff_t *ppos)
{

	return 0;	
	
}


static ssize_t 	mydev_fifo_write(struct file *file, const char __user *ubuf, size_t size, loff_t *ppos)
{


	return 0;	
}


long 		mydev_fifo_unlocked_ioctl(struct file *file, unsigned int cmd,unsigned long arg)
{

	return 0;	

}


//设备操作函数接口
static const struct file_operations fifo_operations = {
	.owner = THIS_MODULE,
   	.open = mydev_fifo_open,
   	.read = mydev_fifo_read,
    	.write = mydev_fifo_write,
    	.unlocked_ioctl = mydev_fifo_unlocked_ioctl,
};


int     __init 	MyDev_Fifo_Init(void)
{
	int ret;
	int i =0;
	int j = 0;
	struct device *device;

	g_pcDev = kzalloc(m_Ndevices * sizeof(struct _MycDev), GFP_KERNEL);
	if(!g_pcDev){
		return -ENOMEM;	
        	printk(KERN_NOTICE "Error add cdevdemo");  
	}
	
	//设备号 : 主设备号(12bit) | 次设备号(20bit)	
	g_pDevNum  = MKDEV(MAJOR_NUM, 0);
	
	//静态注册设备号
	 ret = register_chrdev_region(g_pDevNum, m_Ndevices, "dev_fifo");
   	 if(ret < 0){
		//静态注册失败,进行动态注册设备号
       		ret = alloc_chrdev_region(&g_pDevNum,0,m_Ndevices,"dev_fifo");
        	if(ret < 0){
            		printk("Fail to register_chrdev_region\n");
            		goto err_register_chrdev_region;
        	}
	}
	
	//创建设备类
    	g_pCla = class_create(THIS_MODULE, "dev_fifo");
	if(IS_ERR(g_pCla)){
       		ret = PTR_ERR(g_pCla);
        	goto err_class_create;
    	}	
	
	printk("device: %d \n", m_Ndevices);

	for(i=0; i < m_Ndevices; i++){
		//init 字符设备
		cdev_init(&g_pcDev[i].cdev, &fifo_operations);	
		//添加设备到操作系统
        	ret = cdev_add(&g_pcDev[i].cdev,g_pDevNum + i,1);
        	if (ret < 0){
            		goto err_cdev_add;
        	}
       		//导出设备信息到用户空间(/sys/class/类名/设备名)
		device = device_create(g_pCla,NULL,g_pDevNum + i,NULL,"dev_fifo%d",i);
        	if(IS_ERR(device)){
           		ret = PTR_ERR(device);
            		printk("Fail to device_create\n");
            		goto err_device_create;    
		}
	}

	printk("Register dev_fito to system,ok!\n");
	return 0;

err_register_chrdev_region:
	return ret;

err_class_create:
	unregister_chrdev_region(g_pDevNum, m_Ndevices);

err_cdev_add:
	//将已经添加的全部除去
	for(j=0; j < i; j++){
		cdev_del(&g_pcDev[j].cdev);
	}

err_device_create:
	//将已经导出的设备信息除去
    	for(j = 0;j < i; j++){
        	device_destroy(g_pCla,g_pDevNum + j);    
    	}
	
}


void 	__exit	MyDev_Fifo_Exit(void)
{
	int i;
   	 //删除sysfs文件系统中的设备
    	for(i = 0;i < m_Ndevices;i ++){
        	device_destroy(g_pCla,g_pDevNum + i);    
    	}

    	//删除系统中的设备类
    	class_destroy(g_pCla);

   	 //从系统中删除添加的字符设备
    	for(i = 0;i < m_Ndevices;i ++){
        	cdev_del(&g_pcDev[i].cdev);
    	}

    	//释放申请的设备号
    	unregister_chrdev_region(g_pDevNum, m_Ndevices);
    	return;
}


MODULE_LICENSE("GPL");
module_init(MyDev_Fifo_Init);
module_exit(MyDev_Fifo_Exit); 


 

Makefile

ifeq ($(KERNELRELEASE),)
KERNEL_DIR ?=/lib/modules/$(shell uname -r)/build 
PWD :=$(shell pwd)
modules:
	$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
.PHONY:modules clean 
clean:
	$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean 
else 
    obj-m := dev_fifo.o 

endif


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值