diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,609 @@ + + + + + +Power +Resource Manager (PRM)Describes the Power Resource Manager. + +
Introduction

The +Power Resource Manager (PRM) integrates the Symbian device driver with existing +power control and functions used for resource state changing and querying. +It defines an exported API that device drivers and other users of power resources +(represented by kernel-side components) can use to control the state of power +resources. The PRM assists the development of device drivers by removing the +need to understand the complexities of platform specific power resource management +by providing a simple to use generic framework.

The PRM also allows +user-side clients to gain access to the services. Clients of the PRM can:

    +
  • request information +on the clients and resources registered with PRM

  • +
  • get the current state +of the resources

  • +
  • request changes to the +state of power resources

  • +
  • request notification +of changes (i.e. power-down or change clock frequency) to the power resources +that they depend on.

  • +

The following diagram shows the generic and customisable parts of +the framework:

    +
  • exported kernel level +API (PowerResourceManager)

  • +
  • base virtual class for +Power Resource Controller (DPowerResourceController)

  • +
  • PDD required for user-side +proxy client

  • +
  • platform specific implementation +of resource control at the level of register interface to hardware resource +controller (DXXXPowerResourceController)

  • +
+ +
+
Concepts
    +
  • Power resources

  • +
  • Clients

  • +

Power resources

A +power resource is anything that has an effect on power consumption. These +are typically platform specific and either physical or logical. Physical power +resources are provided by hardware: for example, clocks, outputs from voltage +regulators, switched power domains and performance levels. Logical power resources +do not directly map to hardware components, but their state has an effect +on overall power consumption. In this category we include, for example, shared +buses and devices that provide services to other components.

Power +resources can be further categorised based on:

    +
  • Number of clients

    A power resource can have a single user or it can +be shared. There is no limit to the number of clients sharing a resource. +If the resource is shared, then a request system is used. This comprises a +list of client +level objects, one for each client requesting a level on the resource. +The resource level is determined by a set of rules which govern whether a +request is accepted or declined.

  • +
  • States

    The resource +state may be binary, multi-level or multi-property. A binary state +is either On or Off and a multi-level state can change either discretely or +continuously between a minimum (which could be Off) and a maximum value (which +could be fully On).

    A multi-property resource has different properties +across different portions of the operating curve. For example, the level may +be controllable within the ‘operational’ part of that curve but have different +discrete fixed states for the ‘idle’ or ‘sleep’ modes of operation.

  • +
  • Execution time

    The +execution time of a resource can be either instantaneous or long latency. +An instantaneous resource can be operated almost immediately (no longer than +a few system clock cycles, comparable to a CPU instruction execution time). +Operations on long latency resources take a significant time to complete (a +non-negligible amount of CPU clock cycles).

    Power resources may be +long latency for state change operations and instantaneous for obtaining the +current state. This is typically the case of a PLL (Phase Locked Loop) device +(definition +from Wikipedia), which requires time to stabilise after a frequency +change is initiated but whose current output frequency can be read from a +register. Note: instantaneous operations may pre-empt operations on +long latency resources, and requests to get the state of a shared resource +may be issued while a state change is underway. If the read operation is instantaneous +and the change is long latency, care must be taken (at the PSL level) to not +return inconsistent values.

    Other power resources may be long latency +on both state change and state read operations. This is typically the case +for any resources accessed through an inter-IC bus (even if their operation +is instantaneous).

  • +
  • Resource sense

    Each +client sharing a resource may have a different requirement on its state. The +resource sense is used to determine whose requirement prevails.

    + + + +

    Positive sense

    +

    Can have their value increased without affecting their sharers.

    The +level is set to the highest level that is requested. The highest requirement +for binary resources is the On state.

    +
    + +

    Negative sense

    +

    Can have their value decreased without affecting their sharers.

    The +level is set to the lowest level that is requested. The lowest requirement +for binary resources is the Off state.

    +
    + +

    Custom sense

    +

    May be increased or decreased freely by some privileged sharers +but not by others, which are bound by the requirement of the privileged sharers.

    The +decision to change the prevailing level (or binary state) depends on the privileges +of the client and past usage of the resource. This decision is made by the +PSL custom +function implementation.

    +
    + + +
  • +
  • Static or Dynamic

    Most +power resources are known at device creation time, so their control should +be addressed by such components as the Variant or ASSP. These resources are +registered during the creation of the Resource Controller; these are static +resources. Resources controlled by device drivers (internal or external) are +only registered at driver-creation time using the registration and deregistration +API provided by the PRM; these are known as dynamic resources.

    Note: +Dynamic resources are only available when you use the extended library. See setup +and configuration.

  • +

