Zynq-Linux移植学习7 pl-ps中断调试

1、中断申请问题

中断申请,zynq中对调用request_threaded_irq对中断进行申请。

err = request_threaded_irq(irq, NULL,
                irq_interrupt,
                IRQF_TRIGGER_RISING | IRQF_SHARED,
                devname, (void *)(irq_interrupt)); 
    if (err) {
        printk(KERN_ALERT "irq_probe irq    error=%d\n", err);
        goto fail;
    }

报错,genirq: Thread irq requseted with handler = NULL and !ONESHOT for irq 31.打印如下异常

f58f6e318f624661955ad1c9b203428e.png

查看 request_threaded_irq 源码,

int request_threaded_irq(unsigned int irq, irq_handler_t handler, irq_handler_t thread_fn,
                         unsigned long irqflags, const char *devname, void *dev_id)

网上查找资料:关于IRQF_ONESHOT, 当handler函数为NULL时,必须声明IRQF_ONESHOT, 表示threadirq线程中关闭该中断。在某些情况下,这个标志会非常有用。例如:设备是低电平产生中断,而硬中断函数为NULL,如果不使用IRQF_ONESHOT,就会一直产生中断执行NULL函数,中断线程得不到执行,声明IRQF_ONESHOT后,会执行完线程才使能该中断 。 

修改代码:

err = request_threaded_irq(irq, NULL,
                irq_interrupt,
                IRQF_TRIGGER_RISING | IRQF_ONESHOT,
                devname, (void *)(irq_interrupt)); 

    if (err) {
        printk(KERN_ALERT "irq_probe irq    error=%d\n", err);
        goto fail;
    }

打印如下,解决问题

94f039c5ae4a4c7d90506ec5f0ad9a5f.png

2、内核中断信号同步到应用方法

机制一:信号传递

内核代码,采用信号消息传递方式

static irqreturn_t irq_interrupt(int irq, void *dev_id)
{
    if (task != NULL) {
        if(send_sig_info(SIGSRIO0, &info, task) < 0) {
            printk(KERN_INFO "Unable to send signal\n");
        }
    }
    return IRQ_HANDLED;
}

send_sig_info 函数源码

int send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
{
    unsigned long flags;
    int ret;

    ret = -EINVAL;
    if (sig < 0 || sig > _NSIG)
        goto out_nolock;

    ret = -EPERM;
    if (bad_signal(sig, info, t))
        goto out_nolock;

    ret = 0;
    if (!sig || !t->sig)
        goto out_nolock;

    spin_lock_irqsave(&t->sigmask_lock, flags);
    handle_stop_signal(sig, t);

    if (ignored_signal(sig, t))
        goto out;

    if (sig < SIGRTMIN && sigismember(&t->pending.signal, sig))
        goto out;

    ret = deliver_signal(sig, info, t);
out:
    spin_unlock_irqrestore(&t->sigmask_lock, flags);
    if ((t->state & TASK_INTERRUPTIBLE) && signal_pending(t))
        wake_up_process(t);

out_nolock:
    return ret;
}

 

机制二 :异步传输

static irqreturn_t irq_interrupt(int irq, void *dev_id)
{
    if(irq_is_open)
    {
        kill_fasync (&irq_async, SIGIO, POLL_IN);
    }
    return IRQ_HANDLED;
}

 

3、内核中断命重复问题

不同中断使用同一个中断驱动,出现后注册的中断覆盖前边中断设备名。

dfae284f31d14ecb9bf0402e7ebff2b6.png

问题暂未解决,采用折中的办法,每个中断对应一个中断驱动。作为遗留问题,后续解决。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值