输入系统之led灯控制
来源:互联网 发布:java项目输出日志文件 编辑:程序博客网 时间:2024/04/30 17:13
目前下面的程序在卸载时会出现问题,原因有待查找,问题出现在input_unregister_device(),程序如下:
#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/delay.h>#include <asm/uaccess.h>#include <linux/gpio.h> #include <asm/irq.h>#include <linux/sched.h> #include <linux/irq.h>#include <asm/io.h>#include <linux/device.h>#include <linux/interrupt.h>#include <linux/wait.h>#include <linux/cdev.h>#include <linux/platform_device.h>#include <linux/timer.h>#include <linux/poll.h>#include <linux/fcntl.h>#include <linux/input.h>#define DRVNAME "s5pv210_gpio"struct led_device_ops{ struct input_dev *input; wait_queue_head_t my_waitqueue; struct timer_list timer; /* statistic timer */ int irq; unsigned long virt;};static struct led_device_ops led_info;static uint32_t last_timer; static volatile int press = 0; struct pin_desc{ unsigned char key_val;};static unsigned char witch_key = 0;static struct pin_desc key_descs[8] ={ [0] = { .key_val = KEY_1, }, [1] = { .key_val = KEY_2, }, [2] = { .key_val = KEY_3, }, [3] = { .key_val = KEY_4, }, [4] = { .key_val = KEY_5, }, [5] = { .key_val = KEY_6, }, [6] = { .key_val = KEY_7, }, [7] = { .key_val = KEY_8, }, };volatile unsigned long *GPC0CON, *GPC0DAT;//用与存放两个个寄存器的地址volatile unsigned long *GPH0CON, *GPH0DAT;//按键static unsigned char KeyFlag;static void all_leds_off(void);static void led_config(void){ volatile unsigned long phys;//用于存放虚拟地址和物理地址 phys = 0xE0200060; led_info.virt =(unsigned long)ioremap(phys, 0xf00); GPC0CON = (unsigned long *)(led_info.virt + 0x00);//指定需要操作的三个寄存器的地址 GPC0DAT = (unsigned long *)(led_info.virt + 0x04); GPH0CON = (unsigned long *)(led_info.virt + 0xc00-0x60); //keY1配置为输入 GPH0DAT = (unsigned long *)(led_info.virt + 0xc00-0x60+0x04); *GPC0CON &= ~(0xFF << 12); *GPC0CON |= 0x11 << 12; // 配置GPC0_3和GPC0_4为输出 *GPH0CON &= ~0x0F; //配置为输入 all_leds_off();}static void led1_on(void){ *GPC0DAT |= 1 << 3; *GPC0DAT &= ~(0x01 << 4);// printk("led1 light\n");}static void led2_on(void){ *GPC0DAT |= 1 << 4; *GPC0DAT &= ~(0x01 << 3);// printk("led2 light\n");}static void all_leds_on(void){ *GPC0DAT |= 1 << 3; // 点亮LED1 *GPC0DAT |= 1 << 4; // 点亮LED2 printk("all leds light\n");}static void all_leds_off(void){ *GPC0DAT &= ~(0x3 << 3); // 熄灭LED1和LED2 printk("all leds off\n");}static void led_timer_event(unsigned long arg){ press = 1; KeyFlag = !KeyFlag; if(KeyFlag) { led1_on(); } else { led2_on(); } printk("Timer event time = %ld\n",jiffies-last_timer); input_event(led_info.input, EV_KEY, witch_key, 0); input_sync(led_info.input);}static irqreturn_t led_handler(int irq, void *devid){ struct pin_desc * pindesc = (struct pin_desc *)devid; mod_timer(&led_info.timer,jiffies+HZ); //这里设置定时中断程序多久之后执行,可适当变短些, last_timer=jiffies; //这里为了使程序实验效果更加明显,直接用1s witch_key = pindesc->key_val; printk("KERNEL:irq == %d witch_key= %d\n",irq,witch_key); return IRQ_RETVAL(IRQ_HANDLED); }static int led_device_open(struct inode *inode, struct file *file){ printk("led_drv_open\n"); file->private_data = &led_info; return 0;}static int led_device_release(struct inode *inode, struct file *file){ return 0;}static const struct file_operations led_device_fileops = { .owner = THIS_MODULE, .open = led_device_open, .release = led_device_release,};static int led_device_init(void){ int rc,i,error; //struct led_device_ops *ddata; //struct input_dev *input; //ddata = kzalloc(sizeof(struct led_device_ops),GFP_KERNEL); led_info.input = input_allocate_device(); if (!led_info.input) { printk(KERN_ERR"failed to allocate state\n"); error = -ENOMEM; goto fail1; } //ddata->input = input; led_info.input->name = "key_device"; set_bit(EV_KEY, led_info.input->evbit); set_bit(KEY_1, led_info.input->keybit); set_bit(KEY_2, led_info.input->keybit); set_bit(KEY_3, led_info.input->keybit); set_bit(KEY_4, led_info.input->keybit); set_bit(KEY_5, led_info.input->keybit); set_bit(KEY_6, led_info.input->keybit); set_bit(KEY_7, led_info.input->keybit); set_bit(KEY_8, led_info.input->keybit); //led_info.input = ddata->input; error = input_register_device(led_info.input); if (error) { printk(KERN_ERR"Unable to register input device, error: %d\n", error); goto fail2; } input_sync(led_info.input); for(i=0;i<5;i++) { rc = request_irq(IRQ_EINT(i), &led_handler, IRQ_TYPE_EDGE_FALLING,"led_irq", &key_descs[i]); if(rc) { printk(KERN_ERR"function request_irq(%d) excute error\n",i); goto led_request_irq_error; } } init_timer(&led_info.timer); led_info.timer.function = led_timer_event; add_timer(&led_info.timer); led_config(); all_leds_off(); return 0; /* succeed */ led_request_irq_error: fail2: fail1: input_free_device(led_info.input); return error;}static void led_device_exit(void){ iounmap((void *)led_info.virt); //撤销映射关系 free_irq(IRQ_EINT(0), &key_descs[0]); free_irq(IRQ_EINT(1), &key_descs[1]); free_irq(IRQ_EINT(2), &key_descs[2]); free_irq(IRQ_EINT(3), &key_descs[3]); free_irq(IRQ_EINT(4), &key_descs[4]); printk("led_drv_exit ....excute ok\n"); //all_leds_off(); printk("led_drv_exit ....excute ok0\n"); printk("led_drv_exit ....excute ok1\n"); printk("led_drv_exit ....excute ok2\n"); input_free_device(led_info.input); printk("led_drv_exit ....excute ok3\n"); input_unregister_device(led_info.input); //此处有段错误出现 printk("led_drv_exit ....excute ok4\n"); }module_init(led_device_init);module_exit(led_device_exit);MODULE_AUTHOR("Ethyn blog:http://blog.csdn.net/humanspider1");MODULE_DESCRIPTION("cortex a8 S5pv210 led test Driver");
0 0
- 输入系统之led灯控制
- Stm32按键输入控制LED灯
- 嵌入式驱动之PWM控制LED灯
- 树莓派GPIO入门之控制LED灯
- LED灯控制实验
- Led灯控制代码
- 2440裸机学习之——LED灯的控制
- 2440裸机学习之——LED灯的控制
- 字符设备驱动之led灯的控制实验
- 树莓派入门二之GPIO控制LED灯
- STM32实例之LED灯闪烁控制以及相关注意事项
- CC2530基础实验之串口控制LED灯
- 树莓派养成之路 ——siri 控制LED灯
- arduino学习之led相关--跑马灯+电位器控制led亮灭
- 控制Android LED灯颜色代码
- 5.0 按键控制LED灯
- arm汇编控制led灯
- 四、串口控制LED灯
- 解决了Cocoapods Undefined symbols for architecture _OBJC_CLASS_xxxx的问题,辛苦死我了,记录下之后有空在研究
- 在Oracle Linux 6.5上安装Oracle 10gR2 的最佳实践【Maclean版】
- Girl_iOS100天学iOS的第三天(Plist&UIPickerView)
- 输出好看的图形
- 安装mysql 5.5.8 Error Nr.1364 authentication_string
- 输入系统之led灯控制
- NodeJS会是昙花一现吗?
- Fragment之7____在Fragment 不能正常显示时显示Activity
- Yii1.1 优化URL之去掉index.php(ubuntu Apache2)
- JUnit4单元测试使用方法
- 软件的复用技术及开发方法
- nodejs之旅-001-认识nodejs
- 中小板的时间非即白餐巾纸就东方幻想方法
- 人月神话读后感