Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1254011
  • 博文数量: 479
  • 博客积分: 12240
  • 博客等级: 上将
  • 技术积分: 4999
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-24 17:12
文章分类

全部博文(479)

文章存档

2014年(1)

2013年(1)

2012年(1)

2011年(95)

2010年(177)

2009年(167)

2008年(16)

2007年(21)

分类: LINUX

2010-10-29 09:34:31


如果希望某个硬件动作发生后,用户能在用户态编写中断处理程序,可以使用内核信号,下面是使用范例。


驱动(中断处理)

static irqreturn_t key_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
    printk(DEV_NAME" Interrupted!\n");
    send_sig(SIGUSR1, current, NULL); //send SIGUSR 1

    return IRQ_HANDLED;
}


current是内核是一个全局变量,指向当前在运行的进程。但是内核运行时搜索到特定进程的进程号是个费事的工作,可能要遍历整个进程控制块链表,会很费时间。这也是不推荐在用户态编写中断程序的原因。


驱动程序其它都没有不同,仅仅是在中断中发射信号而已。

用户程序:

/*
 * Catch SIGUSR1 sent from kernel mode Interrupt routine.
 * 捕捉内核态中断服务程序发送的SIGUSR1信号。
 * 用户可以在用户态编写自己的中断处理程序。
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <signal.h>

//#define MODE1
//#define MODE2
void signal_handler(int signo)
{
    printf("####in %s\n", __func__);
}


int main(int argc, char **argv)
{
#if defined (MODE1)
    signal(SIGUSR1, (void *)signal_handler); //这样可以


#else //这样也可以,第一种方式更加简单一些
    struct sigaction action;
    action.sa_handler = signal_handler;
    action.sa_flags = 0;
    sigaction(SIGUSR1, &action, NULL);
#endif

    while(1);
    return 0;
}

阅读(2880) | 评论(3) | 转发(2) |
给主人留下些什么吧!~~

chenxibing0082011-01-14 13:22:44

除非不得已,是不推荐在用户态写驱动程序的。

athurg2011-01-14 12:25:28

这个范例有BUG。在压力测试下,可能会导致内核崩溃。
原因是中断上下文中,current指针结构可能不完整或者压根就没有。

chinaunix网友2010-10-29 15:02:43

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com