zoukankan      html  css  js  c++  java
  • linux驱动中断注册与注销带来的段错误

    错误描述:

    今天写了个重力传感器的驱动,按照通常的中断申请与注册流程,insmod时安静,运行测试程序正常,rmmod安静。但是..... 当我再次insmod时,报了一堆的oops错误,从错误描述中看根本找不出是我写的哪个函数有错,从此以后就再也不能insmod了,rmmod却报资源忙,这下是进也不是退也不是,每次到了这里就得断电重启,这bug,卡了我整整一天。

     1 root@nufront ~$ insmod mc3xxx.ko 
     2 [  199.970066] mc3xxx: request irq sucssce! irq = 105 
     3 [  200.064055] input: mc3xxx as /devices/virtual/input/input1
     4 root@nufront ~$ [  200.314850] mc3xxx: entern extint_irq_handler 
     5 
     6 root@nufront ~$ 
     7 root@nufront ~$ 
     8 root@nufront ~$ 
     9 root@nufront ~$ 
    10 root@nufront ~$ rmmod mc3xxx.ko 
    11 root@nufront ~$ insmod mc3xxx.ko 
    12 [  230.449460] Unable to handle kernel paging request at virtual address bf001e01
    13 [  230.456598] pgd = cf80c000
    14 [  230.459287] [bf001e01] *pgd=0f590811, *pte=00000000, *ppte=00000000
    15 [  230.465539] Internal error: Oops - BUG: 7 [#1] PREEMPT SMP ARM
    16 [  230.471351] Modules linked in: mc3xxx(O+) [last unloaded: mc3xxx]
    17 [  230.477435] CPU: 0 PID: 2562 Comm: insmod Tainted: G           O    4.4.0-xil1
    18 [  230.486975] Hardware name: Xilinx Zynq Platform
    19 [  230.491492] task: c8213ac0 ti: cf8cc000 task.ti: cf8cc000
    20 [  230.496878] PC is at strnlen+0x10/0x28
    21 [  230.500607] LR is at string+0x30/0xcc
    22 [  230.504254] pc : [<c01dd6d8>]    lr : [<c01de8e4>]    psr: a0000093
    23 [  230.504254] sp : cf8cdc20  ip : 00000073  fp : cf8cdc50
    24 [  230.515707] r10: c0626f80  r9 : 00000002  r8 : c0514663
    25 [  230.520916] r7 : bf001e01  r6 : 0000ffff  r5 : c0627360  r4 : c0626fc2
    26 [  230.527426] r3 : bf001e01  r2 : bf001e01  r1 : fffffffe  r0 : bf001e01
    27 [  230.533937] Flags: NzCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment user
    28 [  230.541141] Control: 18c5387d  Table: 0f80c04a  DAC: 00000055
    29 [  230.546869] Process insmod (pid: 2562, stack limit = 0xcf8cc210)
    30 [  230.552858] Stack: (0xcf8cdc20 to 0xcf8ce000)
    31 [  230.557205] dc20: ff0a0004 cf8cdd0c c0626fc2 cf8cdd10 c0627360 c01e0144 c06264
    32 [  230.565363] dc40: ffffffff ffff0008 ffffffff 000003e0 ff0a0004 ffffffff fffff0
    33 [  230.573521] dc60: ffffffff 00000000 00000069 00000000 00000000 00000000 00000c
    34 [  230.581681] dc80: 00000000 c005411c 00000069 00000002 cf8cdcc0 c0057628 cf8cd8
    35 [  230.589840] dca0: cf8cdca8 cf8cdcac 00000000 60000093 c8109f00 c0054464 cd50e0
    36 [  230.597999] dcc0: 00000069 ce97e380 c8109f00 cd50e5e0 60000013 c0054480 c0514c
    37 [  230.606158] dce0: 00000001 c008c67c c051462c cf8cdcfc cf723a00 c00569e4 c05149
    38 [  230.614317] dd00: 00000002 bf008e01 00000002 bf001e01 d7bac450 00000002 00000c
    39 [  230.622476] dd20: 00000069 cf723a00 cd50e580 00000000 c8109f00 00000002 000000
    40 [  230.630636] dd40: c8109f00 d7baca7c ffffffed bf008f8c cd4f5600 00000500 bf0088
    41 [  230.638796] dd60: bf008e01 c8109f00 bf008514 cd4f5600 cd4f5620 ffffffed bf0088
    42 [  230.646954] dd80: 00000001 c032c068 cd4f5620 00000000 bf008f8c 00000008 bf0098
    43 [  230.655113] dda0: 00000000 cd4f5620 cd4f5654 bf008f8c 00000000 c0271814 bf0084
    44 [  230.663273] ddc0: 00000000 c02700e8 c80ef75c c8406b34 bf008f8c cf7ae980 c06164
    45 [  230.671432] dde0: bf008e01 cf8cc020 00000000 bf008f8c 00000000 00000000 c05f48
    46 [  230.679591] de00: c0616494 bf00b000 bf008f70 c032c628 c05f4e50 bf00b000 000004
    47 [  230.687749] de20: ff0a0004 00000000 00000001 00000001 c80b5000 00000001 000000
    48 [  230.695909] de40: d7da5e60 d7da5e80 00000000 c0091404 c05f4e44 d7da5e60 000000
    49 [  230.704068] de60: 00000000 00000000 d7da5e60 c0092ff4 d7da5e60 bf009080 cf8cc0
    50 [  230.712228] de80: ce97e1c0 bf0090c8 00000500 c008c934 bf009080 0000003e bf0090
    51 [  230.720386] dea0: 00000001 c00773b8 bf00908c 00007fff 00000000 c0074c74 000004
    52 [  230.728546] dec0: bf00922c 000000b1 e0940674 000a7008 6e72656b 00006c65 000000
    53 [  230.736703] dee0: 00000000 00000000 00000000 00000000 00000000 00000000 000000
    54 [  230.744862] df00: 00000000 00000000 00000000 00000000 00000000 00000000 000000
    55 [  230.753023] df20: 00000000 c056e410 00000000 00005198 e0942198 00000000 000ac8
    56 [  230.761183] df40: cf8cc000 00000000 00000000 c00776dc e093d000 00005198 e09407
    57 [  230.769341] df60: e0941af4 00002248 00002668 00000000 00000000 00000000 00000f
    58 [  230.777501] df80: 00000016 00000013 00000011 00000000 00005198 bea85e14 bea850
    59 [  230.785661] dfa0: c000ec44 c000eaa0 00005198 bea85e14 000a7018 00005198 000a79
    60 root@nufront ~$ rm mc3xxx.ko 
    61 root@nufront ~$ lsmod 
    62 Module                  Size  Used by
    63 mc3xxx                 14935  1 
    64 root@nufront ~$ rmmod mc3xxx
    65 rmmod: can't unload 'mc3xxx': Device or resource busy
    66 root@nufront ~$ reboot -f
    67 [  508.527520] max_wdt_notify_sys: feed watchdog

    发现问题:

    后来,我尝试着先不注册中断,这样就能随意地加载卸载,逐渐地缩小目标范围,最终锁定“嫌疑犯”:  request_irq() / free_irq() 。  只要注释了这一对“夫妇”,程序就乖乖地听我的话了。

    于是乎,确定时这里面传参的问题了,又在网上几经周折,终于知道原因了:这个gpio是与其他gpio等共享52号中断线的(xilinx zynq-7z030二合一芯片),所以得以共享中断方式注册,而且最后一个参数必不可少,他就是通过这最后一个参数区分具体是谁触发的。

    改正后代码:

    static irqreturn_t extint_irq_handler(int irq, void *dev)
    {
        struct i2c_client *client = container_of(mc3xxx_device.parent, struct i2c_client, dev);
        struct mc3xxx_data *data;
        data = i2c_get_clientdata(client);
        if (&data->input_dev->dev == dev) {
            udelay(100);

    
            i2c_smbus_read_byte_data(client, 0x03);
            GSE_ERR("entern extint_irq_handler 
    ");
        
        }
        
         return IRQ_HANDLED;
    
    }
    
    
    
    probe() 
    {
    
    
       .......
    
    
        
    /* add by xxg for surpport extern interrupt triger */
        np = of_find_compatible_node(NULL, NULL, "mcube,mc3xxx");
        if(NULL == np){
             printk(KERN_DEBUG "not fund device node mc3xxx 
    ");
            goto erro_node_find ;
        }
        
    #if !(DTS_HAVE_INT)        
        data->gpio = of_get_named_gpio(np, "gpio_int", 0);
        if (data->gpio < 0) {
            printk(KERN_DEBUG "get gpio failed 
    ");
            goto erro_node_find ;
        }
        if(gpio_is_valid(data->gpio)){//判断是不是一个可用的gpio号
            ret = gpio_request_one(data->gpio, GPIOF_IN, "mc3xxx");//将这个gpio的引脚复用功能设置成中断功能
            if(ret){
                printk(KERN_DEBUG "get gpio failed 
    ");
                goto erro_get_gpio;
            }
            GSE_ERR("get gpio sucssce! gpio = %d 
    ", data->gpio);
            data->irq = gpio_to_irq(data->gpio);//为gpio申请一个软中断号
        }
        else {
            goto erro_get_gpio;
        }
        
    #endif    
        
        
    #if DTS_HAVE_INT
            data->irq = of_irq_get(np, 0);
    #endif
    
        if (data->irq < 0) {
            printk(KERN_DEBUG "gpio to irq failed 
    ");
            goto erro_get_gpio ;
        }
        
        ret = request_irq(data->irq, extint_irq_handler, IRQF_TRIGGER_FALLING  | IRQF_SHARED ,
                data->input_dev->name , &data->input_dev->dev);//将申请到的软中断号注册进内核(绑定回调函数)
        if(ret){
            printk(KERN_DEBUG "requst irq failled 
    ");
            goto erro_get_irq ;           
        }
        GSE_ERR("request irq sucssce! irq = %d 
    ", data->irq);
    
    
       ......
    
    
    }
    
    
    
    
    
    static int mc3xxx_remove(struct i2c_client *client)
    {
        struct mc3xxx_data *data = i2c_get_clientdata(client);
        
        destroy_workqueue(data->mc3xxx_wq);
        free_irq(data->irq, &data->input_dev->dev );
        gpio_free(data->gpio);
        hrtimer_cancel(&data->timer);
        input_unregister_device(data->input_dev);
        misc_deregister(&mc3xxx_device);
        sysfs_remove_group(&data->input_dev->dev.kobj, &mc3xxx_group);
        
        kfree(data);
        return 0;
    }
  • 相关阅读:
    Cannot find a free socket for the debugger
    如何让myeclipse左边选中文件后自动关联右边树
    myeclipse反编译安装 jd-gui.exe下载
    MyEclipse报错Access restriction: The type BASE64Encoder is not accessible due to restriction on required library
    如何使用JAVA请求HTTPS
    如何使用JAVA请求HTTP
    SVN提交代码时报405 Method Not Allowed
    对称加密和非对称加密
    ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
    调整Linux操作系统时区-centos7
  • 原文地址:https://www.cnblogs.com/xxg1992/p/6842725.html
Copyright © 2011-2022 走看看