linux异步信号驱动

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/list.h>
#include <linux/moduleparam.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/uio.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <asm/unaligned.h>
#include <linux/fs.h>
#include <linux/compat.h>
#include <linux/blkdev.h>
#include <linux/mutex.h>
#include <linux/poll.h>
#include <linux/vmalloc.h>
#define MEM_CLEAR           0x1
#define GLOBALFIFO_MAJOR    230
#define GLOBALFIFO_SIZE     0x1000

static struct fasync_struct *megasas_async_queue;
static int globalfifo_major = GLOBALFIFO_MAJOR;
module_param(globalfifo_major, int, S_IRUGO);

/* 设备结构体 */
struct  globalfifo_dev {
    struct cdev cdev;
    unsigned int current_len;  /* 当前FIFO中有效数据的长度 */
    unsigned char mem[GLOBALFIFO_SIZE];
};
 
struct globalfifo_dev *globalfifo_devp;

struct timertest {
    struct timer_list mytimer;
    int count;
    int delay;
}ttest;

/*在指定回调函数时,并没有给回调函数的实参,
这里的t应该是系统在调用的会传入对应的timer_list,
比如这里是ttest.mytimer*/
void
timer_callback(struct timer_list *t)
{
    printk("timer_callback\n");
    struct timertest *p = container_of(t, struct timertest, mytimer);
    if(--(p->count)) {
        /*如果没有这个,那么回调函数只会进入一次,
        在调用的时候可以改变回调函数的执行时间*/
        mod_timer(t, jiffies+p->delay);
    }
    else {
        printk("timer_callback del\n");
        /*也可以在模块退出时删除*/
        del_timer(t);
    }
	//往应用程序发送信号
	kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
    return;
}

static int globalfifo_open(struct inode *inode, struct file *filp)
{
    return 0;
}
 
static int globalfifo_release(struct inode *inode, struct file *filp)
{
	//fasync_helper(-1, filp, mode, &megasas_async_queue, mode); 
    return 0;
}

static int globalfifo_fasync(int fd, struct file *filep, int mode)
{
	printk(KERN_DEBUG "megasas: fasync_helper\n");
	return fasync_helper(fd, filep, mode, &megasas_async_queue);
}

static const struct file_operations globalfifo_fops = {
    .owner = THIS_MODULE,
    .open = globalfifo_open,
    .release = globalfifo_release,
	.fasync = globalfifo_fasync,
};
 
static void globalfifo_setup_cdev(struct globalfifo_dev *dev, int index)
{
    int err, devno = MKDEV(globalfifo_major, index);
 
    cdev_init(&dev->cdev, &globalfifo_fops);
    dev->cdev.owner = THIS_MODULE;
    err = cdev_add(&dev->cdev, devno, 1);
    if (err)
        printk(KERN_NOTICE "Error %d adding fifo%d", err, index);
}
 
static int __init globalfifo_init(void)
{
    int ret;
    dev_t devno = MKDEV(globalfifo_major, 0);
 
    if (globalfifo_major)
        ret = register_chrdev_region(devno, 1, "fifo");
    else {
        ret = alloc_chrdev_region(&devno, 0, 1, "fifo");
        globalfifo_major = MAJOR(devno);
    }
     
    if (ret < 0)
        return ret;
     
    globalfifo_devp = kzalloc(sizeof(struct globalfifo_dev), GFP_KERNEL);
    if (!globalfifo_devp) {
        ret = -ENOMEM;
        goto fail_malloc;
    }
    globalfifo_setup_cdev(globalfifo_devp, 0);
 
	//定时器
	ttest.count = 100;
    ttest.delay = 100;
    timer_setup(&ttest.mytimer, &timer_callback, 0);
    mod_timer(&ttest.mytimer, jiffies+ttest.delay);

    return 0;
fail_malloc:
    unregister_chrdev_region(devno, 1);
    return ret;
}

static void __exit globalfifo_exit(void)
{
    cdev_del(&globalfifo_devp->cdev);
    kfree(globalfifo_devp);
    unregister_chrdev_region(MKDEV(globalfifo_major, 0), 1);
}

module_init(globalfifo_init);
module_exit(globalfifo_exit);
 
MODULE_AUTHOR("xujia");
MODULE_LICENSE("GPL v2");

//mknod 创建设备节点

//https://www.cnblogs.com/mrlayfolk/p/15858989.html

应用程序

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>

#define MAX_LEN  100

static void signalio_handler(int signum)
{
    printf("receive a signal, signal number:%d\n", signum);
}

int main()
{
    int fd, oflags;

    /* 以非阻塞方式打开设备文件 */
    fd = open("/dev/fifo", O_RDONLY | S_IRUSR | S_IWUSR);
    if (fd != -1) {
        /* 启动信号驱动机制 */
        signal(SIGIO, signalio_handler); //SIGIO信号安装input_handler()作为处理函数
        fcntl(fd, F_SETOWN, getpid());  //设置本进程为STDIN_FIFENO文件的拥有者,进程可以接收异步信号
        oflags = fcntl(fd, F_GETFL);  
        fcntl(fd, F_SETFL, oflags | FASYNC);  //设置FASYNC
        while (1) {
            sleep(100);
        }
    } else {
        printf("device open failure\n");
    }
    
    return 0;
}

都是固定套路了。
参考:https://www.cnblogs.com/mrlayfolk/p/15858989.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值