免费注册 查看新帖 |

Chinaunix

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

关于驱动的I/O中断响应一些的问题请教,跪求高手解答 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-03-28 13:46 |只看该作者 |倒序浏览
我大概描述一下我的 sensor_drive_char.c 文件的主要内容。我的实验平台是S3C2440ARM板。我的目的是希望对GPG13 和 GPG14 两个I/O口,连接一个传感器两个信号线,均发送的是脉冲信号,即1ms脉宽的方波一次,至于硬件电器件性能暂不考虑的情况下,能够使得驱动每来一个脉冲,无论GPG13还是GPG14,就用全局变量计数加一。暂时是想 通过中断方式。关于用这两个引脚,还有待考虑,请问是否有更好的建议。然后两个引脚连接中断     
s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_EINT21);
s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_EINT22);
这么写对么,我是看2440中文手册是这样的
GPG14 [29:28]  00:input 01:output 10:ENIT[22] 11:Reserved
GPG13 [27:26]  00:input 01:output 10:ENIT[21] 11:Reserved
但是结果就编译器报错,



本人所了解到这个错误是因为移植内核代码时,S3C2410_GPG13_EINT21这些没有配置的原因。
但是我主要还是不清楚,到底要改哪些文件,来配置这个中断!!望请不吝赐教

最后附源代码如下,希望高手能多多指正,感激不尽!!谢谢

#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/spinlock.h>
#include <linux/irq.h>
#include <linux/poll.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <mach/regs-gpio.h>
#include <asm/io.h>
#include <linux/cdev.h>
#include <linux/ioctl.h>
#include <linux/device.h>
#include <linux/gpio.h>

MODULE_AUTHOR("kelun";
MODULE_LICENSE("Dual BSD/GPL";

static int g_irq = 0;

struct tasklet_struct sensor_taslet;

//定义模块结构体
static struct cdev sensor_cdev;

//定义一个设备class
static struct class *sensor_class=NULL;

static struct device *sensor_device = NULL;

//设备号
static dev_t devno;

//主设备号
static uint devno_major = 0;

//次设备号
static uint devno_minor = 0;


static long int mycount_gpg13 = 0;
static long int mycount_gpg14 = 0;

module_param (mycount_gpg13,long, 0660);
MODULE_PARM_DESC (mycount_gpg13, "A long integer";

module_param (mycount_gpg14,long, 0660);
MODULE_PARM_DESC (mycount_gpg14, "A long integer";

void sensor_tasklet_fn(unsigned long arg)
{
        /*  deferrable part. 中断的下半部*/
        mycount_gpg13++;
        mycount_gpg14++;
        printk("GPG13=%ld   GPG14=%ld \n",mycount_gpg13,mycount_gpg14);
}

static irqreturn_t sensor_handler(int irq, void *dev_id)
{
//        printk("Debug ++ %s ++ irq = %d\n", __func__, irq);

        /*....   do something urgent , 中断的上半部*/
        //execute urgent part ....

        sensor_taslet.data=irq;
        tasklet_schedule(&sensor_taslet);

        return IRQ_HANDLED;
}

void sensor_gpio_init(void)
{
       
/*设置GPG 13,14为中断引脚 ,寄存器与中断引脚的联结*/
            s3c2410_gpio_cfgpin(S3C2410_GPG(13), (0x02 << 26)); //错误主要就在这里
        s3c2410_gpio_cfgpin(S3C2410_GPG(14), (0x02 << 2); //写成S3C2410_GPG13_EINT21 和22也错


/*中断类型的设置,为高电平触发*/
        set_irq_type(S3C2410_GPG13_EINT21, IRQ_TYPE_LEVEL_HIGH);
        set_irq_type(S3C2410_GPG13_EINT22, IRQ_TYPE_LEVEL_HIGH);

       
}

static int sensor_open (struct inode *inode, struct file *file)
{
        return 0;
}


static int sensor_release (struct inode *inode, struct file *filp)
{      
    return 0;
}

//接口函数填充
struct file_operations sensor_fops = {
  .owner = THIS_MODULE,
  .open  = sensor_open,
  .release = sensor_release,
};


static int sensor_init(void)
{
        int result;
        int ret;


        sensor_gpio_init();       
        result = request_irq (IRQ_EINT21, sensor_handler,IRQF_SAMPLE_RANDOM, "sensor", NULL);       
        if (result) {
                printk(KERN_INFO "button: can't get assigned irq\n";
        }

        result = request_irq (IRQ_EINT22, sensor_handler,IRQF_SAMPLE_RANDOM, "sensor", NULL);       
        if (result) {
                printk(KERN_INFO "button: can't get assigned irq\n";
        }


        tasklet_init(&sensor_taslet, sensor_tasklet_fn, (unsigned long)g_irq);

        //动态申请设备号
        ret = alloc_chrdev_region(&devno, 0, 1, "char_key";//成功返回0,不成功返回-1
        if (ret < 0) //判断是否成功
        {
                printk(KERN_INFO "can't register char device driver\n";
                return -1;
        }

        //提取主设备号
        devno_major = MAJOR(devno);
        //提取次设备号
        devno_minor = MINOR(devno);
       
        //初始化cdev->ops=file_operatins
        cdev_init(&sensor_cdev, &sensor_fops);
       
        //设置当前模块指针填充
        sensor_cdev.owner = THIS_MODULE;
       
        //加载模块到内核
        ret = cdev_add(&sensor_cdev, devno, 1);//成功返回0,失败返回-1
        if(ret<0)//判断是否成功
        {
                printk(KERN_INFO "can't register char device\n";
                return -1;
        }

        //创建设备节点,使用udev
        //调用class_create创建一个设备类
        sensor_class=class_create(THIS_MODULE, "key_class";

        //
        if (IS_ERR(sensor_class))
        {
                printk(KERN_ERR "failed to create device class \n");
                cdev_del(&sensor_cdev);//从系统中移除一个字符设备
                unregister_chrdev_region(devno , 1);//释放设备号,first为第一个设备号,count为申请的设备数量
                return -1;
        }
        //创建设备节点
        sensor_device = device_create(sensor_class,NULL,devno,NULL,"key_dev");
       
        return 0;

}


static void sensor_cleanup(void)
{
        printk("simple device uninstalled\n");

        free_irq(IRQ_EINT21,NULL);
        free_irq(IRQ_EINT22,NULL);


         cdev_del(&sensor_cdev);//卸载字符设备
        unregister_chrdev_region(devno , 1);//释放设备号
       
        /*
        函数device_destroy()用于从linux内核系统设备驱动程序模型中移除一个设备,
        并删除/sys/devices/virtual目录下对应的设备目录及/dev/目录下对应的设备文件
        */
        device_destroy(sensor_class, devno);

        class_destroy(sensor_class);//销毁类
}

module_init(sensor_init);
module_exit(sensor_cleanup);

论坛徽章:
0
2 [报告]
发表于 2012-03-28 16:12 |只看该作者
关于报错的问题我解决了,sensor_gpio_init(void)函数里
修改宏的两个地方就能编过了,但是 希望高手能帮忙指点下
这样做的驱动是否可行,能否达到记录脉冲的功效?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP