input子系统:
像按键、键盘、鼠标、触摸屏、游戏摇杆等设备只有输入没有输出,而且在编程实现其对应的驱动程序时会有很多重复性的代码,内核的设计者将该部分代码抽象出来,驱动工程师只需要复用该部分代码,并且实现硬件相关的代码(中断号,中断触发条件),就可以可以很容易实现对应硬件的驱动程序 如何用复用input子系统中提供的通用函数功能模块, 要遵循以下步骤:
核心数据结构
struct input_dev
{
evbit//记录该设备将来会报告哪些事件
}
1)分配一个输入设备//定义一个input_dev类型变量
input_allocate_device()
2)设置input_dev
3)注册input_dev
input_register_device
4)硬件操作
注册中断服务程序
延时去抖
//保存按键值
5)向input核心模块报告事件
input_event(...)
6)注销input_dev
input_unregister_device
7)释放输入设备
input_free_device(...)
代码实例:
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 //定义按键硬件私有数据结构 9 struct btn_resource { 10 char *name; //名称 11 int irq; //中断号 12 int gpio; //GPIO编号 13 int code; //键值 14 }; 15 16 //初始化开发板按键信息 17 static struct btn_resource btn_info[] = { 18 [0] = { 19 .name = 'KEY_L', 20 .irq = IRQ_EINT(0), 21 .gpio = S5PV210_GPH0(0), 22 .code = KEY_L 23 }, 24 [1] = { 25 .name = 'KEY_S', 26 .irq = IRQ_EINT(1), 27 .gpio = S5PV210_GPH0(1), 28 .code = KEY_S 29 }, 30 [2] = { 31 .name = 'KEY_ENTER', 32 .irq = IRQ_EINT(2), 33 .gpio = S5PV210_GPH0(2), 34 .code = KEY_ENTER 35 }, 36 }; 37 38 //定义input_dev指针 39 static struct input_dev *btn_dev; 40 41 //分配定时器 42 static struct timer_list btn_timer; 43 static struct btn_resource *pdata; 44 45 //定时器的处理函数 46 static void btn_timer_func(unsigned long data) 47 { 48 unsigned int pinstate; 49 50 //2.获取按键的状态 51 pinstate = gpio_get_value(pdata->gpio); 52 53 //3.上报按键信息给核心层然后唤醒休眠的进程 54 if (pinstate == 1) { //松开 55 //EV_KEY:上报按键类事件 56 //pdata->code:具体键值 57 //0:松开 58 input_event(btn_dev, EV_KEY, pdata->code, 0); 59 input_sync(btn_dev); //上报同步类事件 60 } else { //按下 61 //EV_KEY:上报按键类事件 62 //pdata->code:具体键值 63 //1:按下 64 input_event(btn_dev, EV_KEY, pdata->code, 1); 65 input_sync(btn_dev);//上报同步类事件 66 } 67 } 68 69 //中断处理函数 70 static irqreturn_t button_isr(int irq, void *dev_id) 71 { 72 //1.获取按键对应的数据项 73 pdata = (struct btn_resource *)dev_id; 74 75 //2.启动定时器,设置定时器的超时时间为10ms 76 mod_timer(&btn_timer, jiffies + msecs_to_jiffies(10)); 77 return IRQ_HANDLED; 78 } 79 80 static int btn_init(void) 81 { 82 int i; 83 84 //1.分配input_dev 85 btn_dev = input_allocate_device(); 86 87 //2.初始化input_dev 88 btn_dev->name = 'wf_button'; 89 //2.1设置上报按键类事件 90 set_bit(EV_KEY, btn_dev->evbit); 91 //2.2设置上报重复类事件 92 set_bit(EV_REP, btn_dev->evbit); 93 //2.3设置上报按键类事件中的哪些键值 94 for(i = 0; i < ARRAY_SIZE(btn_info); i++) 95 set_bit(btn_info[i].code, btn_dev->keybit); 96 97 //3.注册input_dev 98 input_register_device(btn_dev); 99 100 //4.申请GPIO资源 101 //5.注册中断处理函数 102 for (i = 0; i < ARRAY_SIZE(btn_info); i++) { 103 gpio_request(btn_info[i].gpio, btn_info[i].name); 104 request_irq(btn_info[i].irq, button_isr/*中断处理函数*/, 105 IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,/*下降沿和上升沿触发*/ 106 btn_info[i].name, &btn_info[i]/*给中断处理函数传递的参数*/); 107 } 108 109 //6.初始化定时器 处理按键的毛刺 110 init_timer(&btn_timer); 111 112 //6.1指定定时器的处理函数 113 btn_timer.function = btn_timer_func; 114 add_timer(&btn_timer);//将定时器添加到内核中 115 return 0; 116 } 117 118 static void btn_exit(void) 119 { 120 int i; 121 122 //1.释放中断,释放GPIO资源 123 for (i = 0; i < ARRAY_SIZE(btn_info); i++) { 124 gpio_free(btn_info[i].gpio); 125 free_irq(btn_info[i].irq, &btn_info[i]); 126 } 127 128 //2.卸载input_dev 129 input_unregister_device(btn_dev); 130 131 //3.释放input_dev内存 132 input_free_device(btn_dev); 133 134 //4.删除定时器 135 del_timer(&btn_timer); 136 } 137 138 module_init(btn_init); 139 module_exit(btn_exit); 140 MODULE_LICENSE('GPL'); 测试代码: 1 #include 2 #include 3 #include 4 #include 5 #include 6 7 int main(int argc, char *argv[]) 8 { 9 int fd; 10 struct input_event button; 11 12 fd = open(argv[1], O_RDWR); //./btn_test /dev/input/event3 13 if (fd < 0) { 14 printf('open button failed.n'); 15 return -1; 16 } 17 18 while(1) { 19 read(fd, &button, sizeof(button)); 20 printf('type = %#x, code = %#x, value = %#xn', 21 button.type, button.code, button.value); 22 } 23 24 close(fd); 25 return 0; 26 }
上一篇:TQ210搭载Android 4.0.3测试Google Maps API V2(一.获取地图)
下一篇:创建一个字符设备1.1
推荐阅读最新更新时间:2026-03-20 15:05
- ADR435B 5 Vout 超低噪声 XFET 电压基准的典型应用,具有灌电流和拉电流能力
- 使用 Analog Devices 的 ADP8140 的参考设计
- NCP699SN30T1G 150mA、3 路输出电压 CMOS 低 Iq LDO 的典型应用,在 TSOP-5 中启用
- ZTL431过压/欠压保护电路典型应用
- 使用 Microchip Technology 的 DVR2802B3 的参考设计
- 开源的浮游生物监测分析设备PlanktoScope
- STK503,旨在评估 AT90USB AVR MCU 的入门套件,通过 AVR Studio 支持 JTAGICE mkII 和 AVRISP mkII
- 使用 BittWare 的 XCVU190 的参考设计
- 远程声控参考设计
- NCP4354AADAPGEVB,用于 NCP4354、65W 适配器关闭模式控制器的评估板
- 海康机器人视觉检测方案守护光伏组件生产质量
- 艾利特CSF系列力控协作机器人来了!
- MTBF突破4万小时!这家工业级3D相机品牌产品稳定性获权威机构认可
- G20周刊|埃斯顿与北自所达成战略合作、海康机器人发布光伏组件汇流带视觉检测解决方案
- 14家工业智能企业入选《上海市智能机器人标杆企业与应用场景推荐目录》
- OK6410A 开发板 (八) 20 linux-5.11 OK6410A start_kernel 功能角度 第三阶段之kthreadd进程
- OK6410A 开发板 (八) 21 linux-5.11 OK6410A schedule 的 __switch_to 部分
- OK6410A 开发板 (八) 22 linux-5.11 OK6410A start_kernel 功能角度 第一阶段
- Intel计划四年内量产5代CPU工艺:相当于“1.8nm”水平
- 英特尔、ARM、英伟达力推规范草案,想统一AI数据交换格式

电力电子技术基础第三版(Fundamentals of Power Electronics )
现代雷达系统的信号设计
BFR340T






京公网安备 11010802033920号