免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3172 | 回复: 8
打印 上一主题 下一主题

异步通知引起的问题! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-01-02 19:34 |只看该作者 |倒序浏览
5可用积分
大家好,我做了一个挺简单实现异步通知的驱动函数。
已经可以实现异步通信了,可是好像只有用户空间进行完一次IO之后才能发出一个异步信号。
我是想在ioctl函数中,每隔2秒发出一个异步通知。可是没有实现,只有最后一次实现了。
大家帮忙看看怎么回事呢???
用户空间主函数:
void write_to_file_test(int signum)
{
        printf("get data!\n");
}
int main()
{
                fd = open("/dev/kpp",O_RDWR);
                if(fd==-1)
                {printf("open device %serror\n","TEST");
                }
                else{
                printf("fd=%d\n",fd);
                signal(SIGIO,write_to_file_test);
                fcntl(fd,F_SETOWN,getpid());
                oflags = fcntl(fd,F_GETFL);
                fcntl(fd,F_SETFL,oflags|FASYNC);
                char *inin = "hello";
                sleep(3);
                ioctl(fd,1);
                printf("ioctl after!\n");
                }
                while(1);
}

驱动中各主要实现函数:
主要结构体:
struct globalfifo_dev{
        struct cdev cdev;                        /*cdev结构体*/
        struct fasync_struct *async_queue;/*异步结构体指针,用于读 */
};

struct globalfifo_dev *uspi_devp_1;
1、static int uspi_open(struct inode *inode, struct file *filp)
{
        filp->private_data =  uspi_devp_1;
        return 0;
}
2、static int uspi_release(struct inode *inode, struct file *filp)
{
    uspi_fasync(-1,filp,0);
        return 0;
}

3、static int uspi_fasync(int fd,struct file *filp,int mode)
{
            struct globalfifo_dev *dev = filp->private_data;               
            return fasync_helper(fd, filp, mode, &dev->async_queue);
}
4、static void register_uspi(void)
{
    devno = MKDEV(KPPMAJOR, 0);
    register_chrdev_region(devno, 1, MODULE_NAME);
     uspi_devp_1 = kmalloc(sizeof (struct globalfifo_dev), GFP_KERNEL);
    memset( uspi_devp_1, 0, sizeof (struct globalfifo_dev));
        devno_1= MKDEV(KPPMAJOR, 0);
    cdev_init(& uspi_devp_1->cdev, &uspi_ops);
     uspi_devp_1->cdev.owner = THIS_MODULE;
     uspi_devp_1->cdev.ops = &uspi_ops;
    cdev_add(& uspi_devp_1->cdev, devno_1, 1);
}
5、static int uspi_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,unsigned long arg)
{
        uspi_devp_1 = filp->private_data;
        if(uspi_devp_1->async_queue)
                kill_fasync(&uspi_devp_1->async_queue,SIGIO,POLL_IN);
        printk("haoaoha\n");
        mdelay(2000);
        if(uspi_devp_1->async_queue)
                kill_fasync(&uspi_devp_1->async_queue,SIGIO,POLL_IN);
        printk("haoaoha1111111111\n");
        mdelay(2000);
        if(uspi_devp_1->async_queue)
                        kill_fasync(&uspi_devp_1->async_queue,SIGIO,POLL_OUT);
        printk("haoaoha2222222222222\n");
        mdelay(2000);

        if(uspi_devp_1->async_queue)
                        kill_fasync(&uspi_devp_1->async_queue,SIGIO,POLL_IN);
        printk("haoaoha333333333333\n");
        return 0;
       
}
程序编译没有问题,可是就是不能及时的发出异步通知信号!不知道为什么?

论坛徽章:
5
2 [报告]
发表于 2009-01-02 21:37 |只看该作者
输出结果是什么?

主函数中怎么有while(1);???
换成:
while(1)
{
    sleep(xxx);
}

如何?

