As an income device, keyboards are widely used in embedded systems. Different from PC keyboards, the keyboards in embedded systems vary widely in different scenarios. This is a non-standard keyboard driver.ProgramDesign. In some applications, only a few limited buttons may be used. To save hardware costs and make full use of existing hardware resources, these buttons are usually connected to the MCU's External Interrupt pin. For example, there are more than one hundred gpios in S3C2410 and dozens of external interruptions. We can use several external interruptions to implement the system's key-Pressing function.
Although the keyboards in the embedded system are various and different, the driver framework is basically the same. From the perspective of working mode, there are usually interruption methods and scanning methods. Read the scan code of the key in the interrupt service thread and convert it into a virtual key information and send it to the system. The scanning process is similar. However, as mentioned above, non-standard keyboard drivers do not need to use this framework. Instead, they use a normal interrupt processing method to simulate the corresponding key information in the interrupt service thread and call the function keybd_event () you can.
The following uses external interrupt 4 of S3C2410 as an example to briefly introduce the entire process.
Code
1 Uint32 irq1 = Irq_eint4;
2 Uint32 sysintr1 = Sysintr_undefined;
3 Handle intrevent1 = NULL;
4 Bool bthreadexit1 = False;
5 Uint intrthreadproc1 (lpvoid );
6 // Analog button
7 Void Simulatekey (byte bvk)
8 {
9Keybd_event (bvk,0,0,0);
10Keybd_event (bvk,0, Keyeventf_keyup,0);
11}
12 Key in key_init ()Code:
13 // Initialization interruption
14 Enableinterrupt ();
15 // Create an interrupted service thread
16 If ( ! Createthread ( 0 , 0 , (Lpthread_start_routine) intrthreadproc1, 0 , 0 , Null ))
17 {
18Retailmsg (1, (Text ("* ** Keydrv: key_init fail (1). \ r \ n")));
19ReturnFalse;
20}
21 Key code in key_deinit:
22 // Set the exit flag for the thread
23 Bthreadexit1 = True;
24 // Simulate an interruption event
25 Setinterruptevent (sysintr1 );
26 // Interrupt service thread
27 Uint intrthreadproc1 (lpvoid PTR)
28 {
29 Intrevent1 = Createevent (null, false, false, null );
30
31 If ( ! Kerneliocontrol (ioctl_hal_request_sysintr, & Irq1, Sizeof (Uint32 ), & Sysintr1, Sizeof (Uint32), null ))
32 {
33Retailmsg (1, (Text ("Error: intrthreadproc1 failed to request sysintr. \ r \ n")));
34Return(0);
35}
36
37 // Associate sysintr with the previously created event
38 If ( ! (Interruptinitialize (sysintr1, intrevent1, 0 , 0 )))
39 {
40Retailmsg (1, (Text ("Error: intrthreadproc1 interruptinitialize failed. \ r \ n")));
41}
42
43 While ( 1 )
44 {
45 Waitforsingleobject (intrevent1, infinite );
46
47 If (Bthreadexit1)
48 {
49Break;
50}
51
52 Simulatekey (vk_f1 );
53 Sleep ( 1 );
54 Interruptdone (sysintr1 );
55 }
56 // Cancel association between IRQ and sysintr
57 Kerneliocontrol (ioctl_hal_release_sysintr, & Sysintr1, Sizeof (Uint32), null, 0 , Null );
58 // Cancel association between event and pwrbuttonsysintr
59 Interruptdisable (sysintr1 );
60 Closehandle (intrevent1 );
61 Retailmsg ( 1 , (Text ( " Intrthreadproc1 ist exit. \ r \ n " )));
62 Return 0 ;
63 }
64
This interrupted service thread simulates the F1 pressing and lifting process. Therefore, when the external interrupt 4 is triggered, the system will receive the F1 key information, upper-layer applications can further handle this problem. If there are only two or three buttons in the hardware system, this method is more convenient. If there are many buttons, you can define a structure to streamline the code.
In addition, if the interruption cannot work properly, perform the following steps to troubleshoot the problem one by one.
1.Is the hardware interruption triggered. You can use an oscilloscope to view the signal of the interrupt pin.
2.Does the driver correctly configure the interrupted working mode. In general, interrupt and IO multiplexing must be configured when interrupt is used. After the configuration is complete, you also need to prevent modification by other programs.
3.If there is an interrupt signal and the configuration is completely correct and has not been modified by others, you need to consider whether the current interrupt has been registered by another driver. In wince, hardware interruptions can be registered multiple times without errors, but cannot work properly. In this caseWince 6.0Interrupt Driver AnalysisHas done analysis.
4.If there are no problems with the above steps, you need to consider whether the interrupt service routine has correctly handled the interrupt.