Adaptation/GUID-3B6544CD-FA6E-5AB2-AA63-61186F52167D.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-3B6544CD-FA6E-5AB2-AA63-61186F52167D" xml:lang="en"><title>Controllable
       
    13 Power Resources</title><shortdesc>This topic explains how power resources were controlled in older
       
    14 releases of Symbian platform. For later releases see the Power Resource Manager
       
    15 documentation.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    16 <p>This documentation is retained for reference for those working with hardware
       
    17 or software that is based on older versions of Symbian platform version (in
       
    18 particular old release 9.5). For later releases see the <xref href="GUID-2ECF13A1-9D56-5740-A09F-8267E6A45DD9.dita">Porting
       
    19 the Power Resource Manager</xref> documentation.</p>
       
    20 <p>Controllable power resources are defined as being any device resource,
       
    21 such as voltages on power-lines or clocks, which can be independently enabled,
       
    22 disabled or modified under software control. </p>
       
    23 <p>The following hardware block diagram is an example of the way power resources
       
    24 might be arranged: </p>
       
    25 <fig id="GUID-41113C18-2C87-5DEA-9D05-31083F51269A">
       
    26 <title>Example power resource arrangement</title>
       
    27 <image href="GUID-622D6337-E60A-5252-8B2B-BA8232927453_d0e29152_href.png" placement="inline"/>
       
    28 </fig>
       
    29 <p>There is no default support or default implementation for controllable
       
    30 power resources in the generic layers of Symbian platform. They must be managed
       
    31 by the base port. </p>
       
    32 <p>We suggest that the management of controllable power resources (the resource
       
    33 manager) be implemented in the Variant DLL or the ASSP DLL. This allows the
       
    34 resource manager to be up and running by the time peripheral drivers, which
       
    35 might also be kernel extensions, are loaded. See the <xref href="GUID-984C2A0D-36BE-5A99-9D65-3F8791C669FF.dita#GUID-984C2A0D-36BE-5A99-9D65-3F8791C669FF/GUID-95C34114-F986-5428-9D40-5CF64429CDBD">ASSP/Variant Architecture</xref> and the <xref href="GUID-ECAC3FF3-CDB2-5153-AD76-90732BA83726.dita#GUID-ECAC3FF3-CDB2-5153-AD76-90732BA83726/GUID-F55D88DB-7DE1-5069-BAE7-A7FE3750D065">ASSP/Variant
       
    36 Tutorials</xref>. </p>
       
    37 <p>A suggested implementation has the instance of the <xref href="GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D.dita"><apiname>Asic</apiname></xref> derived
       
    38 class owning a pointer to the resource manager object. The interface class
       
    39 for the ASSP or Variant could then have an exported or an inline member function
       
    40 to return a pointer to this resource manager object. Peripheral drivers are
       
    41 expected to link against either the ASSP DLL, or the Variant DLL, or both. </p>
       
    42 <p>For example, for a device that has a Variant and an ASSP: </p>
       
    43 <codeblock id="GUID-049CEE21-944A-589A-9F1B-8F031D681198" xml:space="preserve">class MyVariant : public MyASSP
       
    44     {
       
    45 public:
       
    46     Init1();
       
    47     Init3();
       
    48     // Other mandatory Asic-derived member functions
       
    49     ...
       
    50 public:
       
    51     ResourceManager* myResMgrPtr;
       
    52     ...
       
    53     };
       
    54       </codeblock>
       
    55 <p>where class <codeph>MyASSP</codeph> is derived from class <xref href="GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D.dita"><apiname>Asic</apiname></xref>. </p>
       
    56 <codeblock id="GUID-E8346FFB-1B0F-5482-9DF7-207B1B1948F8" xml:space="preserve">GLREF_D MyVariant TheVariant;</codeblock>
       
    57 <codeblock id="GUID-CEF1F0C7-62E4-52B1-9830-DBD32B2BE8CE" xml:space="preserve">class TMyVariant
       
    58     {
       
    59 public:
       
    60     inline static ResourceManager* ResourceManager()
       
    61         {return(TheVariant.myResMgrPtr);}
       
    62     // other exported methods
       
    63     ...
       
    64     };
       
    65       </codeblock>
       
    66 <p>where <codeph>TMyvariant</codeph> is the Variant interface class, and <codeph>ResourceManager</codeph> is
       
    67 the resource manager class. </p>
       
    68 <p>The resource manager can be declared as a global object at the Variant
       
    69 (or ASSP) scope and can therefore be created when this component is first
       
    70 loaded. In this case, the <xref href="GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D.dita#GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D/GUID-FE55E398-7F08-384F-9E74-2CC2E45002B6"><apiname>Asic::Init3()</apiname></xref> function would
       
    71 initialise the <codeph>ResourceManager</codeph> object, and set up <codeph>myResMgrPtr</codeph>.
       
    72 Alternatively, if the Variant (or ASSP) were to need the resource manager
       
    73 up and running, then you would initialise <codeph>ResourceManager</codeph> in <xref href="GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D.dita#GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D/GUID-63F2135B-4264-3B3B-9B68-656A89BF7EE9"><apiname>Asic::Init1()</apiname></xref>. </p>
       
    74 <p>In this implementation, the Variant would export a header file(s) publishing
       
    75 a list of controllable power resources. </p>
       
    76 <section id="GUID-CC741BCC-D96E-4FB7-AA8C-7635D4131DE0"><title>Shared controllable
       
    77 power resources</title> <p>Some controllable power resources can be shared
       
    78 between groups of peripherals and therefore may require usage tracking. </p> <p>We
       
    79 recommend that shared power resources be represented by a class derived from <xref href="GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A.dita"><apiname>MPowerInput</apiname></xref>.
       
    80 This class offers the <codeph>Use()</codeph> and <codeph>Release()</codeph> interface
       
    81 that encapsulates resource counting behaviour. This mechanism should turn
       
    82 the resource on when the count becomes non-zero, and turn the resource off
       
    83 when the count becomes zero. </p> <p>We suggest that your <xref href="GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A.dita"><apiname>MPowerInput</apiname></xref> derived
       
    84 class defines and implements a <codeph>GetCount()</codeph> function that returns
       
    85 the usage count on the shared resource. </p> </section>
       
    86 <section id="GUID-37A4098A-5E44-5744-BCE1-CDC8B876E654"><title>A suggested
       
    87 implementation of a resource manager</title> <p>While we have implied that
       
    88 a resource manager is a single class, which we have called <codeph>ResourceManager</codeph>,
       
    89 the resource manager is a notional concept for controlling power resources. <i>Symbian
       
    90 neither mandates a format for a ResourceManager class, nor even its existence</i>.
       
    91 In practice, it may be more useful to embed resource manager functions and
       
    92 data in the Variant interface class (or the ASSP interface class, if appropriate). </p> <p>However,
       
    93 for the purpose of explaining what a resource manager can do, it is easier
       
    94 to assume that this behaviour is handled by a resource manager class. This
       
    95 is the outline definition of such a class. </p> <codeblock id="GUID-BB326270-B8C6-5398-AB36-FA50011004CA" xml:space="preserve">class ResourceManager
       
    96     {
       
    97 public:    
       
    98     void InitResources();                            // called by your Asic::Init3()/Asic::Init1()
       
    99     void Modify(TUint aSetMask, TUint aClrMask);    // only 32 simple Resources can be managed
       
   100     TBool GetResourceState(TUint aResBitMask);    // only 1 bit set on this mask, returns On/Off
       
   101 public:
       
   102     (MPowerInput-derived) iSharedResource1;        // 1 per shared resource
       
   103     (MPowerInput-derived) iSharedResource2;
       
   104     ...
       
   105     };
       
   106       </codeblock> <p>The <codeph>InitResources()</codeph> function would
       
   107 do at least two things: </p> <ul>
       
   108 <li id="GUID-29FA1D5C-0691-5EB2-A45A-5925D5C58A56"><p>enable an appropriate
       
   109 set of simple resources at boot time </p> </li>
       
   110 <li id="GUID-6F0D4084-48E9-585B-857B-F67B7B453DC7"><p>initialise the shared
       
   111 power resource tracking objects, i.e. the instances of your <xref href="GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A.dita"><apiname>MPowerInput</apiname></xref> derived
       
   112 class(es). </p> </li>
       
   113 </ul> <p>The function would be called by the Variant or ASSP implementation
       
   114 of <xref href="GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D.dita#GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D/GUID-FE55E398-7F08-384F-9E74-2CC2E45002B6"><apiname>Asic::Init3()</apiname></xref> or <xref href="GUID-21641835-7103-374B-9FBB-FAB1875D59A5.dita"><apiname>Asic:Init1()</apiname></xref>. </p> <p>The <codeph>Modify()</codeph> function
       
   115 is an example of how to deal with power resources that are either on or off.
       
   116 The function would take bit masks, where a bit represents a separate controllable
       
   117 power resource. The first bit mask would represent the set of power resources
       
   118 to be turned on, while the second would represent the set of power resources
       
   119 to be turned off. This assumes that the function could behave synchronously.
       
   120 Drivers for peripherals that use a set of these controllable power resources,
       
   121 would call <codeph>Modify()</codeph> to turn the relevant controllable power
       
   122 resources on or off. </p> <p>As an example, the most common method of switching
       
   123 clock resources on or off is by setting and clearing bits in a hardware register.
       
   124 A base port could choose to implement common code for setting bits in registers. </p> <p>A
       
   125 shared power resource is further represented by a <xref href="GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A.dita"><apiname>MPowerInput</apiname></xref> derived
       
   126 class. The implementations of <xref href="GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A.dita#GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A/GUID-2BCA5312-43D9-3763-9636-3B2EB046D2C1"><apiname>MPowerInput::Use()</apiname></xref> and <xref href="GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A.dita#GUID-10105403-AF16-3908-AE9E-96CF2A03AD3A/GUID-606ECD77-A5F7-3408-9B63-C68C0A7B73C6"><apiname>MPowerInput::Release()</apiname></xref> would
       
   127 call <codeph>Modify()</codeph> to turn on the shared resource when the usage
       
   128 count becomes non zero, or turn it off when the usage count reaches zero.
       
   129 Peripheral drivers would have access to shared resources, and also to the
       
   130 member functions of the <codeph>ResourceManager</codeph> class, through the
       
   131 ASSP or Variant Interface class function that returns a pointer to it. </p> <p>The
       
   132 resource manager, or its functions and members, could be offered as part of
       
   133 a power controller interface class, the <codeph>TPowerController</codeph> class
       
   134 suggested when we discussed the implementation of the <xref href="GUID-34D1D0BF-20DE-5677-A067-8FF9DD72E703.dita">Power
       
   135 Controller</xref>'s <xref href="GUID-34D1D0BF-20DE-5677-A067-8FF9DD72E703.dita#GUID-34D1D0BF-20DE-5677-A067-8FF9DD72E703/GUID-5A0CAD08-AA12-56EE-B0A3-75548D1896C9">EnableWakeupEvents()</xref> function.
       
   136 The class would provide an exported function that would give access to the
       
   137 resource manager. The resource manager class would be made part of the power
       
   138 controller kernel extension. Peripheral drivers needing access to shared power
       
   139 resources would then link to the power controller DLL. If the Variant or ASSP
       
   140 were also to need access to the resource manager, then the resource manager
       
   141 would have to be initialised much earlier in the kernel start-up sequence.
       
   142 In this case, we would suggest that the standard power controller kernel extension
       
   143 entry point defined by <xref href="GUID-7964FC46-4641-3BDD-92C9-50FA22C3321A.dita"><apiname>DECLARE_STANDARD_EXTENSION()</apiname></xref> be
       
   144 replaced with a custom entry point that might look like this: </p> <codeblock id="GUID-B5262624-C7B8-51E4-AE14-1D905DFC0A99" xml:space="preserve">GLDEF_C TInt KernelModuleEntry(TInt aReason)
       
   145     {
       
   146     if(aReason==KModuleEntryReasonVariantInit0)
       
   147         {
       
   148         ResourceManager* c = new ResourceManager ();    // create Resource Manager
       
   149         return c ? KErrNone : KErrNoMemory;    
       
   150         }
       
   151     else if(aReason==KModuleEntryReasonExtensionInit0)
       
   152         {
       
   153         (create DPowerController and Battery Monitor and Power HAL handler)
       
   154         }
       
   155     return KErrNone;         // gets here from calling with KModuleEntryReasonExtensionInit1
       
   156     }
       
   157         </codeblock> <p>The Variant or ASSP would also need to link to the
       
   158 power controller DLL. </p> <p>The following base port software architecture
       
   159 could be applied to the power supply arrangement as illustrated in the hardware
       
   160 block diagram above (see the beginning of this section at <xref href="GUID-3B6544CD-FA6E-5AB2-AA63-61186F52167D.dita">Controllable
       
   161 Power Resources</xref>): </p> <fig id="GUID-309A6C5E-A347-5E04-B2C8-426A81755226">
       
   162 <title>Base port software architecture</title>
       
   163 <image href="GUID-EE2F64B2-A2E3-524F-8E04-68BE9AA9EA36_d0e29378_href.png" placement="inline"/>
       
   164 </fig> </section>
       
   165 <section id="GUID-C4C67612-C5CD-5D64-B257-259FD12443C9"><title>Multi-level,
       
   166 composite and asynchronous power resources</title> <p>Some power resources
       
   167 may have more than one operational level. For example, it is possible that
       
   168 an input clock to a peripheral can be operated at a nominal value corresponding
       
   169 to the fully active state, and may be lowered to another level corresponding
       
   170 to the power saving state. </p> <p>The same could apply to the input voltages
       
   171 that the peripheral can operate on. The control model suggested above for
       
   172 simple resources may not be appropriate. A suggested alternative would have
       
   173 these multi-Level resources implementing an interface that offers a public
       
   174 enumeration to cover all possible usage levels at which the resource can be
       
   175 used, and APIs such as: </p> <codeblock id="GUID-44492A89-C7DC-5C97-928C-549BEAD38161" xml:space="preserve">class MultiLevelResource
       
   176     {
       
   177     enum TResourceLevel
       
   178         {
       
   179         EOperationalLevel1,
       
   180         EOperationalLevel2,
       
   181         . . .
       
   182         ELowPowerLevel1,
       
   183         ELowPowerLevel2,
       
   184         . . .
       
   185         };
       
   186     void UseToLevel();
       
   187     void ReleaseToLevel();
       
   188     TResourceLevel GetCurrentLevel();
       
   189     . . . 
       
   190     };</codeblock> <p>More importantly, it is possible that resources may
       
   191 have to be operated in combination with other resources. For example, some
       
   192 peripherals may have more than one input clock, and on transition between
       
   193 power states, these clocks may have to be changed simultaneously. </p> <p>If
       
   194 the resources to be actuated simultaneously are simple resources, then the
       
   195 model above with a <codeph>Modify()</codeph> call that takes a bit mask and
       
   196 allows more than one resource to be changed at a time may be appropriate.
       
   197 If the resources to be actuated are shared or multi-level, or have to be represented
       
   198 individually, then another interface will have to be defined to allow modifying
       
   199 more than one of them simultaneously. </p> <p>Modifying some resources may
       
   200 not be an instantaneous operation. For example, it may take a non-negligible
       
   201 amount of time to stabilise an input clock that has just been modified. </p> <p>The
       
   202 nature of EKA2 strongly discourages actively waiting (or “spinning”) inside
       
   203 drivers; instead it is suggested that the multithreading capabilities of EKA2
       
   204 kernel side code and the synchronisation mechanisms available be used to solve
       
   205 the problem of having the driver code having to wait for a resource to stabilise
       
   206 before proceeding with its use. </p> <p>As an example, let us assume that
       
   207 the multi-level resource mentioned above has a non-negligible delay associated
       
   208 with any level changes: </p> <ul>
       
   209 <li id="GUID-0549E815-BB6E-55C7-84DB-FB6A2ACA11AC"><p>If the length of time
       
   210 to wait for a power resource to stabilise is known, and is the order of a
       
   211 few milliseconds or less, or the driver executes on its unique kernel thread
       
   212 (not used by any other kernel-side code), then the best solution would be
       
   213 to sleep the driver thread, by calling <codeph>NKern::Sleep(aTime)</codeph> for
       
   214 the specified length of time after issuing a call to <codeph>UseToLevel()</codeph> (or <codeph>ReleaseToLevel()</codeph>). </p> </li>
       
   215 <li id="GUID-9F0FCB9F-2827-528A-B3D0-FEE6CF8470CD"><p>When the length of time
       
   216 to wait for a power resource to stabilise increases, then sleeping the driver
       
   217 thread may become a problem if the driver executes in a DFC queue used by
       
   218 other drivers, which is often the case. This is because blocking that thread
       
   219 means that no other drivers can run. Here, the best solution is for the driver
       
   220 to create another thread and DFC queue, by calling <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-B9D637A1-4EB9-39F7-8C5C-2C546994C4B8"><apiname>Kern::DfcQInit()</apiname></xref>,
       
   221 and whenever it needs to change the resource, queue a DFC on that queue, which
       
   222 will issue the calls to <codeph>UseToLevel()</codeph> (or <codeph>ReleaseToLevel()</codeph>)
       
   223 and then sleep the thread. </p> </li>
       
   224 <li id="GUID-C8472B27-FC27-5C72-B6C2-A0DA681EA3C6"><p>If the length of time
       
   225 to change a power resource cannot be known in advance, but the hardware provides
       
   226 an indication of completion of the change, for example, in the form of an
       
   227 interrupt, then the solution may involve the driver code waiting on a Fast
       
   228 Mutex, which is signalled by the completion event (in code belonging to the <codeph>MultiLevelResource</codeph> derived
       
   229 object). </p> </li>
       
   230 </ul> </section>
       
   231 </conbody></concept>