Symbian3/PDK/Source/GUID-2E42E7EA-FED8-522C-8A5F-F65D799476C9.dita
changeset 14 578be2adaf3e
parent 5 f345bda72bc4
equal deleted inserted replaced
13:48780e181b38 14:578be2adaf3e
     7     Nokia Corporation - initial contribution.
     7     Nokia Corporation - initial contribution.
     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 Driver Implementation Tutorial</title><shortdesc>This topic describes how to implement an interrupt driven
    13 Driver Implementation Tutorial</title><prolog><metadata><keywords/></metadata></prolog><conbody>
    13 keyboard driver. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
    14 <p>This topic describes how to implement an interrupt driven keyboard driver. </p>
       
    15 <p>The steps are: </p>
    14 <p>The steps are: </p>
    16 <ul>
    15 <ul>
    17 <li id="GUID-BC3A7259-A750-5D5F-8363-6F8BBC03E8EB"><p>Implement the driver
    16 <li id="GUID-BC3A7259-A750-5D5F-8363-6F8BBC03E8EB"><p>Implement the
    18 entry point function and initialisation code. This function is called when
    17 driver entry point function and initialisation code. This function
    19 the extension is loaded. </p> <p>The initialisation code binds the hardware
    18 is called when the extension is loaded. </p> <p>The initialisation
    20 interrupt to the Interrupt Service Routine (ISR) and enables the interrupt. </p> </li>
    19 code binds the hardware interrupt to the Interrupt Service Routine
    21 <li id="GUID-3A050F21-FE10-5C0F-8BFE-C44692C0BDE2"><p>Implement an ISR to
    20 (ISR) and enables the interrupt. </p> </li>
    22 handle key events. The ISR queues a keyboard DFC. </p> </li>
    21 <li id="GUID-3A050F21-FE10-5C0F-8BFE-C44692C0BDE2"><p>Implement an
    23 <li id="GUID-6580FC61-3D9E-5370-88AD-50CC1FB28E5F"><p>Implement a keyboard
    22 ISR to handle key events. The ISR queues a keyboard DFC. </p> </li>
    24 DFC. This function interrogates the keyboard, converts the scancode to a keypress
    23 <li id="GUID-6580FC61-3D9E-5370-88AD-50CC1FB28E5F"><p>Implement a
    25 event, and places it onto the kernel's event queue. </p> </li>
    24 keyboard DFC. This function interrogates the keyboard, converts the
       
    25 scancode to a keypress event, and places it onto the kernel's event
       
    26 queue. </p> </li>
    26 </ul>
    27 </ul>
    27 <section id="GUID-B4B6A6C6-39D0-49FC-A630-1979368056B0"><title>Set Up</title> <p>In
    28 <section id="GUID-B4B6A6C6-39D0-49FC-A630-1979368056B0"><title>Set
    28 the template reference board port, the <filepath>.mmp</filepath> file for
    29 Up</title> <p>In the template reference board port, the <filepath>.mmp</filepath> file for the keyboard driver is <filepath>...\template_variant\exkey_inttemplate.mmp</filepath>. This is one of the PRJ_MMPFILES referenced in the template variant's <filepath>bld.inf</filepath> file in the <filepath>...\template_variant\...</filepath> directory, and means that the keyboard driver is built as part of
    29 the keyboard driver is <filepath>...\template_variant\exkey_inttemplate.mmp</filepath>.
    30 the Variant. </p> <p>The source for the driver is contained entirely
    30 This is one of the PRJ_MMPFILES referenced in the template variant's <filepath>bld.inf</filepath> file
    31 within <filepath>...\template_variant\specific\keyboard_interrupt.cpp</filepath>. </p> <p>The driver is defined as a kernel extension and is loaded
    31 in the <filepath>...\template_variant\...</filepath> directory, and means
    32 early in the boot sequence. </p> </section>
    32 that the keyboard driver is built as part of the Variant. </p> <p>The source
    33 <section id="GUID-547A2791-82D8-4C86-86E6-B4B9CEF04E3B"><title>Entry
    33 for the driver is contained entirely within <filepath>...\template_variant\specific\keyboard_interrupt.cpp</filepath>. </p> <p>The
    34 point implementation</title> <p>The driver functionality is encapsulated
    34 driver is defined as a kernel extension and is loaded early in the boot sequence. </p> </section>
    35 by the <codeph>DKeyboardTemplate</codeph> class, and an instance of
    35 <section id="GUID-547A2791-82D8-4C86-86E6-B4B9CEF04E3B"><title>Entry point
    36 this is created when the extension is loaded. </p> <p>As the driver
    36 implementation</title> <p>The driver functionality is encapsulated by the <codeph>DKeyboardTemplate</codeph> class,
    37 is a kernel extension, it must have a <codeph>DECLARE_STANDARD_EXTENSION()</codeph> statement. In the template port, this is implemented: </p> <codeblock id="GUID-69F707CF-642D-5D03-AC78-4914549C4413" xml:space="preserve">DECLARE_STANDARD_EXTENSION()
    37 and an instance of this is created when the extension is loaded. </p> <p>As
       
    38 the driver is a kernel extension, it must have a <codeph>DECLARE_STANDARD_EXTENSION()</codeph> statement.
       
    39 In the template port, this is implemented: </p> <codeblock id="GUID-69F707CF-642D-5D03-AC78-4914549C4413" xml:space="preserve">DECLARE_STANDARD_EXTENSION()
       
    40     {
    38     {
    41     __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver"));
    39     __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver"));
    42 
    40 
    43     // create keyboard driver
    41     // create keyboard driver
    44     TInt r=KErrNoMemory;
    42     TInt r=KErrNoMemory;
    48 
    46 
    49     __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r));
    47     __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r));
    50     return r;
    48     return r;
    51     }
    49     }
    52 
    50 
    53 </codeblock> <p>It simply creates an instance of the <codeph>DKeyboardTemplate</codeph> class
    51 </codeblock> <p>It simply creates an instance of the <codeph>DKeyboardTemplate</codeph> class and then performs a second-phase initialisation, which is
    54 and then performs a second-phase initialisation, which is a common pattern
    52 a common pattern in Symbian platform and third party applications. </p> <p><b>Initialisation on construction</b> </p> <p>The constructor
    55 in Symbian platform and third party applications. </p> <p><b>Initialisation
    53 of the <codeph>DKeyboardTemplate</codeph> class has the following
    56 on construction</b> </p> <p>The constructor of the <codeph>DKeyboardTemplate</codeph> class
    54 signature: </p> <codeblock id="GUID-5D247843-FF8C-5157-8BE5-53B5883F00B2" xml:space="preserve">DKeyboardTemplate::DKeyboardTemplate()
    57 has the following signature: </p> <codeblock id="GUID-5D247843-FF8C-5157-8BE5-53B5883F00B2" xml:space="preserve">DKeyboardTemplate::DKeyboardTemplate()
       
    58     :    DPowerHandler(KLitKeyboard), 
    55     :    DPowerHandler(KLitKeyboard), 
    59         iMsgQ(rxMsg,this,NULL,1),
    56         iMsgQ(rxMsg,this,NULL,1),
    60         iPowerUpDfc(PowerUpDfcFn,this,6),
    57         iPowerUpDfc(PowerUpDfcFn,this,6),
    61         iPowerDownDfc(PowerDownDfcFn,this,7),
    58         iPowerDownDfc(PowerDownDfcFn,this,7),
    62         iEventDfc(EventDfcFn,this,1)
    59         iEventDfc(EventDfcFn,this,1)
    63     {
    60     {
    64     }
    61     }
    65 
    62 
    66 </codeblock> <p>See also <xref href="GUID-3C34724F-B476-5329-B0B1-6D5A34294979.dita">Interrupt
    63 </codeblock> <p>See also <xref href="GUID-3C34724F-B476-5329-B0B1-6D5A34294979.dita">Interrupt Dispatcher
    67 Dispatcher Tutorial</xref>. </p> </section>
    64 Tutorial</xref>. </p> </section>
    68 <section id="GUID-F11265AA-D280-4B4E-92DA-38F12E7D5E30"><title> Interrupt
    65 <section id="GUID-F11265AA-D280-4B4E-92DA-38F12E7D5E30"><title> Interrupt
    69 Service Routine (ISR) implementation</title> <p>The ISR (Interrupt Service
    66 Service Routine (ISR) implementation</title> <p>The ISR (Interrupt
    70 Routine) just schedules the DFC that handles the keypress. It can also optionally
    67 Service Routine) just schedules the DFC that handles the keypress.
    71 contribute the timing of key interrupts as a source of random data for the
    68 It can also optionally contribute the timing of key interrupts as
    72 Random Number Generator (see <xref href="GUID-8290AAF0-577C-51D2-8AC1-0D37A10F45CB.dita">CSPRNG
    69 a source of random data for the Random Number Generator (see <xref href="GUID-8290AAF0-577C-51D2-8AC1-0D37A10F45CB.dita">CSPRNG Implementation
    73 Implementation in Kernel</xref>). On the template reference board, this is
    70 in Kernel</xref>). On the template reference board, this is implemented
    74 implemented as: </p> <codeblock id="GUID-866CEA65-78AC-5A2C-AF08-29DF8FE53DD5" xml:space="preserve">void DKeyboardTemplate::Isr(TAny* aPtr)
    71 as: </p> <codeblock id="GUID-866CEA65-78AC-5A2C-AF08-29DF8FE53DD5" xml:space="preserve">void DKeyboardTemplate::Isr(TAny* aPtr)
    75 	{
    72 	{
    76 	Interrupt::Disable(KIntIdKeyboard);
    73 	Interrupt::Disable(KIntIdKeyboard);
    77 	
    74 	
    78 	// Add the timing of key interrupts as entropy data for the RNG
    75 	// Add the timing of key interrupts as entropy data for the RNG
    79 	Interrupt::AddTimingEntropy();
    76 	Interrupt::AddTimingEntropy();
    80 	
    77 	
    81 	k.iEventDfc.Add();
    78 	k.iEventDfc.Add();
    82 	}
    79 	}
    83 </codeblock> <p>The ISR disables the keyboard interrupt, as repeated ISRs
    80 </codeblock> <p>The ISR disables the keyboard interrupt, as repeated
    84 are not allowed to queue further DFC routines. </p> </section>
    81 ISRs are not allowed to queue further DFC routines. </p> </section>
    85 <section id="GUID-E53E0FE1-3100-4B8B-BE90-250C1BDDE15C"><title>DFC function
    82 <section id="GUID-E53E0FE1-3100-4B8B-BE90-250C1BDDE15C"><title>DFC
    86 implementation</title> <p>The DFC is the function <codeph>DKeyboardTemplate::EventDfcFn</codeph> which
    83 function implementation</title> <p>The DFC is the function <codeph>DKeyboardTemplate::EventDfcFn</codeph> which is implemented as a
    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)
    84 call to <codeph>DKeyboardTemplate::EventDfc()</codeph>. </p> <codeblock id="GUID-2A1B334A-441E-57C3-B40C-603D992F934F" xml:space="preserve">void DKeyboardTemplate::EventDfcFn(TAny* aPtr)
    88     {
    85     {
    89     ((DKeyboardTemplate*)aPtr)-&gt;EventDfc();
    86     ((DKeyboardTemplate*)aPtr)-&gt;EventDfc();
    90     }
    87     }
    91 
    88 
    92 void DKeyboardTemplate::EventDfc()
    89 void DKeyboardTemplate::EventDfc()
   118         irq=NKern::DisableAllInterrupts();
   115         irq=NKern::DisableAllInterrupts();
   119         }
   116         }
   120     Interrupt::Enable(KIntIdKeyboard);
   117     Interrupt::Enable(KIntIdKeyboard);
   121     NKern::RestoreInterrupts(irq);
   118     NKern::RestoreInterrupts(irq);
   122     }</codeblock> <p>This: </p> <ul>
   119     }</codeblock> <p>This: </p> <ul>
   123 <li id="GUID-8A202894-34F8-5E7B-B791-20D4B6C8B914"><p>reads the scan code
   120 <li id="GUID-8A202894-34F8-5E7B-B791-20D4B6C8B914"><p>reads the scan
   124 data by calling <codeph>DKeyboardTemplate::GetKeyCode()</codeph>  </p> </li>
   121 code data by calling <codeph>DKeyboardTemplate::GetKeyCode()</codeph>  </p> </li>
   125 <li id="GUID-D553B662-F60C-575F-893D-347A9344F9B9"><p>re-enables the keyboard
   122 <li id="GUID-D553B662-F60C-575F-893D-347A9344F9B9"><p>re-enables the
   126 interrupt, now that the DFC has freed up the input data register </p> </li>
   123 keyboard interrupt, now that the DFC has freed up the input data register </p> </li>
   127 <li id="GUID-BFC75E95-A9AE-584E-8A17-CCAF9C2F5913"><p>translates the keypress
   124 <li id="GUID-BFC75E95-A9AE-584E-8A17-CCAF9C2F5913"><p>translates the
   128 event into a Symbian scancode </p> </li>
   125 keypress event into a Symbian scancode </p> </li>
   129 <li id="GUID-20BC22AF-C58C-56DC-B777-B5C8681668D6"><p>puts the translated
   126 <li id="GUID-20BC22AF-C58C-56DC-B777-B5C8681668D6"><p>puts the translated
   130 event on to the event queue. </p> </li>
   127 event on to the event queue. </p> </li>
   131 </ul> </section>
   128 </ul> </section>
   132 <section id="GUID-437735D9-916C-4308-913C-3839CC7F0002"><title>See also</title> <p> <xref href="GUID-EB76FAF8-CD4B-5CB6-9F23-C852ED91866F.dita">Concepts</xref>  </p> </section>
   129 <section id="GUID-437735D9-916C-4308-913C-3839CC7F0002"><title>See
       
   130 also</title> <p> <xref href="GUID-EB76FAF8-CD4B-5CB6-9F23-C852ED91866F.dita">Concepts</xref>  </p> </section>
   133 </conbody></concept>
   131 </conbody></concept>