linux驱动学习2——scull0模块

1.目的

         熟悉字符设备驱动程序编写及调试方法。

2.源码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/types.h>
 
#define SCULL_NAME "scull0"
 
struct st_scull_dev{
         struct cdev char_dev;
};
 
static int scull_ioctl_open(struct inode *node,struct file *filep)
{
         int ret = 0;
         struct st_scull_dev *dev;
        
         pr_info("%s device is open.\n", SCULL_NAME);
        
         dev =container_of(node->i_cdev, struct st_scull_dev, char_dev);
         filep->private_data= dev;
        
         return ret;
}
 
static int scull_ioctl_release(struct inode *node,struct file *filep)
{
         pr_info("%s device is close.\n", SCULL_NAME);
         return 0;  
}
 
static ssize_t scull_ioctl_read(struct file *filep, char __user *buffer, size_t count, loff_t *offp)
{
         pr_info("sculldevice is read size: %ld. \n", count);
         return 0;  
}
 
static ssize_t scull_ioctl_write(struct file *filep, const char __user *buffer, size_t count, loff_t *offp)
{
         ssize_t ret = (ssize_t)count;
         pr_info("sculldevice is write size: %ld. \n", ret);
         return ret;
}
 
static dev_t scull_dev_no;
static struct class *scull_class;
static struct st_scull_dev *scull_dev;
static const struct file_operations scull_fops = {
         .owner= THIS_MODULE,
         .read= scull_ioctl_read,
         .write= scull_ioctl_write,
         .open= scull_ioctl_open,
         .release= scull_ioctl_release,             
};
static int scull_init(void)
{
         int ret = 0;
         struct device *scull_device;
 
         ret =alloc_chrdev_region(&scull_dev_no, 0, 1, SCULL_NAME);
         if(ret < 0){
                   pr_err("%s:Error in allocating char device region. Err: %d\n", KBUILD_MODNAME, ret);
                   goto alloc_region_fail;
         }
        
         scull_class= class_create(THIS_MODULE, "scull_class");
         if(IS_ERR(scull_class)){
                   pr_err("%s:Error in creating class\n", KBUILD_MODNAME);
                   ret= PTR_ERR(scull_class);
                   goto create_class_fail;
         }
 
         scull_device= device_create(scull_class, NULL, scull_dev_no, NULL, SCULL_NAME);
         if(IS_ERR(scull_device)){
                   pr_err("%s:Error in creating character device.\n", KBUILD_MODNAME);
                   ret= PTR_ERR(scull_device);
                   goto create_device_fail;
         }
        
         scull_dev= kmalloc(sizeof(struct st_scull_dev), GFP_KERNEL);
         if(!scull_dev){
                   pr_err("Errorallocating memory\n");
                   ret= -ENOMEM;
                   goto create_device_fail;
         }
        
         memset(scull_dev,0, sizeof(struct st_scull_dev));
        
         cdev_init(&scull_dev->char_dev,&scull_fops);
         ret =cdev_add(&scull_dev->char_dev, scull_dev_no, 1);
         if(ret < 0){
                   pr_err("Errorin adding character device\n");
                   goto create_device_fail;  
         }
         pr_info("%s major no: %d\n", SCULL_NAME, MAJOR(scull_dev_no));
         return ret;
 
create_device_fail:
         device_destroy(scull_class,scull_dev_no);
create_class_fail:
         class_destroy(scull_class);
alloc_region_fail:
         unregister_chrdev_region(scull_dev_no,1);
         return ret;
}
 
static void scull_exit(void)
{
         device_destroy(scull_class,scull_dev_no);
         class_destroy(scull_class);
         cdev_del(&scull_dev->char_dev);
         unregister_chrdev_region(scull_dev_no,1);
         kfree(scull_dev);
         pr_info("Goodbye,cruel word\n");
}
 
module_init(scull_init);
module_exit(scull_exit);
 
 
MODULE_LICENSE("Dual BSD/GPL");


3.测试

	sudo chmod 777 /dev/scull0	        #修改字符设备权限
	cat /dev/scull0				#读测试
	ls -l > /dev/scull0			#写测试1
	cp scull.c > /dev/scull0		#写测试2
	cat /proc/devices			#查看主设备号




         


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值