1

我一直在为真正奇怪的问题而烦恼。内核模块无法在没有 printk 的情况下向用户应用程序发送信号(或用户应用程序无法接收),必须在发送信号之后或之前执行虚拟 printk。

实际上,即使是空的 printk,它也能很好地工作。但是,我试图了解发生了什么。

有什么想法吗?

这是发生了什么:

A - 内核)字符设备类型模块获得中断。

它提取数据并向用户发送信号。

/* 必须在这里做 printk */

返回 IRQ 句柄。

B-用户)

接收信号。

发出系统调用并从 char 设备的缓冲区中读取数据。(copy_to_user)

核心:

void irq_handler(){
    int i;
    for(i =0; i < 32; i++) 
        GPIOdata[i] = read_gpio_status(i);

    struct task_struct *p = find_task_by_pid(processinfo.pid);
    if (NULL == p) 
        return;
    send_sig(SIGUSR1, p, 0);
    /* have to add printk here */
    return IRQ_HANDLED
}

用户:

void signal_handler(int sig) {
    char data[32];
    ioctl(fd, READ_Data_from_Char_device, &data);
}
4

1 回答 1

0

如果您不使用signal设置sigaction处理程序,请记住,signal在收到信号后删除处理程序。你应该屏蔽信号,这样在信号处理程序中运行时它不会中断你的进程。我也不确定ioctl处理程序内部的系统调用(查看异步信号安全功能部分下的man7 信号)。

调用printk可能会减慢这些调用周围其他操作的执行速度(因为它们在 I/O 或缓冲上被阻塞),因此它们可以使同步变慢(因此可能不会发生任何同步错误)。

于 2013-08-06T13:09:13.223 回答