Adaptation/GUID-A7ECF51F-F96A-5251-A71F-2F269C8C0664.dita
changeset 15 307f4279f433
equal deleted inserted replaced
14:578be2adaf3e 15:307f4279f433
       
     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-A7ECF51F-F96A-5251-A71F-2F269C8C0664" xml:lang="en"><title>Accessor
       
    13 Functions for Derived Attributes</title><shortdesc>Explains how to add accessor functions for derived attributes.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    14 <p>You can change HAL to add accessor functions for new derived attributes.
       
    15 This step is not often done, because all normal accessor functions are already
       
    16 defined in <filepath>...\hal\src\userhal.cpp</filepath>. </p>
       
    17 <p>Each derived attribute is declared with an associated function name in <xref href="GUID-52583CC7-483E-54B5-8094-F0F61BD46B7F.dita#GUID-52583CC7-483E-54B5-8094-F0F61BD46B7F/GUID-8648B87A-B712-5458-850A-FDF318669FE3">Config
       
    18 file</xref>. A function with that name must be provided, and it must have
       
    19 the following signature, which is also defined by the <xref href="GUID-0885487F-1482-3BD4-9EA8-9E9643125A0A.dita"><apiname>THalImplementation</apiname></xref> typedef: </p>
       
    20 <codeblock id="GUID-53946166-A153-57E1-8FAB-BB3870B0B829" xml:space="preserve">TInt Function(TInt aAttrib, TBool aSet, TAny* aInOut);</codeblock>
       
    21 <p>This function is called whenever any client of the HAL references the associated
       
    22 attribute. </p>
       
    23 <table id="GUID-2672A463-7AB1-504E-9D0C-2AA29757178A">
       
    24 <tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
       
    25 <tbody>
       
    26 <row>
       
    27 <entry><p> <codeph>aAttrib</codeph>  </p> </entry>
       
    28 <entry><p>Contains the attribute number. </p> </entry>
       
    29 </row>
       
    30 <row>
       
    31 <entry><p> <codeph>aSet</codeph>  </p> </entry>
       
    32 <entry><p>Defines whether the attribute is being set or being read: <xref href="GUID-781E8158-805B-3784-8FED-D7A191822FC3.dita"><apiname>ETrue</apiname></xref> means
       
    33 that the attribute value is being set; <xref href="GUID-A759CA2D-8327-348F-9337-4886E619D920.dita"><apiname>EFalse</apiname></xref> means that
       
    34 the attribute value is being read. </p> <p>Note that if the attribute, as
       
    35 defined in the <filepath>config.hcf</filepath> file, does not have the settable
       
    36 property, then <codeph>aSet</codeph> is ignored . </p> </entry>
       
    37 </row>
       
    38 <row>
       
    39 <entry><p> <codeph>aInOut</codeph>  </p> </entry>
       
    40 <entry><p>A pointer to a <xref href="GUID-7A2A43EC-6125-3BFE-834B-23C37F7B40D5.dita"><apiname>TInt</apiname></xref> type, that contains: </p> <ul>
       
    41 <li id="GUID-B7598EEB-4B73-5E51-8F92-EC527FCED605"><p>the attribute value
       
    42 to be set, if <codeph>aSet</codeph> is <xref href="GUID-781E8158-805B-3784-8FED-D7A191822FC3.dita"><apiname>ETrue</apiname></xref>  </p> </li>
       
    43 <li id="GUID-BEA21EED-2D95-5169-B09C-DD6CC7CE4507"><p>the attribute value
       
    44 to be read, if <codeph>aSet</codeph> is <xref href="GUID-A759CA2D-8327-348F-9337-4886E619D920.dita"><apiname>EFalse</apiname></xref>. </p> </li>
       
    45 </ul> </entry>
       
    46 </row>
       
    47 </tbody>
       
    48 </tgroup>
       
    49 </table>
       
    50 <p>Once the config file has been written, the Perl script <filepath>...\hal\group\halcfg.pl</filepath> can
       
    51 be used to generate a skeleton implementation file. For example, calling </p>
       
    52 <p><userinput>perl \hal\group\halcfg.pl -s \hal\inc\hal_data.h config.hcf
       
    53 imp.cpp</userinput> </p>
       
    54 <p>produces the file <filepath>imp.cpp</filepath> containing the following
       
    55 skeleton code for <i>each</i> derived attribute: </p>
       
    56 <codeblock id="GUID-EAA857F6-61FB-5FAE-815E-9B3601CF182C" xml:space="preserve">// EAttributeName
       
    57 TInt Function(TInt /*aAttrib*/, TBool /*aSet*/, TAny* aInOut)
       
    58     {
       
    59     return KErrNone;
       
    60     }
       
    61 </codeblock>
       
    62 <p>The full implementation for the function can now be written. </p>
       
    63 <p>Notes: </p>
       
    64 <ul>
       
    65 <li id="GUID-25545667-6870-5AAF-9271-D7402E9F777E"><p>The <codeph>aAttrib</codeph> parameter
       
    66 is always marked as a comment because it is not usually needed; it is only
       
    67 needed if the same function is used to implement more than one attribute. </p> </li>
       
    68 <li id="GUID-8DE7C359-AA59-5158-82BD-2184D874168C"><p>The <codeph>aSet</codeph> parameter
       
    69 is marked as a comment if the attribute does not have the <i>settable</i> property. </p> </li>
       
    70 <li id="GUID-27CE60FA-8104-511C-9FC2-3D4557D92BBC"><p>On some platforms it
       
    71 may be necessary to access some HAL attributes via a device driver or server,
       
    72 rather than using <codeph>UserSvr::HalFunction()</codeph> . In this case,
       
    73 a handle to the device driver or server must be opened on the first access.
       
    74 Use the <codeph>HalInternal::Tls()</codeph> function to do this. </p> </li>
       
    75 <li id="GUID-72462FB8-F607-56D8-9F0B-FD9980FDCEBD"><p>Access to any HAL attribute
       
    76 requiring the use of a server or device driver can fail due to lack of memory. </p> </li>
       
    77 </ul>
       
    78 <p>Thee code fragments in the <xref href="GUID-A7ECF51F-F96A-5251-A71F-2F269C8C0664.dita#GUID-A7ECF51F-F96A-5251-A71F-2F269C8C0664/GUID-61707920-B82E-5580-8821-4FD1DC3BE77A">example
       
    79 accessor functions</xref> show the cases where the HAL has an attribute that
       
    80 requires a device driver and another attribute that requires a server. </p>
       
    81 <p>See also <xref href="GUID-F8B8C030-B5E1-5EB3-A672-83BF35555801.dita">halcfg.pl
       
    82 Syntax</xref>. </p>
       
    83 <section id="GUID-61707920-B82E-5580-8821-4FD1DC3BE77A"><title>Example accessor
       
    84 functions for derived attributes using a device driver and a server</title> <p>This
       
    85 code fragment shows the implementation of accessor functions for two HAL derived
       
    86 attributes. One uses a device driver, and the other uses a server to provide
       
    87 the necessary functionality. </p> <p>The examples assume that the attributes
       
    88 are defined in the <filepath>config.hcf</filepath> file with function names <codeph>Attrib1</codeph> and <codeph>Attrib2</codeph>. </p> <p><b>Using a device driver</b> </p> <codeblock id="GUID-810DF0E3-4AE7-5FFC-8434-A845513BCC65" xml:space="preserve">TInt Attrib1(TInt /*aAttrib*/, TBool aSet, TAny* aInOut)
       
    89     {
       
    90        // Do something with the device driver
       
    91        RHwDevice d;
       
    92        TInt r=GetDeviceDriverHandle(d);
       
    93        if (r==KErrNone)
       
    94         {
       
    95         if (aSet)
       
    96             {
       
    97             r=d.Write((TInt)aInOut);
       
    98             }
       
    99         else
       
   100             {
       
   101             r=d.Read(*(TInt*)aInOut);
       
   102             }
       
   103          }
       
   104     return r;
       
   105     }</codeblock> <codeblock id="GUID-88E9FA83-D669-5073-B92A-48A22BFEC4B2" xml:space="preserve">TInt GetDeviceDriverHandle(RHwDevice&amp; aDevice)
       
   106     {
       
   107     // Return the device driver handle for this thread
       
   108     // If it doesn't exist, attempt to open a handle
       
   109     // Careful with OOM errors
       
   110 
       
   111     SHandles* pH=GetHandles();
       
   112     if (!pH)
       
   113         {
       
   114         return KErrNoMemory;    // couldn't allocate TLS memory
       
   115         }
       
   116     if (pH-&gt;iDevHandle)
       
   117         {
       
   118         // device driver handle already open
       
   119         aDevice.SetHandle(pH-&gt;iDevHandle);
       
   120         return KErrNone;
       
   121         }
       
   122 
       
   123     // note: Someone should have previously loaded the required
       
   124     // device driver.  Eg.
       
   125     // User::LoadLogicalDevice(_L("HARDWARE.LDD"));
       
   126     // This can be done here, but it is inefficient since it will
       
   127     // happen once per thread.  It's much better to do it once
       
   128     // at Hal start-up.
       
   129 
       
   130     TInt r=aDevice.Open();    // open handle to driver
       
   131     if (r==KErrNone)
       
   132         {
       
   133            pH-&gt;iDevHandle=aDevice.Handle();    // store handle
       
   134         }
       
   135     return r;
       
   136     }</codeblock> <codeblock id="GUID-264AF5EC-A4F3-5BA7-AC47-576C338D81F2" xml:space="preserve">struct SHandles
       
   137     {
       
   138     TInt iDevHandle;
       
   139     TInt iSvrHandle;
       
   140     };
       
   141 </codeblock> <codeblock id="GUID-7F5DC241-B4B1-501F-A7B6-0B864676A4A2" xml:space="preserve">SHandles* GetHandles()
       
   142     {
       
   143     // Return a pointer to the SHandles structure for this thread
       
   144     // If it doesn't exist, attempt to create it
       
   145 
       
   146     // This function zeros a newly allocated memory block
       
   147     return (SHandles*)HalInternal::Tls(sizeof(SHandles));
       
   148     }
       
   149 </codeblock> <p><b>Using
       
   150 a server</b> </p> <codeblock id="GUID-E0CB12CC-2F83-5AB6-B1F3-B494AD7346CB" xml:space="preserve">TInt Attrib2(TInt /*aAttrib*/, TBool aSet, TAny* aInOut)
       
   151     {
       
   152     // Do something with the server
       
   153     RHwServer s;
       
   154     TInt r=GetServerHandle(s);
       
   155     if (r==KErrNone)
       
   156         {
       
   157         if (aSet)
       
   158             {
       
   159             r=s.Write((TInt)aInOut);
       
   160             }
       
   161             else
       
   162             {
       
   163             r=s.Read(*(TInt*)aInOut);
       
   164             }
       
   165         }
       
   166     return r;
       
   167     }</codeblock> <codeblock id="GUID-C74F36A5-78CA-52A6-A8E9-6BEAAC7B9257" xml:space="preserve">TInt GetServerHandle(RHwServer&amp; aServer)
       
   168     {
       
   169     // Return the server handle for this thread
       
   170     // If it doesn't exist, attempt to open a handle
       
   171     // Careful with OOM errors
       
   172 
       
   173     SHandles* pH=GetHandles();
       
   174     if (!pH)
       
   175         {
       
   176         return KErrNoMemory;    // couldn't allocate TLS memory
       
   177         }
       
   178     if (pH-&gt;iSvrHandle)
       
   179         {
       
   180         // server handle already open
       
   181            aServer.SetHandle(pH-&gt;iSvrHandle);
       
   182            return KErrNone;
       
   183         }
       
   184     TInt r=aServer.Connect();    // create session with server
       
   185     if (r==KErrNone)
       
   186         {
       
   187         pH-&gt;iSvrHandle=aServer.Handle();    // store handle
       
   188         }
       
   189     return r;
       
   190     }</codeblock> <codeblock id="GUID-9527E73D-FAFA-519A-80F1-FD10E5AF3D40" xml:space="preserve">struct SHandles
       
   191     {
       
   192     TInt iDevHandle;
       
   193     TInt iSvrHandle;
       
   194     };
       
   195 </codeblock> <codeblock id="GUID-6C88ED9C-E8D1-5901-BE00-F52130F3509C" xml:space="preserve">SHandles* GetHandles()
       
   196     {
       
   197     // Return a pointer to the SHandles structure for this thread
       
   198     // If it doesn't exist, attempt to create it
       
   199 
       
   200     // This function zeros a newly allocated memory block
       
   201     return (SHandles*)HalInternal::Tls(sizeof(SHandles));
       
   202     }
       
   203 </codeblock> </section>
       
   204 </conbody></concept>