微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 一个相当详细的MINI2440按键驱动详解

一个相当详细的MINI2440按键驱动详解

时间:11-11 来源:互联网 点击:

s3c2410_gpio_cfgpin(button_irqs[i].pin,button_irqs[i].pin_setting);

/*中断的注册*/
/*request_irq()函数*/
/*要注意其输入参数*/
/*&button_irqs[i]是该中断享有的资源*/
/*会被传入buttons_interrupt,进行处理*/

err = request_irq(button_irqs[i].irq,buttons_interrupt,NULL,button_irqs[i].name,(void *)&button_irqs[i]);

/*中断类型的设置*/
/*set_irq_type()函数*/
/*IRQT_BOTHEDGE的中断类型代表什么样的中断呢?*/

/*有几个非常重要的问题*/
/*中断注册后,并设置好其中断类型之后,当有中断发生时,*/
/*即按下某个按钮时,系统能够自动检测到有中断发生吗?*/
/*检测到有中断发生,它能够自动辨别是几号中断吗?*/
/*知道了是几号中断,那么它能自动调用其中断服务程序吗?*/
/*对这几个问题的解答,够成了linux系统中断处理机制的核心*/

set_irq_type(button_irqs[i].irq,IRQT_BOTHEDGE);

/*注册失败的处理*/

if(err)
break; /*跳出循环*/
}

/*若有一个按钮中断注册失败*/
/*则还需把前面注册成功的中断给拆了*/

if(err)
{
i--; /*回到前面一个按钮的处理*/

for(;i >=0; i--) /*依此拆除*/
{
/*使中断不起作用*/

disable_irq(button_irqs[i].irq);

/*释放中断资源*/

free_irq(button_irqs[i].irq,(void *)&button_irqs[i]);
}

return -EBUSY; /*中断注册没成功的最终的返回值*/
}

return 0; /*正常返回*/
}

/**************************buttons_interrupt()*****************************/
/*此中断服务程序,在每中断一次,就要对key_values数组设一下值*/
/*并对数组可读标志位ev_press设一下值*/
/*并唤醒在等待队列里的进程*/
/*这是中断处理经常要做的事情*/
/*在这里,等待队列button_waitq里经常等待的进程是数组的读取进程*/
/*就是说,读取进程在没有读到数据的时候就一直在等待,等待按键的输入*/
/*读取进程在等待,并不代表所有进程在等待,其它进程该干啥干啥去*/

static irqreturn_t buttons_interrupt(int irq,void *dev_id)
{
/*button_irq_desc结构体变量*/
/*对传入的资源进行处理*/

struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;

/*获取寄存器的值*/
/*这一步至关重要*/
/*s3c2410_gpio_getpin()函数直接获取寄存器的值*/

/*要注意,按一下按钮,会发生两次中断*/

/*即按下是一次中断,放开又是一次中断*/

int up = s3c2410_gpio_getpin(button_irqs->pin);

/*通过电路原理图,可以知道没按下的时候,中断引脚应该是高电平*/
/*从而寄存器的值应该是1*/
/*变量取up也是有意义的,表示默认状态是弹起的状态*/
/*当按下按钮的状态下,寄存器的值就应该是0*/

/*下面对up的值进行处理*/
/*即是要把数据经过一定的变换存入key_values数组中*/

if(up) /*如果是弹起的状态*/
/*那么就要在key_values数组的相应位存入很大的一个值*/
/*同时又要能从值里辨别出是哪个按键*/

key_values[button_irqs->number] = (button_irqs->number + 1) + 0x80;
/*比如K1键开启的状态下,key_values[0]被置为(0+1)+0x80,即为129*/

else /*如果按键是闭合的状态*/
/*那么就要在key_values数组的相应位存入一个很小的数*/
/*同时又要能从值中辨别出是哪个键*/

key_values[button_irqs->number] = (button_irqs->number + 1);
/*比如K1键闭合,则key_values[0]被置为(0+1),即为1*/

/*对数组可读标志位进行设置*/

ev_press = 1; /*表示数组已经可读了*/

/*唤醒休眠的进程?*/
/*button_waitq队列里存放有相应的处理进程*/
/*如读取数组的值的进程*/
/*要注意wake_up_interruptible()这些函数的用法*/

wake_up_interruptible(&button_waitq);

/*返回*/

return IRQ_RETVAL(IRQ_HANDLED); /*?*/
}

/**********************mini2440_buttons_close()*****************************/

static int mini2440_buttons_close(struct inode *inode,struct file *file)
{
int i; /*循环变量,要操作好几个按键*/

/*for循环,对各个按键依此释放中断*/

for(i = 0;i < sizeof(button_irqs)/sizeof(button_irqs[0]);i++)
{
/*使中断失效*/

disable_irq(button_irqs[i].irq);

/*释放资源*/

free_irq(button_irqs[i].irq,(void *)&button_irqs[i]);
}

/*返回*/

return 0;
}

/**********************mini2440_buttons_read()***************************/

/*要注意,该read函数,只读取一次中断的值,而不是连续地读入*/
/*要做到连续地读入,则需要做一个循环,不断地调用该read函数,但那不是驱动程序里该做的事情*/

static int mini2440_buttons_read(struct file *fil

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top