8、驱动错误处理

常使用goto语句对错误进行处理回

错误码

IS_ERR(data) 会检查 data 是否是一个错误指针。如果是,PTR_ERR(data) 宏可以被用来将错误指针转换回原来的错误码(errno 值),以便进行进一步的错误处理;

需要包含头文件 errno.h

例:

#include <linux/module.h>
#include <linux/init.h>
 
#include <linux/fs.h>
#include <linux/modulepram.h>
#include <linux/kdev_t.h>
 
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/asm-generic/uaccess.h>  
#include <linux/errno.h>
 
 
static int major;
static int minor; 
 
 
module_param(major,int,S_IRUGO);
MODULE_PARAM_DESC(major,"e.g:major=1");
 
module_param(minor,int,S_IRUGO);
MODULE_PARAM_DESC(minor,"e.g:minor=1");
 
 
static struct cdev cdev_test;
 
struct class *class;
struct device *device;
 
 
 
static  int cdev_test_open(struct inode *node, struct file *file)
{
     printk("cdev_test_open \n");
     return 0;
}
 
static int cdev_test_release(struct inode *node, struct file *file)
{
 
     printk("cdev_test_release \n");
     return 0;
 
}
 
static ssize_t cdev_test_read (struct file *file, char __user *buf, size_t size, loff_t *off)
{
    char kbuf[64]="123456hello";
    
    copy_to_user(buf,kbuf,strlen(kbuf));
 
     printk("cdev_test_read \n");
 
 
}  
 
static ssize_t cdev_test_write (struct file *file, const char __user *buf, size_t size, loff_t *off)
{
 
     char kbuf[64];
     copy_from_user(kbuf,buf,size);
     printk("write buf[%s]\n",kbuf);
     printk("cdev_test_write\n");
 
 
 
 
}
 
 
struct file_operations cdev_test_ops={
 
    .owner=THIS_MODULE,
    .open=cdev_test_open,
    .release=cdev_test_release,
    .read=cdev_test_read,
    .write=cdev_test_write,
    .ioctl=cdev_test_ioctl
};
 
 
static int cdv_init(void)
{
    dev_t dev_num;
    int ret;
    printk("input major=%d minor=%d \n",major,minor);
 
 
  
        //动态申请
        ret=alloc_chrdev_region(&dev_num,0,1,"chrdev_num");
        if(ret <0 )
        {
            printk("alloc_chrdev_regionerr %d\n",ret);
            goto err_alloc_chrdev_region ;
        }
       printk("dev_num=%d \n",dev_num);
       major = MAJOR(dev_num);
       minor = MINOR(dev_num);
       printk("input major=%d minor=%d \n",major,minor);
 
   
 
    cdev_test.owner= THIS_MODULE;
    cdev_init(&cdev_test,&&cdev_test_ops);  
    ret = cdev_add(&cdev_test,dev_num,1);
    if(ret <0 )
    {
      goto err_cdev_add ;
    }
 
    class = class_create(THIS_MODULE,"test");
    if(IS_ERR(class))
    {
        ret=PTR_ERR(class);
        goto err_class_create ;
    }

    device = device_create(class,NULL,dev_num,NULL,"/dev/test");
    if(IS_ERR(device ))
    {
        ret=PTR_ERR( device );
        goto err_device_create ;
    }


    
    
    printk("cdv init\n");
    return 0;

err_device_create :
    device_destroy(class,dev_num);
err_class_create :
    classs_destroy(class);
err_cdev_add :
    cdev_del(&cdev_test);
err_alloc_chrdev_region :
    unregister_chrdev_region(dev_num,1);
    return ret;
}
 
static void cdv_exit(void)
{ 
    
    device_destroy(class,dev_num);
    classs_destroy(class);
 
    cdev_del(&cdev_test);
    //释放设备号
    unregister_chrdev_region(dev_num,1);


    printk("cdv exit\n");
    return 0;
}
 
 
module_init(cdv_init);
module_exit(cdv_exit);
 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("SONG");
MODULE_VERSION("v1.0");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值