Physical resources may belong to one or more of these categories, +for example, a multilevel resource may be shared between different clients +and take a significant time to change state (long latency).

External +devices may include and control their own power resources. In some cases, +an external device can function as a bus expander, allowing other devices +to be connected, and eventually share the power resources it controls.

Caching the prevailing level

The +PRM caches the prevailing level of each resource as well as the client that +requested it. The cached state is guaranteed to be the state that the resource +was in when the last request to change or read the state from its hardware +was issued.

On resource state read operations, the PRM allows clients +to select the cached state instead of the current state of the hardware resource. +A cached state read is always an instantaneous operation executed in the context +of the calling client thread (even for long latency resources).

However, +care must be taken as the cached state may not be the state the resource is +at that moment. For example, a resource can be non-sticky: when it is turned +on it stays on during an operation but then automatically switches itself +off.

The consistency of the cached state relies on all resource state +operations being requested through the Power +Resource Controller.

Dynamic +resources

A generic layer provides basic functionality for static +resources an extended version of the PRM provides APIs for dynamic resources +and resource dependencies. These dynamic resource and resource dependent APIs +are only available through the extended library resmanextended.lib.

A +dynamic resource is registered with the PRM using PowerResourceManager::RegisterDynamicResource(). +This function is also used to register a dynamic resource that supports dependencies +between resources.

TInt RegisterDynamicResource(TUint aClientId, DDynamicPowerResource* aResource, TUint& aResourceId)

Pass the ID of the client that requests the dynamic resource and the +dynamic resource (DDynamicPowerResource) to register. The +PRM sets aResourceId to the resource ID of this resource. +Dynamic resources that support dependencies are derived from the class DDynamicPowerResourceD.

Deregistering a dynamic resource

Use PowerResourceManager::DeRegisterDynamicResource() to +deregister a dynamic resource from the PRM. You can also use the function +to deregister a dynamic resource that supports a dependency.

TInt DeRegisterDynamicResource(TUint aClientId, TUint aResourceId, TInt* aState)

aState is a pointer to the final state that the resource is set +to before deregistration if this value is NULL the state of the resource is +changed to its default.

Changing resource state on a dynamic resource

Because a dynamic +resource can deregister from the PRM it is necessary to indicate to clients +that this has happened. Any remaining notification requests are completed +with a -2 in the client field of the callback function. This indicates that +this notification is because the resource has been deregistered and not because +the notification conditions have been met. When a client recieves a notification +of this type the request notification should be cancelled using CancelNotification().

Resource dependencies

A +resource may register a dependency on another resource. At least one of the +resources must be a dynamic resource. Request a dependency between resources +with PowerResourceManager::RegisterResourceDependency().

TInt RegisterResourceDependency(TUint aClientId, SResourceDependencyInfo* aResDependecyInfo1, SResourceDependencyInfo* aResDependencyInfo2)

This function is passed the ID of the client that sets the resource dependency +and the dependency information of the resource (SResourceDependencyInfo). SResourceDependencyInfo contains +the resource ID and the priority of the dependency.

The kernel will +panic if a closed loop dependency is found for the specified dependency or +if a resource with same dependency priority is already registered.

Use GetNumDependentsForResource() to +retrieve the number of resources that depend on the specified resource directly +and GetDependentsIdForResource() to return the IDs of all +the dependent resources.

Deregistering +resource dependencies

Use PowerResourceManager::DeRegisterResourceDependency() to +remove a dependency. This function takes the ID of the client that requests +the deregistration of the resource dependency and the IDs of the linked resources.

TInt DeRegisterResourceDependency(TUint aClientId, TUint aResourceId1, TUint aResourceId2)

Note: These functions are only available when you use the extended +library.

