触发IRQ处理程序后如何写文件?

时间:2019-06-11 01:55:51

标签: linux linux-kernel linux-device-driver

我试图在触发IRQ处理程序后写入文件(/ tmp / trigger_irq)。
但是Ubuntu总是显示内核崩溃。

PS。 / tmp / trigger_irq始终存在。


系统架构

I2C地址-> FPGA(INT)-> CPU(GPIO_40)-> Linux驱动程序(IRQ)-> IRQ处理程序->写入文件

如果i2c地址为0x01,则会触发IRQ处理程序。

i2cset -f -y 3 0x60 0x0f 0x01(触发IRQ)


紧急恐慌消息

[ 2986.981436] kernel BUG at fs/buffer.c:1270!
[ 2986.985615] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
[ 2986.991091] Modules linked in: cpld_irq(O) cavium_rng_vf rng_core smsc75xx usbnet cavium_rng lm90 xp80_Pcie_Endpoint ipv6
[ 2987.002075] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G           O    4.9.0-OCTEONTX_SDK_6_2_0_p2_build_35 #28
[ 2987.011891] Hardware name: Cavium ThunderX CN83XX board (DT)
[ 2987.017541] task: ffff00000905b380 task.stack: ffff000009030000
[ 2987.023455] PC is at __find_get_block+0x100/0x108
[ 2987.028150] LR is at __getblk_gfp+0x30/0x2c8
[ 2987.032410] pc : [<ffff000008212b08>] lr : [<ffff000008213118>] pstate: 204001c9
[ 2987.039795] sp : ffff8003fea439c0
[ 2987.043099] x29: ffff8003fea439c0 x28: ffff8003c5e79800 
[ 2987.048406] x27: 0000000000000001 x26: 0000000000001678 
[ 2987.053714] x25: 0000000003100187 x24: 0000000000000008 
[ 2987.059021] x23: 0000000003100187 x22: ffff8003a02a0000 
[ 2987.064328] x21: ffff8003fea43b28 x20: 0000000000001000 
[ 2987.069635] x19: ffff8003c5ac7800 x18: 0000000000000a03 
[ 2987.074943] x17: 0000ffff8c6af290 x16: ffff0000081f1710 
[ 2987.080250] x15: 0000ffff8c79ccc0 x14: 0000000000000000 
[ 2987.085557] x13: ffffffffffffffff x12: 0000000000000000 
[ 2987.090864] x11: 0101010101010101 x10: ffff8003a0d5b700 
[ 2987.096172] x9 : 0000000000000000 x8 : ffff8003a15e05f0 
[ 2987.101479] x7 : ffff8003fea45188 x6 : 0000000000000020 
[ 2987.106786] x5 : 0000000000000018 x4 : ffff8003a02e0270 
[ 2987.112093] x3 : 00000000000001c0 x2 : 0000000000001000 
[ 2987.117400] x1 : 0000000003100187 x0 : ffff8003a02a0000 
[ 2987.122707] 
[ 2987.124189] Process swapper/0 (pid: 0, stack limit = 0xffff000009030020)
[ 2987.130880] Stack: (0xffff8003fea439c0 to 0xffff000009034000)
[ 2987.136615] Call trace:
[ 2987.139053] Exception stack(0xffff8003fea437f0 to 0xffff8003fea43920)
[ 2987.145484] 37e0:                                   ffff8003c5ac7800 0001000000000000
[ 2987.153305] 3800: ffff8003fea439c0 ffff000008212b08 ffff000009008000 0000000000000000
[ 2987.161126] 3820: ffff8003fea43860 ffff0000080815bc ffff8003fea43860 ffff0000080e999c
[ 2987.168947] 3840: ffff8003fea4a9e8 ffff8003c7118000 ffff8003fea43860 ffff0000080e99b0
[ 2987.176768] 3860: ffff8003fea438e0 ffff0000080dd294 ffff8003fea4a980 ffff8003fea4a980
[ 2987.184588] 3880: 0000000000000001 0000000000000001 ffff8003a02a0000 0000000003100187
[ 2987.192409] 38a0: 0000000000001000 00000000000001c0 ffff8003a02e0270 0000000000000018
[ 2987.200229] 38c0: 0000000000000020 ffff8003fea45188 ffff8003a15e05f0 0000000000000000
[ 2987.208050] 38e0: ffff8003a0d5b700 0101010101010101 0000000000000000 ffffffffffffffff
[ 2987.215870] 3900: 0000000000000000 0000ffff8c79ccc0 ffff0000081f1710 0000ffff8c6af290
[ 2987.223692] [<ffff000008212b08>] __find_get_block+0x100/0x108
[ 2987.229430] [<ffff00000825e17c>] __ext4_get_inode_loc+0x104/0x378
[ 2987.235515] [<ffff00000826286c>] ext4_reserve_inode_write+0x3c/0xb0
[ 2987.241773] [<ffff00000826290c>] ext4_mark_inode_dirty+0x2c/0x188
[ 2987.247857] [<ffff000008265e54>] ext4_dirty_inode+0x44/0x70
[ 2987.253421] [<ffff00000820a654>] __mark_inode_dirty+0x3c/0x210
[ 2987.259246] [<ffff0000081f9b2c>] generic_update_time+0x7c/0xc0
[ 2987.265069] [<ffff0000081f9cfc>] file_update_time+0xa4/0x108
[ 2987.270721] [<ffff000008166f30>] __generic_file_write_iter+0x98/0x1c8
[ 2987.277153] [<ffff000008259e54>] ext4_file_write_iter+0xc4/0x2f0
[ 2987.283150] [<ffff0000081de13c>] __vfs_write+0xac/0x100
[ 2987.288366] [<ffff0000081dec98>] vfs_write+0xa0/0x1b8
[ 2987.293412] [<ffff000000ed0058>] cpld_irq_isr+0x58/0xd8 [cpld_irq]
[ 2987.299583] [<ffff0000080ff754>] __handle_irq_event_percpu+0x9c/0x128
[ 2987.306015] [<ffff0000080ff7fc>] handle_irq_event_percpu+0x1c/0x58
[ 2987.312185] [<ffff0000080ff880>] handle_irq_event+0x48/0x78
[ 2987.317748] [<ffff0000081030b8>] handle_edge_irq+0x128/0x190
[ 2987.323398] [<ffff0000080fe844>] generic_handle_irq+0x24/0x38
[ 2987.329136] [<ffff00000844dd64>] thunderx_gpio_chain_handler+0x24/0x38
[ 2987.335654] [<ffff0000080ff754>] __handle_irq_event_percpu+0x9c/0x128
[ 2987.342085] [<ffff0000080ff7fc>] handle_irq_event_percpu+0x1c/0x58
[ 2987.348255] [<ffff0000080ff880>] handle_irq_event+0x48/0x78
[ 2987.353819] [<ffff0000081031d8>] handle_fasteoi_irq+0xb8/0x1b0
[ 2987.359642] [<ffff0000080fe844>] generic_handle_irq+0x24/0x38
[ 2987.365378] [<ffff0000080feec4>] __handle_domain_irq+0x5c/0xb8
[ 2987.371202] [<ffff0000080815bc>] gic_handle_irq+0xbc/0x168
[ 2987.376677] Exception stack(0xffff000009033de0 to 0xffff000009033f10)
[ 2987.383108] 3de0: 0000000000000080 0000000000000000 0000000000000001 0000000000000000
[ 2987.390929] 3e00: 0100000000000000 ffff000009173100 0000000000000000 ffff8003fea4aa40
[ 2987.398749] 3e20: ffff00000905bc80 ffff000009030000 00000000000008a0 0000000000000000
[ 2987.406570] 3e40: 000000000000000f ffffffffffffffff 0000000000000000 0000ffff8c79ccc0
[ 2987.414390] 3e60: ffff0000081f1710 0000ffff8c6af290 0000000000000a03 ffff0000090526b8
[ 2987.422211] 3e80: ffff000009052608 0000000000000001 0000000000000000 0000000000000000
[ 2987.430031] 3ea0: ffff000009030000 ffff000009009880 ffff000009071b15 ffff000009052000
[ 2987.437852] 3ec0: ffff000009052000 ffff000009033f10 ffff00000808488c ffff000009033f10
[ 2987.445672] 3ee0: ffff000008084890 0000000000400149 ffff000009033f00 ffff00000810b6c8
[ 2987.453492] 3f00: ffffffffffffffff ffff0000080f4a78
[ 2987.458360] [<ffff000008082670>] el1_irq+0xb0/0x124
[ 2987.463229] [<ffff000008084890>] arch_cpu_idle+0x10/0x18
[ 2987.468532] [<ffff0000080f4a98>] cpu_startup_entry+0x118/0x1d8
[ 2987.474357] [<ffff000008ab0614>] rest_init+0x84/0x90
[ 2987.479313] [<ffff000008f20b4c>] start_kernel+0x384/0x398
[ 2987.484703] [<ffff000008f201d8>] __primary_switched+0x5c/0x64
[ 2987.490440] Code: aa0003f3 b4ffff40 97fffe36 17fffff8 (d4210000) 
[ 2987.496580] ---[ end trace 49c16f989e5d9a90 ]---
[ 2987.501198] Kernel panic - not syncing: Fatal exception in interrupt
[ 2987.507541] SMP: stopping secondary CPUs
[ 2987.511460] Kernel Offset: disabled
[ 2987.514937] Memory Limit: none
[ 2987.517984] ---[ end Kernel panic - not syncing: Fatal exception in interrupt

Linxu驱动程序代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

#define CPLD_INT 472 /* PIN of GPIO_40 */
#define DEV_NAME "cpld_irq"
#define irq_dev_id "cpid_irq_id"
#define IRQ_FILE  "/tmp/trigger_irq"

static int IRQ_NUM = 0;
static unsigned long flags = 0;
static int trigger_line = 0;
static char buf[] = "trigger_irq";

static int do_scan_cpld(void)
{
    struct file *fd;
    mm_segment_t fs;
    loff_t pos;

    fd = filp_open(IRQ_FILE , O_RDWR, 0644);

    if(IS_ERR(fd))
    {
        printk("Open %s failed!\n", IRQ_FILE);
        return -1;
    }

    fs = get_fs();
    set_fs(KERNEL_DS);
    pos = 0;
    vfs_write(fd, buf, sizeof(buf), &pos);
    filp_close(fd, NULL);
    set_fs(fs);

    return 0;
}

irqreturn_t cpld_irq_isr(int irq, void *dev_instance)
{
    local_irq_save(flags);
    do_scan_cpld();
    local_irq_restore(flags);

    return IRQ_NONE;
}

static int cpld_irq_init(void)
{
    int ret;

    printk("[%s] cpld_irq driver installed.\n", __func__);

    if(gpio_is_valid(CPLD_INT) < 0)
    {
        printk("[%s] gpio %d is invalid.\n", __func__, CPLD_INT);
        return -1;
    }

    if(gpio_request(CPLD_INT, "CPLD_INT") < 0)
    {
        printk("[%s] gpio_request failed for gpio %d\n", __func__, CPLD_INT);
        return -1;
    }

    IRQ_NUM = gpio_to_irq(CPLD_INT);

    if(IRQ_NUM < 0)
    {
        printk("[%s] Get the IRQ_NUM failed.\n", __func__);
        return -1;
    }

    ret = request_irq(IRQ_NUM, cpld_irq_isr, IRQF_TRIGGER_RISING, DEV_NAME, irq_dev_id);

    if(ret)
    {
        printk("[%s] request_irq() failed (%d)\n", __func__, ret);
    }

    return 0;
}

static void cpld_irq_exit(void)
{
    gpio_free(CPLD_INT);
    free_irq(IRQ_NUM, irq_dev_id);
    printk("[%s] cpld_irq driver unstalled.\n", __func__);
}

module_init(cpld_irq_init);
module_exit(cpld_irq_exit);
MODULE_LICENSE("Dual BSD/GPL");

如果在cpld_irq_init函数中写入文件。很好。

#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

#define IRQ_FILE  "/tmp/trigger_irq"

static char buf[] = "trigger_irq";

static int cpld_irq_init(void)
{
    struct file *fd;
    mm_segment_t fs;
    loff_t pos;

    fd = filp_open(IRQ_FILE , O_RDWR, 0644);

    if(IS_ERR(fd))
    {
        printk("Open %s failed!\n", IRQ_FILE);
        return -1;
    }

    fs = get_fs();
    set_fs(KERNEL_DS);
    pos = 0;
    vfs_write(fd, buf, sizeof(buf), &pos);
    filp_close(fd, NULL);
    set_fs(fs);

    return 0;
}

static void cpld_irq_exit(void)
{
    printk("[%s] cpld_irq driver unstalled.\n", __func__);
}

module_init(cpld_irq_init);
module_exit(cpld_irq_exit);
MODULE_LICENSE("Dual BSD/GPL");

0 个答案:

没有答案