8 Contributors: |
8 Contributors: |
9 --> |
9 --> |
10 <!DOCTYPE concept |
10 <!DOCTYPE concept |
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
12 <concept id="GUID-2E42E7EA-FED8-522C-8A5F-F65D799476C9" xml:lang="en"><title>Keyboard |
12 <concept id="GUID-2E42E7EA-FED8-522C-8A5F-F65D799476C9" xml:lang="en"><title>Keyboard |
13 Driver Implementation Tutorial</title><shortdesc/><prolog><metadata><keywords/></metadata></prolog><conbody> |
13 Driver Implementation Tutorial</title><prolog><metadata><keywords/></metadata></prolog><conbody> |
14 <p>This topic describes how to implement an interrupt driven keyboard driver. </p> |
14 <p>This topic describes how to implement an interrupt driven keyboard driver. </p> |
15 <p>The steps are: </p> |
15 <p>The steps are: </p> |
16 <ul> |
16 <ul> |
17 <li id="GUID-BC3A7259-A750-5D5F-8363-6F8BBC03E8EB"><p>Implement the driver |
17 <li id="GUID-BC3A7259-A750-5D5F-8363-6F8BBC03E8EB"><p>Implement the driver |
18 entry point function and initialisation code. This function is called when |
18 entry point function and initialisation code. This function is called when |
22 handle key events. The ISR queues a keyboard DFC. </p> </li> |
22 handle key events. The ISR queues a keyboard DFC. </p> </li> |
23 <li id="GUID-6580FC61-3D9E-5370-88AD-50CC1FB28E5F"><p>Implement a keyboard |
23 <li id="GUID-6580FC61-3D9E-5370-88AD-50CC1FB28E5F"><p>Implement a keyboard |
24 DFC. This function interrogates the keyboard, converts the scancode to a keypress |
24 DFC. This function interrogates the keyboard, converts the scancode to a keypress |
25 event, and places it onto the kernel's event queue. </p> </li> |
25 event, and places it onto the kernel's event queue. </p> </li> |
26 </ul> |
26 </ul> |
27 <section id="GUID-B4B6A6C6-39D0-49FC-A630-1979368056B0"><title>Set Up</title> <p>In the template reference board port, the <filepath>.mmp</filepath> file |
27 <section id="GUID-B4B6A6C6-39D0-49FC-A630-1979368056B0"><title>Set Up</title> <p>In |
28 for the keyboard driver is <filepath>...\template_variant\exkey_inttemplate.mmp</filepath>. |
28 the template reference board port, the <filepath>.mmp</filepath> file for |
|
29 the keyboard driver is <filepath>...\template_variant\exkey_inttemplate.mmp</filepath>. |
29 This is one of the PRJ_MMPFILES referenced in the template variant's <filepath>bld.inf</filepath> file |
30 This is one of the PRJ_MMPFILES referenced in the template variant's <filepath>bld.inf</filepath> file |
30 in the <filepath>...\template_variant\...</filepath> directory, and means |
31 in the <filepath>...\template_variant\...</filepath> directory, and means |
31 that the keyboard driver is built as part of the Variant. </p> <p>The source |
32 that the keyboard driver is built as part of the Variant. </p> <p>The source |
32 for the driver is contained entirely within <filepath>...\template_variant\specific\keyboard_interrupt.cpp</filepath>. </p> <p>The |
33 for the driver is contained entirely within <filepath>...\template_variant\specific\keyboard_interrupt.cpp</filepath>. </p> <p>The |
33 driver is defined as a kernel extension and is loaded early in the boot sequence. </p> </section> |
34 driver is defined as a kernel extension and is loaded early in the boot sequence. </p> </section> |
34 <section id="GUID-547A2791-82D8-4C86-86E6-B4B9CEF04E3B"><title>Entry point implementation</title> <p>The driver functionality |
35 <section id="GUID-547A2791-82D8-4C86-86E6-B4B9CEF04E3B"><title>Entry point |
35 is encapsulated by the <codeph>DKeyboardTemplate</codeph> class, and an instance |
36 implementation</title> <p>The driver functionality is encapsulated by the <codeph>DKeyboardTemplate</codeph> class, |
36 of this is created when the extension is loaded. </p> <p>As the driver is |
37 and an instance of this is created when the extension is loaded. </p> <p>As |
37 a kernel extension, it must have a <codeph>DECLARE_STANDARD_EXTENSION()</codeph> statement. |
38 the driver is a kernel extension, it must have a <codeph>DECLARE_STANDARD_EXTENSION()</codeph> statement. |
38 In the template port, this is implemented: </p> <codeblock id="GUID-69F707CF-642D-5D03-AC78-4914549C4413" xml:space="preserve">DECLARE_STANDARD_EXTENSION() |
39 In the template port, this is implemented: </p> <codeblock id="GUID-69F707CF-642D-5D03-AC78-4914549C4413" xml:space="preserve">DECLARE_STANDARD_EXTENSION() |
39 { |
40 { |
40 __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver")); |
41 __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver")); |
41 |
42 |
42 // create keyboard driver |
43 // create keyboard driver |
62 { |
63 { |
63 } |
64 } |
64 |
65 |
65 </codeblock> <p>See also <xref href="GUID-3C34724F-B476-5329-B0B1-6D5A34294979.dita">Interrupt |
66 </codeblock> <p>See also <xref href="GUID-3C34724F-B476-5329-B0B1-6D5A34294979.dita">Interrupt |
66 Dispatcher Tutorial</xref>. </p> </section> |
67 Dispatcher Tutorial</xref>. </p> </section> |
67 <section id="GUID-F11265AA-D280-4B4E-92DA-38F12E7D5E30"><title> Interrupt Service Routine (ISR) implementation</title> <p>The |
68 <section id="GUID-F11265AA-D280-4B4E-92DA-38F12E7D5E30"><title> Interrupt |
68 ISR (Interrupt Service Routine) just schedules the DFC that handles the keypress. |
69 Service Routine (ISR) implementation</title> <p>The ISR (Interrupt Service |
69 On the template reference board, this is implemented as: </p> <codeblock id="GUID-866CEA65-78AC-5A2C-AF08-29DF8FE53DD5" xml:space="preserve">void DKeyboardTemplate::Isr(TAny* aPtr) |
70 Routine) just schedules the DFC that handles the keypress. It can also optionally |
70 { |
71 contribute the timing of key interrupts as a source of random data for the |
71 DKeyboardTemplate& k=*(DKeyboardTemplate*)aPtr; |
72 Random Number Generator (see <xref href="GUID-8290AAF0-577C-51D2-8AC1-0D37A10F45CB.dita">CSPRNG |
72 Interrupt::Disable(KIntIdKeyboard); |
73 Implementation in Kernel</xref>). On the template reference board, this is |
73 k.iEventDfc.Add(); |
74 implemented as: </p> <codeblock id="GUID-866CEA65-78AC-5A2C-AF08-29DF8FE53DD5" xml:space="preserve">void DKeyboardTemplate::Isr(TAny* aPtr) |
74 } |
75 { |
|
76 Interrupt::Disable(KIntIdKeyboard); |
|
77 |
|
78 // Add the timing of key interrupts as entropy data for the RNG |
|
79 Interrupt::AddTimingEntropy(); |
|
80 |
|
81 k.iEventDfc.Add(); |
|
82 } |
75 </codeblock> <p>The ISR disables the keyboard interrupt, as repeated ISRs |
83 </codeblock> <p>The ISR disables the keyboard interrupt, as repeated ISRs |
76 are not allowed to queue further DFC routines. </p> </section> |
84 are not allowed to queue further DFC routines. </p> </section> |
77 <section id="GUID-E53E0FE1-3100-4B8B-BE90-250C1BDDE15C"><title>DFC function implementation</title> <p>The DFC is the function <codeph>DKeyboardTemplate::EventDfcFn</codeph> which |
85 <section id="GUID-E53E0FE1-3100-4B8B-BE90-250C1BDDE15C"><title>DFC function |
|
86 implementation</title> <p>The DFC is the function <codeph>DKeyboardTemplate::EventDfcFn</codeph> which |
78 is implemented as a call to <codeph>DKeyboardTemplate::EventDfc()</codeph>. </p> <codeblock id="GUID-2A1B334A-441E-57C3-B40C-603D992F934F" xml:space="preserve">void DKeyboardTemplate::EventDfcFn(TAny* aPtr) |
87 is implemented as a call to <codeph>DKeyboardTemplate::EventDfc()</codeph>. </p> <codeblock id="GUID-2A1B334A-441E-57C3-B40C-603D992F934F" xml:space="preserve">void DKeyboardTemplate::EventDfcFn(TAny* aPtr) |
79 { |
88 { |
80 ((DKeyboardTemplate*)aPtr)->EventDfc(); |
89 ((DKeyboardTemplate*)aPtr)->EventDfc(); |
81 } |
90 } |
82 |
91 |