论坛徽章:
0
3 [报告]
发表于 2009-01-03 13:51 |只看该作者
用了,sleep也不行呢?
怎么回事呢?

论坛徽章:
0
4 [报告]
发表于 2009-01-08 22:48 |只看该作者
将全部源代码copy上来,我来调式看看.

论坛徽章:
0
5 [报告]
发表于 2009-01-08 22:51 |只看该作者
void write_to_file_test(int signum)
{
        static int i=0;
        printf("get data! i=%i\n",i++);
}
以便于区别开每次的SIGIO

论坛徽章:
0
6 [报告]
发表于 2009-01-08 23:08 |只看该作者
fasync_helper函数将该设备文件相对应的file加入到struct fasync_struct的
(struct file* )fa_file指针队列中,kill_fasync则将其从队列中去掉,如果fasync_helper一次,那么kill_fasync也只能一次,也就是说会引发一次SIGIO,多次kill_fasync,也只是有一次SIGIO.

所以,我想你的程序如果这样写:
5、static int uspi_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,unsigned long arg)
{
static int j=0;
        uspi_devp_1 = filp->private_data;
        if(uspi_devp_1->async_queue)
                {kill_fasync(&uspi_devp_1->async_queue,SIGIO,POLL_IN);printk(KERN_ALERT "kernel:j=%i\n",++j);}
        printk("haoaoha\n");
        mdelay(2000);
        if(uspi_devp_1->async_queue)
           {kill_fasync(&uspi_devp_1->async_queue,SIGIO,POLL_IN);printk(KERN_ALERT "kernel:j=%i\n",++j);}
        printk("haoaoha1111111111\n");
        mdelay(2000);
        if(uspi_devp_1->async_queue)
                        {kill_fasync(&uspi_devp_1->async_queue,SIGIO,POLL_IN);printk(KERN_ALERT "kernel:j=%i\n",++j);}
        printk("haoaoha2222222222222\n");
        mdelay(2000);

        if(uspi_devp_1->async_queue)
                        {kill_fasync(&uspi_devp_1->async_queue,SIGIO,POLL_IN);printk(KERN_ALERT "kernel:j=%i\n",++j);}
        printk("haoaoha333333333333\n");
        return 0;
      
}
你就会明白是不是只是执行了第一次kill_fasync????????//

我也是刚学,以上是我的分析,不知道正不正确?

[ 本帖最后由 whoisliang 于 2009-1-8 23:11 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2009-01-08 23:25 |只看该作者
另一种改法:
在我加的三个kill_fasync,printk语句序列中前两个再加一句setfl(...),最后一个kill_fasync序列中不加就可以成功了.

注:
setfl是EXPORT_SYMBOL函数,具体参数我忘记了.

论坛徽章:
0
8 [报告]
发表于 2009-01-12 17:23 |只看该作者
LZ不见了,DX们也不回复,BZ也不来回答了,我也不知道我的回答对不对

论坛徽章:
0
9 [报告]
发表于 2009-01-12 20:55 |只看该作者
原帖由 whoisliang 于 2009-1-8 23:25 发表
另一种改法:
在我加的三个kill_fasync,printk语句序列中前两个再加一句setfl(...),最后一个kill_fasync序列中不加就可以成功了.

注:
setfl是EXPORT_SYMBOL函数,具体参数我忘记了.





好像不是这样的吧,我在一个定时器中调用kill_fasyns() ,都可以一直触发异步信号。。。

struct globalfifo_dev *uspi_devp_1;
1、static int uspi_open(struct inode *inode, struct file *filp)
{
        filp->private_data =  uspi_devp_1;
        return 0;
}

我觉得你这里的参数好像有问题, 你这边 uspi_devp_1 都是一个空指针, 你 ioctl 哪里来的值 运行?? 这是随机数值吧,你设个具体值看看

[ 本帖最后由 star316 于 2009-1-12 21:02 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP