Chinaunix首页 | 论坛 | 博客
  • 博客访问: 277832
  • 博文数量: 58
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 600
  • 用 户 组: 普通用户
  • 注册时间: 2015-11-27 08:37
个人简介

从linux了解世界

文章分类
文章存档

2017年(5)

2016年(51)

2015年(2)

我的朋友

分类: 嵌入式

2016-01-14 09:46:57

和字符驱动程序一样,先学习驱动框架,再研究构成框架的这些注册函数在内核是怎么工作的。
mini2440的6个按键连接在gpg0,3,5,6,7,11上,中断号是8,11,13,14,15,19共用一个中断eint8-23,在irqs.h中有所有中断号的宏定义。在interrupt.h中有中断触发方式的宏定义。
int devid=1;
static struct class *seconddrv_class;
static struct device    *seconddrv_class_dev;
volatile unsigned long *gpgcon;
volatile unsigned long *gpgdat;//mini2440的6个按键连接在gpg0,3,5,6,7,11上

static irqreturn_t botton_handle(int irq, void *dev_id)//irq为linux提供的中断号,dev_id可以看做该中断下不同中断函数的id,irqreturn_t的宏定义在
{                                                                            //irqreturn.h中,是一个枚举
    printk("irq=%d\n",irq);
    return IRQ_HANDLED;
}//注册的中断响应函数


static int second_drv_close(struct inode *inode, struct file *file)
{
    free_irq(IRQ_EINT8,&devid);
    free_irq(IRQ_EINT11,&devid);
    free_irq(IRQ_EINT13,&devid);
    free_irq(IRQ_EINT14,&devid);
    free_irq(IRQ_EINT15,&devid);
    free_irq(IRQ_EINT19,&devid);
    return 0;
}//解除注册


static int second_drv_open(struct inode *inode, struct file *file)
{
    *gpgcon &= ~((3<<0)|(3<<6)|(3<<10)|(3<<12)|(3<<14)|(3<<22));
    *gpgcon |= (2<<0)|(2<<6)|(2<<10)|(2<<12)|(2<<14)|(2<<22);//中断配置  
    request_irq(IRQ_EINT8,botton_handle,IRQF_TRIGGER_RISING,"bottontest1",&devid);
    request_irq(IRQ_EINT11,botton_handle,IRQF_TRIGGER_RISING,"bottontest2",&devid);
    request_irq(IRQ_EINT13,botton_handle,IRQF_TRIGGER_RISING,"bottontest3",&devid);
    request_irq(IRQ_EINT14,botton_handle,IRQF_TRIGGER_RISING,"bottontest4",&devid);
    request_irq(IRQ_EINT15,botton_handle,IRQF_TRIGGER_RISING,"bottontest5",&devid);
    request_irq(IRQ_EINT19,botton_handle,IRQF_TRIGGER_RISING,"bottontest6",&devid);
    return 0;
}//注册六个按键的中断函数并自动完成打开中断需要的所有工作

static struct file_operations sencod_drv_fops = {
    .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
    .open   =   second_drv_open,    
    .release =     second_drv_close,
};

int major;
static int second_drv_init(void)
{
    major = register_chrdev(0, "botton_drv", &sencod_drv_fops);
    seconddrv_class = class_create(THIS_MODULE, "second_drv");
    seconddrv_class_dev = device_create(seconddrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */
    gpgcon = (volatile unsigned long *)ioremap(0x56000060, 16);
    gpgdat = gpgcon + 1;
    return 0;
}

static void second_drv_exit(void)
{
    unregister_chrdev(major, "second_drv");
    device_destroy(seconddrv_class,MKDEV(major, 0));
    class_destroy(seconddrv_class);
    iounmap(gpgcon);
}

module_init(second_drv_init);
module_exit(second_drv_exit);
MODULE_LICENSE("GPL");
最后在板子上测试发现6个按键有5个已经被内核注册为键盘了,需要在内核配置中取消device/drive/input device support/keyboard再重新编译内核,执行exec 5 关于exec的用法看:http://blog.chinaunix.net/uid-26798528-id-3497940.htmllinux exec用法总结
阅读(2003) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~