Changing +resource state on a dependent resource

A resource state can change +when the state of any of its dependent resources changes. A state change causes +a notification if the requested conditions are met. The client ID in the callback +function is updated with the ID of the resource that triggered this resource +change (bit 16 of the ID is set for dependency resource; this is used to distinguish +between a resource ID and a client ID).

Clients

The +PRM has both user and kernel-side clients. Kernel-side clients are:

    +
  • device drivers

  • +
  • performance scaling +and/or performance monitoring and prediction components

  • +

User-side clients are:

    +
  • user-side system-wide +power management framework

  • +
  • other power-aware servers +and power-aware applications

  • +

Clients register with the PRM by name. Clients can request to allocate +and reserve client level objects and request message objects after registering +with PRM.

Client level objects

Client +level objects represent a client requesting a level on a resource. They are +used by resources to set the current level of the resource and the current +owner of the resource level.

Each resource has a doubly linked list +on which client level objects are held. When a client requests a level for +the first time, a new client level object is added to the list; however, if +the client already has an object on the list, this object is adjusted to reflect +the change in the required level.

The following rules determine whether +the change is allowed on positive and negative sense resources:

    +
  • If the requested change +is in the direction permitted by the resource sense and would result in exceeding +the prevailing level, the change is allowed.

    The new prevailing level +is recorded, and the previous prevailing level and the requirements other +clients have on the resource remain on record.

  • +
  • If the requested change +is not in the direction permitted by the resource sense, but the client requesting +the change is the owner of the prevailing level, the resource state changes +up to next highest for a positive sense resource, or lowest for a negative +sense resource.

    This value is now the prevailing level and the client +that requested it remains the owner of the prevailing level.

  • +
  • If the requested change +is not in the direction permitted by the resource sense, and the client requesting +the change is not the owner of the prevailing level, the change is not allowed.

    Even +though the request was rejected, the client's existing requirement is adjusted +to reflect the request.

  • +

Prevailing levels are recorded by either adjusting the previous requirement +for the client that requested it or, if it is the first time this client requests +a level, a new requirement is created.

Notifications

A +client may request a state change notification from a resource. Notifications +can be conditional or unconditional; conditional notifications specify a threshold +on the resources state, which when crossed in the direction specified, triggers +the notification.

Notifications are always issued post resource change +and invoke callback functions executed in the context of the requesting client +thread. The process of notifying a client involves queuing a DFC in that clients' +thread. The notification object encapsulating the DFC must be created in kernel +heap and passed to the notification API by the client that requested the notification. +The client may share the same callback function between several notifications, +but a unique DFC must be created and queued per notification.

Because +notifications result in DFCs being queued, it is not possible to guarantee +that all changes of resource state are notified. If the resource state changes +again before the first DFC runs, a separate notification cannot be generated. +It is also not possible to guarantee that by the time the notification callback +runs, the resource state is still the same as the state that caused the notification +to be issued: it is the responsibility of the driver to read the resource +state after receiving a notification.

+
User-side
    +
  • Introduction

  • +
  • Initialisation

  • +
  • Getting power resource information

  • +
  • Requesting notifications

  • +
  • Changing the state of power resources

  • +

Introduction

The RBusDevResManUs user-side +API makes relevant PRM functionality available to user-side applications that +have power-aware features.

RBusDevResManUs is derived +from RBusLogicalChannel, the user-side handle to a logical +channel base class, and presents the user-side interface to a kernel-side +LDD. The LDD is built as resman.ldd.

The API +enables concurrent access by multiple clients, with one channel supported +for each. Sharing of channels between threads is not supported.

To +open a channel on the user-side API a client must exhibit the PlatSec capability PowerMgt.

If a client wishes to access information +on kernel-side clients of the Resource Controller, it must also exhibit the ReadDeviceData capability.

Initialisation

Clients +do not need to explicitly load the kernel-side LDD, as this is a kernel extension +and so is loaded and initialised during kernel initialisation (attempts to +re-load it returns the error code KErrAlreadyExists but initialistation +otherwise appears successful).

Clients open a channel on the LDD by +calling the RBusDevResManUs::Open() method. The client +passes a name to the method - ideally, this is the client’s component name. +It is the client’s responsibility to ensure the name is unique even if multiple +channels are opened.

The client then needs to call the Initialise() method +specifying the number of request objects required. The numbers passed to Initialise() determine +the extent of memory allocation required (in part by the LDD and in addition +by request to the Resource Controller) and also the maximum number of concurrent +client requests supported.

The number of request objects created at +initialisation should be the maximum number of concurrent (asynchronous) requests +that the client expects to have outstanding at any time.

Getting power resource information

RBusDevResManUs::GetResourceInfo() is a method to retrieve the information for a specified resource, which +it returns in a TResourceInfo object. There is also a method +to get all the information for all the resources (GetAllResourcesInfo()). +This function requires the allocation of buffer memory in which the information +for all the resources is returned. GetNoOfResources() returns +the total number of resources available for access.

The example below +shows these functions in use. The amount of resources available are returned +by GetNoOfResources. This figure is used to calculate the +size of the buffer that is populated with the resource information by the GetAllResourcesInfo method.

TInt r = KErrNone; + TUint numResources=0; + if((r=gChannel.GetNoOfResources(numResources))!=KErrNone) + { + // Failed + return r; + } + + RBuf buffer; + if((buffer.Create(numResources*sizeof(TResourceInfo)))!=KErrNone) + { + // Failed + return KErrGeneral; + } + + buffer.SetLength(numResources*sizeof(TResourceInfo)); + + if((r=gChannel.GetAllResourcesInfo(buffer,numResources))!=KErrNone) + { + // Failed + return r; + }

Get the current resource state with GetResourceState(). +Passing ETrue results in the cached state being read rather +than the current hardware state. The cached state is guaranteed to be the +state that the resource was in when it was last changed or read from hardware. +This is why it is important that all change requests are carried out through +the Resource Controller. readValue returns the current prevailing +level and levelOwnerId the ID of the client that owns the +prevailing level. GetResourceState() can be cancelled using CancelGetResourceState() passing +the resource ID of the resource that the original request was on. Use the +method GetResourceIdByName() to get the ID of a resource +from the resource's name.

// Get initial state +TRequestStatus status; +TBool cached = EFalse; +TInt readValue; +TInt levelOwnerId = 0; + +gChannel.GetResourceState(status, gSharedResource, cached, &readValue, &levelOwnerId); +User::WaitForRequest(status);

GetNumClientsUsingResource() and GetNumResourcesInUseByClient() are used to retrieve the numbers of clients using a resource and the number +of resources in use by a client, respectively. GetInfoOnClientsUsingResource() and GetInfoOnResourcesInUseByClient() complement the last two methods by retrieving the resource information for +each resource that is in use by a specified client or retrieving the client +information for each client using the specified resource.

The API +supports receiving a number of concurrent (asynchronous) requests from a client; +the maximum number is determined by the number of resources that were specified +at initialisation. If a client issues a request that exceeds its allocation, +the error code KErrUnderflow is returned.

Some synchronous +methods take a binary value, aIncludeKern, which defaults +to EFalse. If this parameter is set to ETrue, +the API attempts to return information that includes kernel-side clients.

Requesting notifications

Clients +can request to be notified when a resource changes its state using the RBusDevResManUs::RequestNotification() method. +Clients can also request to be notified when a resource reaches a specified +threshold in a specified direction (positive or negative resource sense) using the same method but also passing it threshold +and direction values.

To cancel a notification, use CancelNotification() passing +the resource ID from which the notification was requested. Note: Any +notifications issued by a client must be cancelled before the client deregisters.

It +is not guaranteed that all changes of resource state result in a notification +– a resource may change state more than once before a notification request +is completed. In addition, it is not guaranteed that a resource is in the +same state as it was when the notification was generated. For these reasons, +it is the responsibility of the user-side client to read the state of a resource +after receiving a notification.

Changing the state of power +resources

To change a resource state call the asynchronous ChangeResourceState() method +passing the ID of the resource on which the change is being requested and +the requested state.

CancelChangeResourceState() cancels +all the ChangeResourceState() outstanding requests from the +client on the specified power resource. For each outstanding request, the +request object is removed from the doubly linked list within the Resource +Controller and returned to the request object pool.

+
Kernel-side

The Power Resource Manager component is implemented +as a kernel extension. It has an exported public interface accessible to kernel-side +components. Kernel components link to the resource manager kernel extension +DLL (resman.lib). Extended features are compiled and +exported in an additional library (resmanextended.lib). +The export library is built from the generic layer.

To ease the development +of the PRM including the functionality provided by the generic layer and the +mandatory PSL implementation, the generic layer is compiled into a kernel +library (klib) (resmanpsl.lib for the basic version and resmanextendedpsl.lib for +the extended version) which is included by the PSL to produce the kernel extension.

    +
  • Concepts

  • +
  • Registration and initialisation

  • +
  • Deregistration

  • +
  • Requesting power resource information

  • +
  • Changing the state of power resources

  • +
  • Requesting notifications

  • +

Concepts

    +
  • Requests

  • +
  • Callbacks

  • +

Request messages

Request +message objects represent a request for an operation on a resource by a client. +For example a request to change a resource's level or notification if a resource's +level changes.

The client may attempt to increase its quota by requesting +the allocation of request messages, but this may fail with KErrNoMemory. +A long latency resource request on may fail with KErrUnderflow if +the number of request messages pre-allocated by the client has been exceeded +and no more messages are left in the free pool to satisfy the request.

The +pre-allocation and reservation of client +levels and request messages is synchronously serviced in the context +of the calling client, although this may result in memory allocation that +is not time bound.

See Pre-allocating +client level and request message objects for implementation guidelines.

Callbacks

A +callback object is a customised DFC that is used to signal the completion +of notifications and the PRM's asynchronous APIs. Use the class TPowerResourceCb to +create a resource callback object that encapsulates callback functions.

The +resource callback object is initialised with a callback function TPowerResourceCbFn, +a pointer to data passed to the callback function, the priority of the DFC +within the queue (0 to 7, where 7 is highest) and optionally, a pointer to +the DFC queue that this DFC should use.

inline TPowerResourceCb(TPowerResourceCbFn aFn, TAny* aPtr, TInt aPriority)

This one specifies the DFC queue:

inline TPowerResourceCb(TPowerResourceCbFn aFn, TAny* aPtr, TDfcQue* aQue, TInt aPriority)

The user specified callback function is invoked with five arguments:

    +
  • the ID of the client +is:

      +
    • the client that issued +an asynchronous operation - if the callback function is called as a result +of an asynchronous resource state read operation

    • +
    • the client that is currently +holding the resource - if the callback function is called as a result of an +asynchronous resource state change operation or resource state change notification.

    • +
    • Note:

        +
      • If -1 is passed as the +client ID this specifies that no client is currently holding the resource.

      • +
      • In the extended version +of PRM (see Dynamic and Dependant resources) if -2 is passed as the client +ID in the callback function it signifies that the dynamic resource is deregistering. +With dependency resources, the ID of the dependent resource is passed as the +client ID if the state of the resource (specified in aResourceId) +changes as a result of the dependant resources stage changing (whose ID is +specified in aClientId).

      • +
    • +
      +
    • issued an asynchronous +API (state read or change) which leads to the callback function being called

    • +
    • requested the resource +state change that leads to queuing a notification, which then leads to the +callback function being called.

    • +
  • +
  • the resource ID - a +client may have multiple notifications pending on different resources and +a single callback function. The resource ID can be used to specify which resource +change is being notified

  • +
  • the level of the resource +when either:

      +
    • the callback is called +as a result of a notification of state change

    • +
    • when the callback is +called as a result of a non-blocking form of PowerResourceManager::GetResourceState().

    • +
    • the requested level +for the resource when the callback is called as a result of a non-blocking +form of PowerResourceManager::ChangeResourceState()

    • +
  • +
  • the ID of the resource +level owner

  • +
  • the error code returned +when the callback is called as a result of an asynchronous request to change +the state of the resource. This is not relevant when the callback is called +as a result of a notification of state change

  • +
  • a user defined argument +that is passed to the constructor.

  • +

Cancel an asynchronous request, or its callback, by calling CancelAsyncRequestCallback().

Registration and initialisation

Clients +need to register with the PRM using PowerResourceManager::RegisterClient() before +they can request operations on resources.

Registration happens at +different times for different clients:

    +
  • kernel extensions register +from their entry point during kernel boot

  • +
  • device drivers for internal +or external devices register on opening a channel.

  • +

When a client registers with the PRM, a client link object is removed +from the free pool, populated with the relevant information, and a pointer +to it is added to a container of clients within the PRM. If no free link exists +within the pool, a number of client links are created in kernel heap. As a +result, client registration may fail in out of memory situations. Client links +are never destroyed after the client deregisters, but are released back into +the free pool.

Clients are registered by name; the PRM does not check +that a name is unique unless the DEBUG_VERSION macro is enabled. +The component registering the client should check that the name is unique. +The ID returned is a handle to the client link object that represents the +client in the PRM.

On registration, a client also specifies the type +of ownership (TOwnerType) that applies. This is either:

    +
  • EOwnerThread - +the client ID is only used by the thread that registered the client to call +the PRM APIs

  • +
  • EOwnerProcess - +the client ID is used by all threads in the process to call the PRM APIs.

  • +

The default is EOwnerProcess.

Pre-allocating client level +and request message objects

The controller has an initial pool +of free client levels and request messages whose size can be configured at +build time by the PSL. After registering with the PRM, a client can request +the pre-allocation of a number of client levels and request messages to guarantee +deterministic behaviour (to avoid out of memory failure) of the resource state +change operation using PowerResourceManager::AllocReserve(). +This allocation remains reserved to the specified client until the client +is deregistered from the PRM. The number of client level objects reserved +by a client depends on the number of resources on which a resource state change +will be requested.

A client may issue more than one request, possibly +to the same resource, before the previous one completes, it is therefore more +difficult to determine how many objects to pre-allocate.

It is recommended +that as many request messages as asynchronous long latency resources the client +expects to use are pre-allocated. The free pool should be relied on for the +situations when a resource is requested more than once before the first request +completes.

Deregistration

All +notifications and asynchronous requests must be cancelled before the client +is deregistered, otherwise the kernel will panic. Use the PowerResourceManager::CancelNotification() and CancelAsyncRequestCallback() methods to cancel all pending notifications and asynchronous requests. Notifications +that have been registered with the Controller should be deregistered before +they are deleted as the Controller may attempt to issue them. Deleting a notification +that is still registered with the Controller results in the kernel panicking.

Client +level objects and request objects reserved by the client remain reserved +for that client until it deregisters. When the client is deregistering these +objects are moved to free pool by the PRM.

Client deregistration can +result in a resource state change:

    +
  • If the resource is shared +and the deregistering client owned the prevailing level, the resource state +is moved to the next level according to its sense. If it is a custom sense +resource, the resource state is changed as a result of calling a custom function.

  • +
  • If the resource is not +shared or if it is shared but the client is the only one using it at the time +of deregistration, the resource is moved to the default state. The +default state is only known by the PSL.

  • +

A deregistering client can have a number of active requirements on +a number of resources and more than one of these resources may need to change +state as a result of the client deregistering. The combined operation of deregistering +the client and adjusting the state of all resources it shares executes synchronously. +That is, the client thread is blocked throughout whether the resources whose +state needs to change is instantaneous or long latency.

Getting power resource information

The +resource information can be retrieved using the method PowerResourceManager::GetResourceInfo(), +information can also be retrieved for all of the resources used by the specified +client using GetInfoOnResourcesInUseByClient(). This function +takes a buffer that must be the size of the information structure multipled +by the number of resources in use by the client, this figure can be retrieved +using the method GetNumResourcesInUseByClient(). Specify +the resource ID as zero to retrieve all information from all the clients registered +with PRM.

To get information about clients using a resource, use the +method GetInfoOnClientsUsingResource(). Use the number +of clients using a resource using GetNumClientsUsingResource(). +Specify the client ID as zero to retrieve all information from all the resources +registered with PRM.

Use PowerResourceManager::GetResourceState() to +retrieve resource state information. This function can be called synchronously +or asynchronously. Asynchronous calls require the client to create a callback +object in the kernel heap or data section. The synchronous GetResourceState() call.

TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId);

