|
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& 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->iDevHandle) |
|
117 { |
|
118 // device driver handle already open |
|
119 aDevice.SetHandle(pH->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->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& 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->iSvrHandle) |
|
179 { |
|
180 // server handle already open |
|
181 aServer.SetHandle(pH->iSvrHandle); |
|
182 return KErrNone; |
|
183 } |
|
184 TInt r=aServer.Connect(); // create session with server |
|
185 if (r==KErrNone) |
|
186 { |
|
187 pH->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> |