Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1254264
  • 博文数量: 404
  • 博客积分: 10011
  • 博客等级: 上将
  • 技术积分: 5382
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-03 16:29
文章存档

2010年(40)

2009年(140)

2008年(224)

我的朋友

分类: LINUX

2008-09-25 17:38:59

/*这段代码是一个用户模式下的DEMO,不是真正的驱动,它负责把按键的键值打印输出*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

int main(void)
{
int buttons_fd;
int key_value;

buttons_fd = open("/dev/buttons", 0);
if (buttons_fd < 0) {
perror("open device buttons");
exit(1);
}

for (;;) {
fd_set rds;
int ret;

FD_ZERO(&rds);
FD_SET(buttons_fd, &rds);

ret = select(buttons_fd + 1, &rds, NULL, NULL, NULL);
if (ret < 0) {
perror("select");
exit(1);
}
if (ret == 0) {
printf("Timeout.\n");
} else if (FD_ISSET(buttons_fd, &rds)) {
int ret = read(buttons_fd, &key_value, sizeof key_value);
if (ret != sizeof key_value) {
if (errno != EAGAIN)
perror("read buttons\n");
continue;
} else {
printf("buttons_value: %d\n", key_value);
}

}
}

close(buttons_fd);
return 0;
}

/*下面是真正的驱动部分*/
#include
#include
#include
#include

#include
#include
#include
#include
#include
#include
#include

#include

#define DEVICE_NAME "buttons"
#define BUTTON_MAJOR 232

static struct key_info {
int irq_no;
unsigned int gpio_port;
int key_no;
} key_info_tab[4] = {
{ IRQ_EINT1, GPIO_F1, 1 },
{ IRQ_EINT2, GPIO_F2, 2 },
{ IRQ_EINT3, GPIO_F3, 3 },
{ IRQ_EINT7, GPIO_F7, 4 },
};

static int ready = 0;
static int key_value = 0;

static DECLARE_WAIT_QUEUE_HEAD(buttons_wait);

static void buttons_irq(int irq, void *dev_id, struct pt_regs *reg)
{
struct key_info *k;
int i;
int found = 0;
int up;
int flags;
for (i = 0; i < sizeof key_info_tab / sizeof key_info_tab[1]; i++) {
k = key_info_tab + i;
if (k->irq_no == irq) {
found = 1;
break;
}
}
if (!found) {
printk("bad irq %d in button\n", irq);
return;
}

save_flags(flags);
cli();
set_gpio_mode_user(k->gpio_port, GPIO_MODE_IN);
up = read_gpio_bit(k->gpio_port);
set_external_irq(k->irq_no, EXT_BOTH_EDGES, GPIO_PULLUP_DIS);
restore_flags(flags);
if (up) {
key_value = k->key_no + 0x80;
} else {
key_value = k->key_no;
}
ready = 1;
wake_up_interruptible(&buttons_wait);
}

static int request_irqs(void)
{
struct key_info *k;
int i;
for (i = 0; i < sizeof key_info_tab / sizeof key_info_tab[1]; i++) {
k = key_info_tab + i;
set_external_irq(k->irq_no, EXT_BOTH_EDGES, GPIO_PULLUP_DIS);
if (request_irq(k->irq_no, &buttons_irq, SA_INTERRUPT, DEVICE_NAME, &buttons_irq)) {
return -1;
}

}
return 0;
}

static void free_irqs(void)
{
struct key_info *k;
int i;
for (i = 0; i < sizeof key_info_tab / sizeof key_info_tab[1]; i++) {
k = key_info_tab + i;
free_irq(k->irq_no, buttons_irq);
}
}

static int matrix4_buttons_read(struct file * file, char * buffer, size_t count, loff_t *ppos)
{
static int key;
int flags;
int repeat;
if (!ready)
return -EAGAIN;
if (count != sizeof key_value)
return -EINVAL;
save_flags(flags);
if (key != key_value) {
key = key_value;
repeat = 0;
} else {
repeat = 1;
}
restore_flags(flags);

if (repeat) {
return -EAGAIN;
}

copy_to_user(buffer, &key, sizeof key);
ready = 0;
return sizeof key_value;
}

static unsigned int matrix4_buttons_select(
struct file *file,
struct poll_table_struct *wait)
{
if (ready)
return 1;
poll_wait(file, &buttons_wait, wait);
return 0;
}


static int matrix4_buttons_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
switch(cmd) {
default:
return -EINVAL;
}
}
static struct file_operations matrix4_buttons_fops = {
owner: THIS_MODULE,
ioctl: matrix4_buttons_ioctl,
poll: matrix4_buttons_select,
read: matrix4_buttons_read,
};

static devfs_handle_t devfs_handle;
static int __init matrix4_buttons_init(void)
{
int ret;

ready = 0;
ret = register_chrdev(BUTTON_MAJOR, DEVICE_NAME, &matrix4_buttons_fops);
if (ret < 0) {
printk(DEVICE_NAME " can't register major number\n");
return ret;
}

ret = request_irqs();
if (ret) {
unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);
printk(DEVICE_NAME " can't request irqs\n");
return ret;
}
devfs_handle = devfs_register(NULL, DEVICE_NAME, DEVFS_FL_DEFAULT,
BUTTON_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR, &matrix4_buttons_fops, NULL);

return 0;
}

static void __exit matrix4_buttons_exit(void)
{
devfs_unregister(devfs_handle);
free_irqs();
unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);
}

module_init(matrix4_buttons_init);
module_exit(matrix4_buttons_exit);
MODULE_LICENSE("GPL");

红色的代码作用?何时(或什么条件下)能执行此段代码?蓝色代码执行后,有什么结果?是调用红色代码吗?如果是,那他们的参数怎么不一样?
阅读(1065) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~