Symbian3/PDK/Source/GUID-124AC7EE-E227-5358-A755-628FFE257250.dita
changeset 1 25a17d01db0c
child 3 46218c8b8afa
equal deleted inserted replaced
0:89d6a7a84779 1:25a17d01db0c
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-124AC7EE-E227-5358-A755-628FFE257250" xml:lang="en"><title>HAL Handler
       
    13 Implementation</title><shortdesc>Describes how to implement or change a new HAL handler when you
       
    14 create a base port. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    15 <p>A HAL handler gets or sets hardware-specific settings, for example, the
       
    16 display contrast.</p>
       
    17 <p>A HAL handler is normally implemented in the kernel extension or a driver
       
    18 that provides the hardware-specific functionality. </p>
       
    19 <p>The easiest way to see the general pattern for implementing HAL handlers
       
    20 is to look at a real example. We will use the screen (i.e. video or LCD) driver
       
    21 for the template reference board, which is implemented in <filepath>...\template_variant\specific\lcd.cpp</filepath>. </p>
       
    22 <section id="GUID-B0EF5EC5-E7DA-5700-A187-4B8D14A3956A"><title>HAL handler
       
    23 function signature</title> <p>The HAL handler function has a signature that
       
    24 is defined by the <xref href="GUID-A65A16CA-488D-3A16-A034-F01C9C0B9D15.dita"><apiname>THalFunc</apiname></xref> typedef that is exported in <filepath>epoc32\include\kernel\kernel.h</filepath>. </p> <p>For
       
    25 example: </p> <codeblock id="GUID-0C6E606C-7916-50D3-8E89-D27BC3EB8C54" xml:space="preserve">TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)</codeblock> </section>
       
    26 <section id="GUID-217DAB35-D227-5FB7-8342-7EFD69E6CDBC"><title>Registering
       
    27 the HAL handler</title> <p>Before the handler can do anything, the extension
       
    28 or driver must register its handler for a specific HAL group. It does so by
       
    29 calling: </p> <codeblock id="GUID-0B935CC7-DA21-56A7-9BBE-F90B61EACDE0" xml:space="preserve">Kern::AddHalEntry(group, handler_func, ptr);</codeblock> <p>where: </p> <ul>
       
    30 <li id="GUID-17F56160-DFE5-5703-959F-EE93C748F74D"><p> <codeph>group</codeph> is
       
    31 the number of the <xref href="GUID-9AE254D4-AA60-579E-8D9D-F2797106A413.dita#GUID-9AE254D4-AA60-579E-8D9D-F2797106A413/GUID-366CC4B8-C6BD-5DCC-B55D-6D87CD5C8E64">HAL
       
    32 group attribute</xref> for which the HAL handler is being registered. </p> </li>
       
    33 <li id="GUID-C6D34824-AD21-514E-BC4E-EE1323E5A9C9"><p> <codeph>handler_func</codeph> is
       
    34 a pointer to the HAL handler function. </p> </li>
       
    35 <li id="GUID-195CE0E3-9658-51D4-B5FA-10B0263FBE60"><p> <codeph>ptr</codeph> is
       
    36 a pointer that is passed to the HAL handler function when it is called. This
       
    37 is usually a pointer to an object that can handle the specified HAL attribute. </p> </li>
       
    38 </ul> <p><note> A group can only have one handler, any attempt to register
       
    39 another handler returns an error. Typically, a driver will register its handler
       
    40 during its initialisation phase. </note></p> <p>Nearly all the functionality
       
    41 of the template screen driver is implemented in a single class, the LCD power
       
    42 handler object; its <codeph>DLcdPowerHandler::Create()</codeph> function is
       
    43 called as part of startup processing. It is this function that registers the
       
    44 HAL handler: </p> <codeblock id="GUID-09BCD8E9-60DB-5805-9A32-F5652C434AEE" xml:space="preserve">...
       
    45 // install the HAL function
       
    46 r=Kern::AddHalEntry(EHalGroupDisplay,halFunction,this);
       
    47 if (r!=KErrNone)
       
    48     return r;
       
    49 ...
       
    50 </codeblock> <p>Note that the third parameter is, in general, an optional
       
    51 pointer. It is a pointer to the current object, i.e. the <codeph>DLcdPowerHandler</codeph> object.
       
    52 It is this pointer that is passed on to the HAL handler function as its first
       
    53 argument. </p> </section>
       
    54 <section id="GUID-DAE573D1-EAA1-530F-93D4-0F4F8BC7EA60"><title>Common implementation
       
    55 pattern</title> <p>Using the template screen driver as an example, the driver
       
    56 provides the HAL handler for dealing with information related to the display
       
    57 HAL group, <xref href="GUID-7F299BFC-D8A5-3A5A-B8DA-39BF42C99DC6.dita"><apiname>EHalGroupDisplay</apiname></xref>. The HAL handler is the function: </p> <codeblock id="GUID-646A151D-79E3-54A8-8D52-D732C3E5F5AE" xml:space="preserve">LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
       
    58     {
       
    59     DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr;
       
    60     return pH-&gt;HalFunction(aFunction,a1,a2);
       
    61     }
       
    62 </codeblock> <p>This is a stand-alone function. The first parameter <codeph>aPtr</codeph> is
       
    63 the pointer that was originally passed to the kernel when the HAL handler
       
    64 was registered via the <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-8C8DCE9D-0094-3909-8FDA-2F3134D0BC88"><apiname>Kern::AddHalEntry()</apiname></xref> call, and in
       
    65 this case, points to the LCD's power handler object. In this example, the
       
    66 main implementation of the HAL handler is the member function <codeph>HalFunction()</codeph> of
       
    67 the <codeph>DLcdPowerHandler</codeph> instance. </p> <p>Whether you use this
       
    68 kind of technique depends on the way your drivers are implemented, but it
       
    69 is a pattern that is also used by the digitiser and the keyboard driver, as
       
    70 well as by the Symbian implemented HAL handlers. </p> <p>The other parameters
       
    71 passed to the HAL handler function, i.e. <codeph>aFunction</codeph>, <codeph>a1</codeph>,
       
    72 and <codeph>a2</codeph> are the ones passed into a call to <xref href="GUID-9EF04FB9-B36F-3A6F-AF3F-F2238BD181E9.dita#GUID-9EF04FB9-B36F-3A6F-AF3F-F2238BD181E9/GUID-7F07C14C-E69A-3277-8BFF-0CE2A820166D"><apiname>UserSvr::HalFunction()</apiname></xref>,
       
    73 which itself is called by the various accessor functions; see <xref href="GUID-9D4B8CDF-60D7-5952-AAAF-94A3C1E8908F.dita">the
       
    74 overall picture</xref>. </p> <p>It's useful to note that a single HAL handler
       
    75 may end up being called as a result of calls to different accessor functions.
       
    76 For example, <codeph>ProcessDisplayCurrentModeInfo()</codeph> and <codeph>GetBacklightPresent()</codeph> are
       
    77 accessor functions that result in a call to the screen driver's HAL handler. </p> <p>To
       
    78 further distinguish between the different characteristics represented by a
       
    79 group, each group has an associated set of function-ids. The function id is
       
    80 the second parameter passed to the HAL handler function, and the most common
       
    81 pattern for an implementation is to code a simple switch statement based on
       
    82 this value. For example, the function-ids associated with the <xref href="GUID-7F299BFC-D8A5-3A5A-B8DA-39BF42C99DC6.dita"><apiname>EHalGroupDisplay</apiname></xref> are
       
    83 represented by the set of enum values defined by the <xref href="GUID-BB011D9B-105F-345C-9FC0-39B0BA509394.dita"><apiname>TDisplayHalFunction</apiname></xref> enum.
       
    84 This is a fragment taken from the template screen driver: </p> <codeblock id="GUID-F1CA7147-4659-572E-8AEB-437B7E9CA2CF" xml:space="preserve">TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
       
    85     {
       
    86     TInt r=KErrNone;
       
    87     switch(aFunction)
       
    88         {
       
    89         case EDisplayHalScreenInfo:
       
    90             {
       
    91             TPckgBuf&lt;TScreenInfoV01&gt; vPckg;
       
    92             ScreenInfo(vPckg());
       
    93             Kern::InfoCopy(*(TDes8*)a1,vPckg);
       
    94             break;
       
    95             }
       
    96 
       
    97         case EDisplayHalWsRegisterSwitchOnScreenHandling:
       
    98             iWsSwitchOnScreen=(TBool)a1;
       
    99             break;
       
   100         
       
   101         case EDisplayHalWsSwitchOnScreen:
       
   102             WsSwitchOnScreen();
       
   103             break;
       
   104         
       
   105         case EDisplayHalMaxDisplayContrast:
       
   106             {
       
   107             TInt mc=KMaxDisplayContrast;
       
   108             kumemput32(a1,&amp;mc,sizeof(mc));
       
   109             break;
       
   110             }
       
   111         ...
       
   112         default:
       
   113             r=KErrNotSupported;
       
   114             break;
       
   115         }
       
   116     ...
       
   117     }</codeblock> <p>If the HAL handler function does not deal with a specific
       
   118 function-id, then it returns <codeph>KErrNotSupported</codeph>. </p> <p>The
       
   119 meaning of the parameters <codeph>a1</codeph> and <codeph>a2</codeph> passed
       
   120 to the HAL handler depends on the group and function-id; see the list: <xref href="GUID-857F981E-711B-5CA8-AB37-5C700A6140FA.dita">groups and the location of
       
   121 their HAL handlers</xref> and <xref href="GUID-E49A8036-EACF-5181-91DA-AE89D3B6E815.dita">Cross
       
   122 reference: attribute --&gt; group/function-id/capabilities</xref> for the full
       
   123 detail. </p> <p id="GUID-D75D3A65-590D-5716-84A7-0195DFCD1656"><b>Dealing with the HAL::GetAll()
       
   124 function</b> </p> <p>Calls that come through the <xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-EF03B832-E9AA-32CF-903F-DFFA63A3E9AB"><apiname>HAL::GetAll()</apiname></xref> function
       
   125 must be dealt with by the HAL handler implementation in a particular way. </p> <p> <codeph>GetAll()</codeph> calls
       
   126 the HAL handler and passes -1. The HAL handler must return the HAL attribute
       
   127 value when it is passed a -1 as its parameter unless the handler requires
       
   128 additional parameters. If the handler expects more than one parameter then
       
   129 it must return the error code <codeph>KErrArgument</codeph>. </p> <p>For example,
       
   130 using a <xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-573C49D6-7763-37AE-B2B2-4C8FB1327E21"><apiname>HAL::Get()</apiname></xref> request with the attribute <xref href="GUID-DEEDAD63-57EB-3FFC-9D1C-5AD32C424879.dita"><apiname>EDisplayBrightness</apiname></xref> returns
       
   131 the brightness for the <i>specified</i> device (screen). </p> <codeblock id="GUID-27357ABD-D38C-5B09-85B7-3B33440FC911" xml:space="preserve">HALArg = 0;
       
   132 ret = HAL::Get(screen, HAL::EDisplayBrightness, HALArg);</codeblock> <p>The
       
   133 information cannot be retrieved by the <codeph>GetAll()</codeph> function. </p> <p>When
       
   134 the HAL handler is expecting a value that specifies a particular mode or setting
       
   135 but receives a -1 the HAL handler must return the error code <xref href="GUID-0BEA3647-7888-3612-A2D3-7E27AC405E29.dita"><apiname>KErrArgument</apiname></xref> to
       
   136 indicate that an additional parameter was expected. </p><p>See <xref href="GUID-85AB6B6F-216E-3716-8A86-D0C44EE8008E.dita"><apiname>&gt;THalImplementation</apiname></xref> and <xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-EF03B832-E9AA-32CF-903F-DFFA63A3E9AB"><apiname>HAL::GetAll()</apiname></xref>.</p> </section>
       
   137 <section id="GUID-01D6179B-F1B6-5186-A96E-A1A5EDDC7A7A"><title>Context of
       
   138 the call to the HAL handler</title> <p>The HAL handler itself is only called
       
   139 by the kernel, and is the end result of a sequence that starts either with
       
   140 a call to the user interface functions provided by the HAL class (<xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-9454F1B2-D525-3D6D-A872-C6457CACD4FC"><apiname>HAL::Set()</apiname></xref>, <xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-573C49D6-7763-37AE-B2B2-4C8FB1327E21"><apiname>HAL::Get()</apiname></xref> or <xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-EF03B832-E9AA-32CF-903F-DFFA63A3E9AB"><apiname>HAL::GetAll()</apiname></xref>), or with a call to the kernel side <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-DA115709-A225-3E2A-BCCD-6E2BB15979B9"><apiname>Kern::HalFunction()</apiname></xref>. </p> <p>The
       
   141 handler runs on the kernel side in the context of the calling thread with
       
   142 no kernel mutexes or fast mutexes held; the calling thread is not placed into
       
   143 a critical section. It is the responsibility of the handler to do any thread
       
   144 synchronisation required. The handler returns a <xref href="GUID-7A2A43EC-6125-3BFE-834B-23C37F7B40D5.dita"><apiname>TInt</apiname></xref>, which
       
   145 is passed back to the user side, or the caller of <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-DA115709-A225-3E2A-BCCD-6E2BB15979B9"><apiname>Kern::HalFunction()</apiname></xref>. </p> </section>
       
   146 <section id="GUID-9C3570E1-50F6-5178-B9A1-99BCBB01ECA3"><title>Platform security</title> <p>If
       
   147 you are providing or porting a HAL handler, you need to be aware of platform
       
   148 security issues. In principle, for each call into the HAL handler, you need
       
   149 to check the capabilities of the caller's process. </p> <p>Recall that <xref href="GUID-9AE254D4-AA60-579E-8D9D-F2797106A413.dita#GUID-9AE254D4-AA60-579E-8D9D-F2797106A413/GUID-366CC4B8-C6BD-5DCC-B55D-6D87CD5C8E64">function-ids</xref> are
       
   150 used to distinguish between the different requests made on a given HAL handler.
       
   151 Different requests may require different capabilities, although many requests
       
   152 require no special capabilities. This means that each function-id is associated
       
   153 with a capability, and means that code that is dealing with a request associated
       
   154 with a specific function-id, must check the associated capability. </p> <p>For
       
   155 example, the screen (i.e. video or LCD) driver must check that the caller
       
   156 has the <xref href="GUID-C607209F-6FC5-31DE-8034-E5B799B857A8.dita"><apiname>ECapabilityWriteDeviceData</apiname></xref> capability before proceeding
       
   157 with a request to set the device's backlight on. This is a capability that
       
   158 grants write access to settings that control the behaviour of the device. </p> <codeblock id="GUID-AC4567DA-400E-53FB-8D90-E3D537AF68A3" xml:space="preserve">TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
       
   159     {
       
   160     TInt r=KErrNone;
       
   161     switch(aFunction)
       
   162         {
       
   163         ...
       
   164         case EDisplayHalSetBacklightOn:
       
   165         if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn")))
       
   166             {
       
   167             return KErrPermissionDenied;
       
   168             )
       
   169         ...
       
   170         break;
       
   171         ...
       
   172     }</codeblock> <p>To find the capabilities associated with function-ids,
       
   173 see the <xref href="GUID-E49A8036-EACF-5181-91DA-AE89D3B6E815.dita">HAL Attributes
       
   174 and Related Function IDs Tables</xref> section. Capabilities are documented
       
   175 as part of the API reference for each function-id. </p> </section>
       
   176 </conbody></concept>