當我們閱讀『技術文件』時,為什麼老覺得咬文嚼字,難以下咽的呢?這是因為『技術文件』之『術語』定義,必要的『精確性』 ── 精準且正確 ── 使然。比方說, CPU 的『存取單位』是一個『模糊』的名詞。因為『資料匯流排』 data bus 有多少『位元』的寬度,決定了那個 CPU 資料『存取單位』的大小。更不要說還有那『位元組』 byte 排序問題,因此不同種類的 CPU ,就有了『位元組序』 Endianness 的『大‧小』之區分。再加上許多『技術文件』通常用於整個『事物族系』,散布於『技術文件』的『不同部份』 ,很容易導致了『不知全盤』就『難知其一』的現象。舉例來講,什麼是『輸入事件』 input event ?假使我們查詢『 input_event 』名稱在 Kernel 4.1.X 中使用之『交互參考』,恐怕會暈頭轉向的吧!如果對『輸入裝置』這個子系統多些了解之後,也許從下面的資料『樣板結構』,就能知道梗概的了︰
Linux/include/uapi/linux/input.h
20 /*
21 * The event structure itself
22 */
23
24 struct input_event {
25 struct timeval time;
26 __u16 type;
27 __u16 code;
28 __s32 value;
29 };
30
這裡『__u16』和『__s32』都是指『位元』之大小,假使想更清楚知道這個『資料結構』大小及意義,還得先知道『__kernel_time_t』與『__kernel_suseconds_t』之大小及意義!!
Linux/include/uapi/linux/time.h
14
15 struct timeval {
16 __kernel_time_t tv_sec; /* seconds */
17 __kernel_suseconds_t tv_usec; /* microseconds */
18 };
19
這也就是一般 kernel 裝置『驅動程式』學習的為難處。因此若想『學習』 PiTFT 的『觸控輸入』,用
pi@raspberrypi ~ evtest /dev/input/touchscreen Input driver version is 1.0.1 Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0 Input device name: "stmpe-ts" Supported events: Event type 0 (EV_SYN) Event type 1 (EV_KEY) Event code 330 (BTN_TOUCH) Event type 3 (EV_ABS) Event code 0 (ABS_X) Value 1851 Min 0 Max 4095 Event code 1 (ABS_Y) Value 2714 Min 0 Max 4095 Event code 24 (ABS_PRESSURE) Value 0 Min 0 Max 255 Properties: Testing ... (interrupt to exit) Event: time 1439617362.428940, type 3 (EV_ABS), code 0 (ABS_X), value 2413 Event: time 1439617362.428940, type 3 (EV_ABS), code 1 (ABS_Y), value 2222 Event: time 1439617362.428940, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 93 Event: time 1439617362.428940, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1 Event: time 1439617362.428940, -------------- SYN_REPORT ------------ Event: time 1439617362.435368, type 3 (EV_ABS), code 0 (ABS_X), value 2482 Event: time 1439617362.435368, type 3 (EV_ABS), code 1 (ABS_Y), value 2238 Event: time 1439617362.435368, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 100 Event: time 1439617362.435368, -------------- SYN_REPORT ------------ Event: time 1439617362.441796, type 3 (EV_ABS), code 0 (ABS_X), value 2484 Event: time 1439617362.441796, type 3 (EV_ABS), code 1 (ABS_Y), value 2249 Event: time 1439617362.441796, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 97 Event: time 1439617362.441796, -------------- SYN_REPORT ------------ Event: time 1439617362.448270, type 3 (EV_ABS), code 0 (ABS_X), value 2550 Event: time 1439617362.448270, type 3 (EV_ABS), code 1 (ABS_Y), value 2256 Event: time 1439617362.448270, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 98 Event: time 1439617362.448270, -------------- SYN_REPORT ------------ Event: time 1439617362.454676, type 3 (EV_ABS), code 0 (ABS_X), value 2561 Event: time 1439617362.454676, type 3 (EV_ABS), code 1 (ABS_Y), value 2258 Event: time 1439617362.454676, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 96 Event: time 1439617362.454676, -------------- SYN_REPORT ------------ Event: time 1439617362.461091, type 3 (EV_ABS), code 0 (ABS_X), value 2555 Event: time 1439617362.461091, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 97 Event: time 1439617362.461091, -------------- SYN_REPORT ------------ Event: time 1439617362.483105, type 3 (EV_ABS), code 0 (ABS_X), value 2536 Event: time 1439617362.483105, type 3 (EV_ABS), code 1 (ABS_Y), value 2259 Event: time 1439617362.483105, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 101 Event: time 1439617362.483105, -------------- SYN_REPORT ------------ Event: time 1439617362.554620, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 0 Event: time 1439617362.554620, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0 Event: time 1439617362.554620, -------------- SYN_REPORT ------------
看似易讀,總『留有疑惑』,終究有賴於『整體了解』的耶??此正是研讀『高階程式庫』,更需要小心之處︰
This module provides the InputEvent
class, which closely resembles the input_event
struct defined in linux/input.h
:
struct input_event { struct timeval time; __u16 type; __u16 code; __s32 value; };
This module also defines several InputEvent
sub-classes that know more about the different types of events (key, abs, rel etc). The event_factory
dictionary maps event types to these classes.
Assuming you use the evdev.util.categorize()
function to categorize events according to their type, adding or replacing a class for a specific event type becomes a matter of modifying event_factory
.
All classes in this module have reasonable str()
and repr()
methods:
>>> print(event) event at 1337197425.477827, code 04, type 04, val 458792 >>> print(repr(event)) InputEvent(1337197425L, 477827L, 4, 4, 458792L) >>> print(key_event) key event at 1337197425.477835, 28 (KEY_ENTER), up >>> print(repr(key_event)) KeyEvent(InputEvent(1337197425L, 477835L, 1, 28, 0L))
,一旦『望文生義』常是『囫圇吞棗』之結果??所以請對眾多之『術語』務必清楚明白,這才是應用真實的基礎也!!
能夠嘗試『解讀』他人來源碼,或正是『寫程式』之基本功乎!?
pi@raspberrypi ~ $ python3 Python 3.2.3 (default, Mar 1 2013, 11:53:50) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from evdev import InputDevice, list_devices, categorize, ecodes >>> devices = [InputDevice(fn) for fn in list_devices()] >>> for dev in devices: ... print(dev.fn, dev.name, dev.phys) ... /dev/input/event2 Gwell HicHan RF-Dongle usb-3f980000.usb-1.2/input1 /dev/input/event1 Gwell HicHan RF-Dongle usb-3f980000.usb-1.2/input0 /dev/input/event0 stmpe-ts stmpe-ts/input0 >>> >>> dev = InputDevice('/dev/input/event0') >>> print(dev) device /dev/input/event0, name "stmpe-ts", phys "stmpe-ts/input0" >>> >>> dev.capabilities() {0: [0, 1, 3], 1: [330], 3: [(0, AbsInfo(value=2212, min=0, max=4095, fuzz=0, flat=0, resolution=0)), (1, AbsInfo(value=2904, min=0, max=4095, fuzz=0, flat=0, resolution=0)), (24, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0))]} >>> >>> dev.capabilities(verbose=True) {('EV_KEY', 1): [('BTN_TOUCH', 330)], ('EV_ABS', 3): [(('ABS_X', 0), AbsInfo(value=2212, min=0, max=4095, fuzz=0, flat=0, resolution=0)), (('ABS_Y', 1), AbsInfo(value=2904, min=0, max=4095, fuzz=0, flat=0, resolution=0)), (('ABS_PRESSURE', 24), AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0))], ('EV_SYN', 0): [('SYN_REPORT', 0), ('SYN_CONFIG', 1), ('SYN_DROPPED', 3)]} >>> >>> for event in dev.read_loop(): ... if event.type == ecodes.EV_ABS: ... print(categorize(event)) ... absolute axis event at 1439627454.210421, ABS_X absolute axis event at 1439627454.210421, ABS_Y absolute axis event at 1439627454.210421, ABS_PRESSURE absolute axis event at 1439627454.241907, ABS_X absolute axis event at 1439627454.241907, ABS_Y absolute axis event at 1439627454.241907, ABS_PRESSURE absolute axis event at 1439627454.257593, ABS_X absolute axis event at 1439627454.257593, ABS_Y absolute axis event at 1439627454.257593, ABS_PRESSURE absolute axis event at 1439627454.264023, ABS_X absolute axis event at 1439627454.264023, ABS_Y absolute axis event at 1439627454.264023, ABS_PRESSURE absolute axis event at 1439627454.270441, ABS_X absolute axis event at 1439627454.270441, ABS_Y absolute axis event at 1439627454.270441, ABS_PRESSURE absolute axis event at 1439627454.276901, ABS_X absolute axis event at 1439627454.276901, ABS_Y absolute axis event at 1439627454.276901, ABS_PRESSURE absolute axis event at 1439627454.380102, ABS_PRESSURE