The asynchronous GetResourceState() call.

TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb);

If executing asynchronously, the callback function encapsulated in the +callback object (called in the client’s context) is invoked when the state +of the resource is available. The third argument of the callback function +carries the resource state. If this function is called with aCached set +as ETrue, then the callback function is called in the context +of the calling thread both for instantaneous and long latency resources, thus +blocking the calling thread throughout.

For instantaneous resources, GetResourceState() executes +in the context of the calling thread and, if specified, the callback function +is called after getting the state of the requested resource. The calling thread +is blocked throughout.

GetResourceState() takes +a boolean value that determines from where the requested resource state information +is retrieved:

    +
  • ETrue - the resource +state is the cached value, this value is returned faster but is not guaranteed +to be correct

  • +
  • EFalse - the resource +state is read from the resource, this value takes longer to return, but is +much more likely to be correct.

  • +

Changing the state of power +resources

The PowerResourceManager::ChangeResourceState() method +is used to request a change on a resource. When a state change is requested +on a shared resource, only the minimum state change that satisfies the request +is guaranteed.

TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL);

The values passed to the method are:

    +
  • the ID of the client +requesting the change

  • +
  • the ID of the resource +that the change is to take place

  • +
  • the new state of the +resource

  • +
  • a pointer to the resource +callback object.

  • +

