//buttons_timer.expires = 0;
add_timer(&buttons_timer);
major = register_chrdev(0, "key_drv", &key_drv_fops);
keydrv_class = class_create(THIS_MODULE, "key_drv");
keydrv_class_dev = class_device_create(keydrv_class, NULL, MKDEV(major, 0), NULL, "buttons");
// /dev/buttons
gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);
gpfdat = gpfcon + 1;
gpgcon = (volatile unsigned long *)ioremap(0x56000060, 16);
gpgdat = gpgcon + 1;
return 0;
}
static void key_drv_exit(void)
{
unregister_chrdev(major, "key_drv");
class_device_unregister(keydrv_class_dev);
class_destroy(keydrv_class);
iounmap(gpfcon);
iounmap(gpgcon);
return 0;
}
module_init(key_drv_init);
module_exit(key_drv_exit);
MODULE_LICENSE("GPL");
=================================================================
测试程序:
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "stdio.h"
#include "poll.h"
#include "signal.h"
#include "sys/types.h"
#include "unistd.h"
#include "fcntl.h"
int fd;
void my_signal_fun(int signum)
{
unsigned char key_val;
read(fd, &key_val, 1);
printf("key_val: 0x%x\n", key_val);
}
int main(int argc, char **argv)
{
int ret;
fd = open("/dev/buttons", O_RDWR);
if(fd < 0)
{
printf("cant open!\n");
return -1;
}
while(1)
{
ret = read(fd, &key_val, 1);
printf("key_val:0x%x,ret = %d",key_val,ret);
//sleep(5);
}
return 0;
}
===============================================================
解析:
1、先定义一个定时器:static struct timer_list buttons_timer;
2、再在key_drv_init函数中初始化定时器:
init_timer(&buttons_timer);
buttons_timer.function = buttons_timer_function;
//buttons_timer.expires = 0;
add_timer(&buttons_timer);
3、在按键中断中设置定时器时间:
mod_timer(&buttons_timer,jiffies+HZ/100); //10ms以后启动定时器
4、如果没有二次中断修改中断时间则10ms以后就会进入定时器中断函数,处理定时器中断。