先办事后付款的黑客免费接单黑客QQ接单网
tangfengyu2023-01-30 20:14:34健康新闻75来源:男科
先办事后付款的黑客免费接单黑客QQ接单网
Note that input core keeps track of number of users for the device and makes sure that dev-> open () is called only when the first user connects to the device and that dev->close() is called when the very last user disconnects. Calls to both callbacks are serialized. The open () callback should return a 0 in case of success or any nonzero value in case of failure. The close() callback ( which is void) must always succeed. 1.3 Basic event types ~~~~~~~~~~~~~~~~~~~~~ The most simple event type is EV_KEY, which is used for keys and buttons. It's reported to the input system via: input_report_key(struct input_dev *dev, int code, int value) See linux /input .h for the allowable values of code (from 0 to KEY_MAX). Value is interpreted as a truth value, ie any nonzero value means key pressed, zero value means key released. The input code generates events only in case the value is different from before. In addition to EV_KEY, there are two more basic event types: EV_REL and EV_ABS. They are used for relative and absolute values supplied by the device. A relative value may be for example a mouse movement in the X axis. The mouse reports it as a relative difference from the last position, because it doesn't have any absolute coordinate system to work in . Absolute events are namely for joysticks and digitizers - devices that do work in an absolute coordinate systems. Having the device report EV_REL buttons is as simple as with EV_KEY, simply set the corresponding bits and call the input_report_rel(struct input_dev *dev, int code, int value) function . Events are generated only for nonzero value. However EV_ABS requires a little special care. Before calling input_register_device, you have to fill additional fields in the input_dev struct for each absolute axis your device has. If our button device had also the ABS_X axis: button_dev.absmin[ABS_X] = 0; button_dev.absmax[ABS_X] = 255; button_dev.absfuzz[ABS_X] = 4; button_dev.absflat[ABS_X] = 8; Or, you can just say: input_set_abs_params(button_dev, ABS_X, 0, 255, 4, 8); This setting would be appropriate for a joystick X axis, with the minimum of 0, maximum of 255 ( which the joystick *must* be able to reach, no problem if it sometimes reports more , but it must be able to always reach the min and max values), with noise in the data up to +- 4, and with a center flat position of size 8. If you don't need absfuzz and absflat, you can set them to zero, which mean that the thing is precise and always returns to exactly the center position ( if it has any). 1.4 BITS_TO_LONGS(), BIT_WORD(), BIT_MASK() ~~~~~~~~~~~~~~~~~~~~~~~~~~ These three macros from bitops.h help some bitfield computations: BITS_TO_LONGS(x) - returns the length of a bitfield array in longs for x bits BIT_WORD(x) - returns the index in the array in longs for bit x BIT_MASK(x) - returns the index in a long for bit x 1.5 The id * and name fields ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The dev->name should be set before registering the input device by the input device driver. It 's a string like ' Generic button device' containing a user friendly name of the device. The id * fields contain the bus ID (PCI, USB, ...), vendor ID and device ID of the device. The bus IDs are defined in input.h. The vendor and device ids are defined in pci_ids.h, usb_ids.h and similar include files. These fields should be set by the input device driver before registering it. The idtype field can be used for specific information for the input device driver. The id and name fields can be passed to userland via the evdev interface. 1.6 The keycode, keycodemax, keycodesize fields ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These three fields should be used by input devices that have dense keymaps. The keycode is an array used to map from scancodes to input system keycodes. The keycode max should contain the size of the array and keycodesize the size of each entry in it ( in bytes). Userspace can query and alter current scancode to keycode mappings using EVIOCGKEYCODE and EVIOCSKEYCODE ioctls on corresponding evdev interface. When a device has all 3 aforementioned fields filled in , the driver may rely on kernel's default implementation of setting and querying keycode mappings. 1.7 dev->getkeycode() and dev->setkeycode() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ getkeycode() and setkeycode() callbacks allow drivers to override default keycode /keycodesize/keycodemax mapping mechanism provided by input core and implement sparse keycode maps. 1.8 Key autorepeat ~~~~~~~~~~~~~~~~~~ ... is simple. It is handled by the input.c module. Hardware autorepeat is not used, because it's not present in many devices and even where it is present, it is broken sometimes (at keyboards: Toshiba notebooks). To enable autorepeat for your device, just set EV_REP in dev->evbit. All will be handled by the input system. 1.9 Other event types, handling output events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The other event types up to now are: EV_LED - used for the keyboard LEDs. EV_SND - used for keyboard beeps. They are very similar to for example key events, but they go in the other direction - from the system to the input device driver. If your input device driver can handle these events, it has to set the respective bits in evbit, *and* also the callback routine: button_dev->event = button_event; int button_event(struct input_dev *dev, unsigned int type , unsigned int code, int value); { if ( type == EV_SND && code == SND_BELL) { outb(value, BUTTON_BELL); return 0; } return -1; } This callback routine can be called from an interrupt or a BH (although that isn't a rule), and thus must not sleep , and must not take too long to finish. input-programming.txt |
该例子提供的案例代码描述了一个button设备,产生的事件通过BUTTON_PORT引脚获取,当有按下/释放发生时,BUTTON_IRQ被触发,以下是驱动的源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #include <linux/input.h> #include <linux/module.h> #include <linux/init.h> #include <asm/irq.h> #include <asm/io.h> static struct input_dev *button_dev; /*输入设备结构体*/ /*中断处理函数*/ static irqreturn_t button_interrupt(int irq, void *dummy) { /*向输入子系统报告产生按键事件*/ input_report_key(button_dev, BTN_0, inb(BUTTON_PORT) & 1); /*通知接收者,一个报告发送完毕*/ input_sync(button_dev); return IRQ_HANDLED; } /*加载函数*/ static int __init button_init(void) { int error; /*申请中断处理函数*/ // 返回0表示成功,返回-INVAL表示无效 if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button" , NULL)) { /*申请失败,则打印出错信息*/ printk(KERN_ERR "button.c: Can't allocate irq %d\n" , button_irq); return -EBUSY; } /*分配一个设备结构体*/ // 将在 sys /class/input/input-n 下面创建设备属性文件 button_dev = input_allocate_device(); if (!button_dev) { /*判断分配是否成功*/ printk(KERN_ERR "button.c: Not enough memory\n" ); error = -ENOMEM; goto err_free_irq; } button_dev->evbit[0] = BIT_MASK(EV_KEY); /*设置按键信息*/ button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); error = input_register_device(button_dev); /*注册一个输入设备*/ if (error) { printk(KERN_ERR "button.c: Failed to register device\n" ); goto err_free_dev; } return 0; /*以下是错误处理*/ err_free_dev: input_free_device(button_dev); err_free_irq: free_irq(BUTTON_IRQ, button_interrupt); return error; } /*卸载函数*/ static void __exit button_exit(void) { input_unregister_device(button_dev); /*注销按键设备*/ free_irq(BUTTON_IRQ, button_interrupt);/*释放按键占用的中断线*/ } module_init(button_init); module_exit(button_exit); |