3353|2

71

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

关于linux外部中断,定时器,等对队列的问题 [复制链接]

我写了一个linux的中断驱动,驱动功能是利用DECLARE_WAIT_QUEUE_HEAD()申请了等对队列。在read()函数中用wait_event_interruptible()使程序等待外部中断的到来,中断处理函数的主要功能是用wake_up_interruptible()使程序继续运行下去。但是在测试程序中我使用了信号SIGALRM,以及setitimer()设置了一个定时器,目的是为了每隔一段时间利用定时器的中断处理函数向一个文件中写入一个固定变量的值。在我用实验板测试的时候发现每当到达设定时间后,处理完定时器中断处理函数,之后会自动使驱动使用的等待队列被唤醒,虽然这时候我没有引起外部中断。
还是把代码贴一下吧,可能我讲的不够详细。
/*中断驱动程序*/
/*read()函数*/
static ssize_t my_read(struct file *filp, char * buf, size_t count, loff_t *f_pos)
{
        static int value;
        wait_event_interruptible(key_wait, ready == 1);
        if(count != sizeof(key_value))
                return -EINVAL;
                 value = key_value;
        copy_to_user(buf, &value, sizeof(value));
        ready = 0;
        return sizeof(value);
}
/*中断处理函数*/
static DECLARE_WAIT_QUEUE_HEAD(key_wait);

static void key_irq_handle(int irq, void *dev_id, struct pt_regs *reg)
{
        struct key_info *key;
        key = key1;
        key_value = key->key_num;
        ready = 1;
        wake_up_interruptible(&key_wait);

}
/*这里的key_info是一个自己定义的结构体,用于返回一些信息*/
static struct key_info
{
        int                 irq_num;
        unsigned int         gpio_port;
        int                 key_num;
} key1[1] =
{
        { IRQ_EINT4, GPIO_F4, 1 },
};

/*测试程序*/
main()
{
         ……………………
         /*设定闹钟*/
         act.sa_handler =  savefile;
        sigemptyset(&act.sa_mask);
        act.sa_flags |= SA_RESTART;
        if (sigaction(SIGALRM, &act, &oact) < 0)
        {
                perror("sigaction\n");
                exit(1);
        }
        savetime.it_value.tv_sec = 5;
        savetime.it_value.tv_usec = 0;
        savetime.it_interval.tv_sec = 5;
        savetime.it_interval.tv_usec = 0;
        setitimer(ITIMER_REAL, &savetime, &ovalue);
          for(i = 0; i < 20; i++)
          {
                  /*我希望当我没有提供外部中断的时候,程序会停在这里,定时器返回后程序也会停在这里,但是结果是read()返回值是1,也就是说等待队列被唤醒,驱动中read()函数继续运行了,在这里跳入了else中,输出了一些信息,但是这些信息是我希望在提供外部中断信号之后才显示的*/
                     result = read(fd2, &key_value, sizeof(key_value)) == sizeof(key_value);
                usleep(700000); //按键防抖
                if (!result)
                {
                        if (errno == EINVAL)
                        {
                                printf("Wrong size!\n");
                                break;
                        }
                }
                else
                {
                        /*打印一些信息*/
                }   
               
    }
         
}
/*定时器中断处理函数*/
int  savefile()
{
        struct rainfall raindata1 = {2009, 7, 11, 2, 12,23,0};/*自己定义的结构体,在存储时使用,主要内容是当前时间,和一个变量值*/
        get_sys_time(&raindata1);/*因为要存储当前系统时间,所以使用了该函数*/
        file_write("/tmp/sd/rainfall.dat", raindata1);/*自己编写的简单的文件存储程序*/
        return 1;
}

遇见这个问题之后,查了很多东西,我有几种想法,但是好像用来解决问题都没有用,说出来希望大家帮我分析分析是否正确。
第一,看了《Unix环境高级编程》里面的第10章,里面有提到信号会中断系统调用,是不是和这个问题有关系。由于被信号中断而重新启动了该系统调用,如果是这样的话,但是为什么程序会继续运行下去。
第二,看了《linux kernel development》相关内容,对于等待队列和工作队列不太明白,不知道两个是不是同一个概念。如果是一个概念,书中说内核态有一个默认的工作队列,而且我没有新建另外一个,那么驱动中read()和定时器中断处理函数是不是都挂在了同一个等待队列上,在定时器到时后激活等待队列,等待队列处理完队列上所有工作后才返回,所以才造成这个现象。

我是第一次发帖,我也是刚开始接触嵌入式和linux的新手,问题和想法还比较低级,不过希望有人可以帮我解答,或者想想办法,谢谢!

最新回复

哎……其实也不是很长,说起来就是有几个地方是关键部分,看来失误了   详情 回复 发表于 2009-8-27 09:28
点赞 关注

回复
举报

65

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
代码太长了先MARK吧。
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
哎……其实也不是很长,说起来就是有几个地方是关键部分,看来失误了
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表