The requested state is either a binary value for a binary resource, +an integer level for a multilevel resource or some platform specific token +for a multi-property resource. The pointer to the callback object is defined +by the class TPowerResourceCb; its use is optional and +is treated by synchronous and asynchronous resources as described below.

Changing resource state on a long latency resource

If the +callback object is specified, then ChangeResourceState() is +executed asynchronously and returns immediately. The actual resource change +happens in the resource controller thread and the callback function encapsulated +in the callback object is called after the resource is changed.

If +the callback object is NULL, then ChangeResourceState() executes +synchronously, meaning the client thread is blocked until the resource state +has changed. The PRM panics if the synchronous version of this API for long +latency resources is called from DFC thread 0.

Changing resource state on an instantaneous resource

On an +instantaneous resource ChangeResourceState() always executes +synchronously.

If a callback object is specified, then the callback +function encapsulated in the callback object is called from the client thread +after the resource change and before returning from the function.

Use CancelAsyncRequestCallBack() to +cancel change requests on a resource. When the client no longer requires a +level on a resource use the method DeRegisterClientLevelFromResource() to +remove a client level object from a resource.

Requesting notifications

Clients +can request notification of a state change on a resource. Notifications are +issued post resource change and invoke the callback function encapsulated +in a notification object. The callback is executed in the context of the requesting +client thread.

The parameters passed to PowerResourceManager::RequestNotification() are:

    +
  • the ID of the client +requesting the notification

  • +
  • the ID of the resource +for which notification of state changes is being requested

  • +
  • a reference to a notification +object encapsulating a callback function called whenever a resource state +change takes place.

  • +

A notification may be unconditional or conditional. An unconditional +notification request notifies the client each time the state changes. A conditional +notification request notifies the client when a threshold has been met in +the direction specified. A conditional notification has these additional parameters:

    +
  • aThreshold - the level +of the resource state that triggers the notification

  • +
  • aDirection - the direction +the resource state change that triggers a notification:

      +
    • EFalse - the resource +state is equal to or below the threshold

    • +
    • ETrue - the resource +state is equal to or above the threshold.

    • +
  • +

The client must create the notification object (DPowerResourceNotification) +in the kernel heap or data section. Note: The client may share the +same callback function between several notifications but a unique DFC must +be created and queued for each notification.

Because notifications +result in DFCs being queued, it is not possible to guarantee that all resource +state changes are notified. If the resource state changes again, before the +first DFC runs, it does not generate a separate notification. It is also not +possible to guarantee that by the time the notification callback runs the +resource state is still the same state that caused the notification to be +issued. The client should read the resource state after receiving a notification.

Use CancelRequestNotification() to +cancel a notification request. It takes a reference to the notification object +associated with the original notification request that is being cancelled.

+
\ No newline at end of file