免费注册 查看新帖 |

Chinaunix

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

请教下驱动问题,什么情况下会导致Ctrl+C终止不了应用程序 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-10 10:39 |只看该作者 |倒序浏览
5可用积分
在学写Linux驱动
对ARM9系列的S3C2440A写了个最简单的linux定时器驱动,设定每秒中断一次并打印出信息
然后写个测试程序,运行情况正常
但是按Ctrl+C就是没办法终止程序运行,不知是不是驱动有冲突?没查明是何原因

代码我贴出来,希望大家帮我看看
--------------------------------------------------------------------------------------
测试程序的代码:

int main(void) //测试程序就是一个死循环,等待定时器一秒中断打印出信息
{
        int fd;
        fd=open("/dev/timer",0);
        if(fd<0){
                printf("Open /dev/timer failed!\n");
                exit(1);
        }
        else printf("Open device successfully!\n");
        while(1);
        close(fd);
        return 0;
}


------------------------------------------------------------------------------------------------------------------------
驱动程序的代码:

#include "arm-linux.h"  //一些需要的头文件

#define timer_irq IRQ_TIMER0  //定时器0的中断号
#define DEVICE_NAME "timer"

static int major;  //存放主设备号
static int interrupt_flag=0;  //中断发生标记

#define DEVICE_MAJOR major
#define DEVICE_MINOR 0

void timer_do_tasklet(void)
{
        interrupt_flag=0; //中断标记清零,表示已处理中断事件
        printk("Doing tasklet_schedule!\n\n");
}
DECLARE_TASKLET(timer_tasklet,timer_do_tasklet,0); //静态创建一个tasklet

static irqreturn_t timer_interrupt(void)
{
        interrupt_flag++;
        printk("Timer0 interrupt occured!\n");
        tasklet_schedule(&timer_tasklet);  //开始调度tasklet的函数
        return IRQ_HANDLED;
}

static int timer_open(struct inode *inode,struct file *filp)
{
        int ret;
        unsigned long Ftclk,Fpclk=50000000; //s3c2440a的默认Fpclk为50MHz
        outl(255,S3C2410_TCFG0); //设置预分频
        outl(3,S3C2410_TCFG1);   //设置分频和模式
        Ftclk=Fpclk/(255+1)/16;  //参考datasheet公式
        outl(Ftclk,S3C2410_TCNTB(0));  //写入定时初值
        outl(0,S3C2410_TCMPB(0));  //写入终点比较值
        outl(S3C2410_TCON_T0MANUALUPD,S3C2410_TCON); //手动刷新一次,将数据装入TCNT和TCMP
        outl(S3C2410_TCON_T0START|S3C2410_TCON_T0RELOAD,S3C2410_TCON);   //设置自动装载初值,开始计数

        ret=request_irq(timer_irq,&timer_interrupt,SA_INTERRUPT,DEVICE_NAME,NULL);
        if(ret<0){
                printk("Register IRQ_TIMER0 failed!\n");
                return ret;
        }
}

static int timer_close(struct inode *inode,struct file *filp)
{
        free_irq(timer_irq,NULL);
        return 0;
}

static struct file_operations timer_fops={
        .owner=THIS_MODULE,
        .open=timer_open,
        .release=timer_close,
};

int timer_init(void)
{
        major=register_chrdev(0,DEVICE_NAME,&timer_fops);
        if(major<0){
                printk("Device register failed!\n");
                return major;
        }
        devfs_mk_cdev(MKDEV(DEVICE_MAJOR,DEVICE_MINOR),S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP,DEVICE_NAME);
        printk("Device register successfully!\n");
        return 0;
}

void timer_exit(void)
{
        unregister_chrdev(DEVICE_MAJOR,DEVICE_NAME);
        devfs_remove(DEVICE_NAME);
        printk("Device unregistered!\n");
}

MODULE_LICENSE("GPL");
MODULE_AUTHOR("HJW");
module_init(timer_init);
module_exit(timer_exit);

最佳答案

查看完整内容

ctrl+c终止了应用程序,从while(1);退出,没有执行close(fd);驱动还在运行应用应改成接受到ctrl+c信号,执行close(fd);[ 本帖最后由 mingloie 于 2009-9-11 11:26 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-09-10 10:39 |只看该作者

回复 #1 hjw951 的帖子

ctrl+c终止了应用程序,从while(1);退出,没有执行close(fd);驱动还在运行
应用应改成接受到ctrl+c信号,执行close(fd);

[ 本帖最后由 mingloie 于 2009-9-11 11:26 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2009-09-11 08:57 |只看该作者
先不用驱动,就在应用层编个死循环作一下测试,看看control+C好不好用,如果没问题,再查驱动

论坛徽章:
0
4 [报告]
发表于 2009-09-11 22:47 |只看该作者

回复 #3 mingloie 的帖子

首先不加驱动的死循环程序我试过了,是可以ctrl+c来终止的,然后按照你的说法
我加了一个捕捉信号的函数
13 void sig_handle(int fd)
14 {
15         printf("Now catch a signal! exit!\n");
16         close(fd);
17         exit(0);
18 }

但是ctrl+c依然没有反应,好像根本没有signal发生那样

[ 本帖最后由 hjw951 于 2009-9-11 23:53 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2009-09-12 10:54 |只看该作者
linux 开机自动执行的脚本中有执行不成功的话,也回到室ctrl c 不工作,你先确认一下在不跑任何程序的情况下,ctrl c 工作是否正常。。。
就是这个样子。。。

论坛徽章:
0
6 [报告]
发表于 2009-09-15 22:31 |只看该作者
怎么解觉得?说一下啊。

论坛徽章:
0
7 [报告]
发表于 2009-09-15 23:59 |只看该作者

回复 #6 llzzccc 的帖子

最后就是不了了之~
问了不少人了,就是不知道个所以然
也尝试过捕捉信号的方法,但一加上驱动就不奏效~驱动代码又没看出是什么问题

论坛徽章:
0
8 [报告]
发表于 2009-09-16 15:55 |只看该作者
原帖由 hjw951 于 2009-9-11 22:47 发表
首先不加驱动的死循环程序我试过了,是可以ctrl+c来终止的,然后按照你的说法
我加了一个捕捉信号的函数
13 void sig_handle(int fd)
14 {
15         printf("Now catch a signal! exit!\n");
16    ...

以为你解决了呢,你的signal函数怎么写的?放在哪里的?

论坛徽章:
0
9 [报告]
发表于 2009-09-16 21:28 |只看该作者

回复 #8 mingloie 的帖子

void sig_handle(void)
{
printf("Catch a signal!\n");
exit(0);
}

int main(void)
{
        int fd;
        signal(SIGINT,sig_handle);
        fd=open("/dev/timer",0);
        if(fd<0){
                printf("Open /dev/timer failed!\n");
                exit(1);
        }
        else printf("Open device successfully!\n");
        while(1);
        close(fd);
        return 0;
}

我就这么写了,在不加驱动的时候是可以捕捉到并退出程序的

论坛徽章:
0
10 [报告]
发表于 2009-09-25 09:35 |只看该作者
SA_INTERRUPT把这个换成SA_SHIRQ  实验一下。
因为SA_INTERRUPT是禁止其他任何中断的。CTRL+C发送信号已经被禁止了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP