diff -r 48780e181b38 -r 578be2adaf3e Symbian3/PDK/Source/GUID-A789E0D6-74B2-517D-B73A-F9B11794F175.dita --- a/Symbian3/PDK/Source/GUID-A789E0D6-74B2-517D-B73A-F9B11794F175.dita Tue Jul 20 12:00:49 2010 +0100 +++ b/Symbian3/PDK/Source/GUID-A789E0D6-74B2-517D-B73A-F9B11794F175.dita Fri Aug 13 16:47:46 2010 +0100 @@ -1,187 +1,160 @@ - - - - - -Peripheral -Driver Power Implementation Tutorial -

Peripheral driver power management is based on the DPowerHandler class. -This is a class that defines the interface that the driver must provide to -the generic kernel side power manager.

-

The class also provides the necessary support functions. The class is defined -as:

-class DPowerHandler : public DBase - { -public: - IMPORT_C ~DPowerHandler(); -public: - IMPORT_C DPowerHandler(const TDesC& aName); - IMPORT_C void Add(); - IMPORT_C void Remove(); - IMPORT_C void PowerUpDone(); - IMPORT_C void PowerDownDone(); - IMPORT_C void SetCurrentConsumption(TInt aCurrent); - IMPORT_C void DeltaCurrentConsumption(TInt aCurrent); -public: - virtual void PowerDown(TPowerState aTargetState) = 0; - virtual void PowerUp() = 0; -private: - ... - }; - -

Typically, at least one power handler object is implemented by the peripheral -driver. In some cases the peripheral driver interface class may derive from DPowerHandler, -in others it creates and owns an instance of a DPowerHandler derived -class.

-

The Symbian port of the LCD -Extension for the Lubbock reference board is an example of the first -type of implementation.

-

The first eight functions are exported from the kernel, EKERN.EXE, -while the remaining two pure virtual functions are implemented by the peripheral -driver.

-
    -
  • PowerDown()

  • -
  • PowerUp()

  • -
-

Notes:

-
    -
  1. Current consumption -monitoring does not have a full implementation in the power manager at present. -It is unclear whether this will be ever required. However, DPowerHandler does -provide two functions: DPowerHandler::SetCurrentConsumption() and DPowerHandler::DeltaCurrentConsumption() that -a power handler can use to track the peripheral's power consumption. Note -that this is not based on actual measurements.

    SetCurrentConsumption() sets -a target current consumption, usually at driver creation time.

    DeltaCurrentConsumption() changes -this target current consumption value, specifying a positive or a negative -value as appropriate; this might be called in response to an operation that -is about to start.

    Although we have described the context in which -these functions would be used, we recommend that you do not use them.

  2. -
  3. Fixed media drivers -do not have a power handler. This means there is currently no mechanism to -power down media drivers and the associated fixed media when the system transitions -to a low power state.

  4. -
  5. The __NEW_POWER_HANDLERS macro -is used to maintain backwards compatibility with the power model used in previous -versions of Symbian platform. If this macro is not defined, it is possible -for power handlers to revert back to the behaviour they present in Kernel -Architecture 1 (EKA1).

    If implementing an old style power handler, -the following functions will have to have an implementation provided by the -peripheral driver:

    virtual TInt DoPowerUp() -virtual void DoPowerDown(TUint32 /* aPowerDownMask */) -virtual void DoEmergencyPowerDown() -

    If using at least an old style power handler the -power manager will not complete any powering down (transition to Off or Standby). -Thus it is recommended that they not be used.

  6. -
-
DPowerHandler::PowerDown() virtual void PowerDown(TPowerState) = 0;

When -is it called?

DPowerHandler::PowerDown() is -called by the Power -manager during a transition to the Standby or the Off state. -The TPowerState argument specifies which of the two power -states is the target.

Implementation issues

    -
  1. After receiving a request -to power down, as a result of a system transition to the Standby or Off states, -a peripheral driver should perform the necessary activity to power down the -peripheral and ancillary hardware, unless it is required for the detection -of wake-up events. This activity might include requesting the removal of the -power supply and any other power resources.

  2. -
  3. The power down operation -can be done in the same thread in which PowerDown() runs, -i.e. synchronously, or it can run in another thread, i.e. asynchronously. -You would probably implement power down in another thread if the operation -were potentially slow. Once the peripheral has powered down, it must inform -the power manager by calling DPowerHandler::PowerDownDone(), -and this function can be called from the same thread in which PowerDown() runs, -or it can be called from another thread. Two points to note:

      -
    • PowerDownDone() can -be called before or after PowerDown() returns

    • -
    • PowerDownDone() cannot -be called before PowerDown() has been entered.

    • -
  4. -
  5. PowerDown() is -only called on a transition to the Standby or the Off state. -If the peripheral hardware is powered down when the peripheral driver is closed, -or when the hardware resources are relinquished by the driver, then this is -managed by the driver alone.

  6. -
  7. There are synchronisation -issues related to calls to the DPowerHandler::Add() and DPowerHandler::Remove() functions. DPowerHandler::Add() is called by the peripheral driver when the driver object is created. This -registers the power handler with the power manager so that so that the driver -can receive notification of power state transitions. Conversely, DPowerHandler::Remove() is -called when the peripheral driver is in the process of being destroyed. This -de-registers the power handler so that the driver is no longer notified of -power state transitions. Calls to DPowerHandler::Add(), DPowerHandler::Remove(), DPowerHandler::PowerDown() and DPowerHandler::PowerUp() can run asynchronously in -relation to one another. For example, it is entirely possible that the kernel -may be asking the driver to power down while it is being created, or indeed -while it is being destroyed.

    To avoid deadlock, DPowerHandler::Add(), DPowerHandler::Remove(), -and the Power -manager functions that call your DPowerHandler::PowerDown() and -your DPowerHandler::PowerUp() functions, all acquire a -lock, a DMutex. While the lock itself is internal to Symbian -platform, it does impose a requirement that:

      -
    • DPowerHandler::Add()

    • -
    • DPowerHandler::Remove()

    • -
    • DPowerHandler::PowerDown()

    • -
    • DPowerHandler::PowerUp()

    • -

    all run in the same thread. A common implementation of DPowerHandler::PowerDown(), -therefore, schedules a DFC to run on the same thread (a DFC queue) as the -one that calls DPowerHandler::Add() and DPowerHandler::Remove().

  8. -
-
DPowerHandler::PowerUp() virtual void PowerUp() = 0;

When -is it called?

DPowerHandler::PowerUp() is -called by the Power -manager during a transition from the Standby state back to the Active state. -It is up to the peripheral driver to decide whether or not to power up the -peripheral.

Implementation issues

    -
  1. After receiving a notification -to power up, as a result of a system transition from the Standby to -the Active state, it is up to the peripheral driver to decide whether -or not to power up the peripheral and ancillary hardware. The decision usually -depends on whether or not the peripheral driver is currently in use.

  2. -
  3. The power up operation -can be done in the same thread in which PowerUp() runs, i.e. -synchronously, or it can run in another thread, i.e. asynchronously. You would -probably implement power up in another thread if the operation were potentially -slow. Whether or not the peripheral driver intends to power up immediately, -it must acknowledge the power up request by calling DPowerHandler::PowerUpDone(), -and this function can be called from the same thread in which PowerUp() runs, -or it can be called from another thread. Two points to note:

      -
    • PowerUpDone() can -be called before or after PowerUp() returns

    • -
    • PowerUpDone() cannot -be called before PowerUp() has been entered.

    • -
  4. -
  5. PowerUp() is -only called on a transition to the Active state. If the peripheral -hardware is powered up when the peripheral driver is opened, or when the hardware -resources are first used by the driver, then this is managed by the driver -alone.

  6. -
  7. There are synchronisation -issues related to calls to the DPowerHandler::Add() and DPowerHandler::Remove() functions. DPowerHandler::Add() is called by the peripheral driver when the driver object is created. This -registers the power handler with the power manager so that so that the driver -can receive notification of power state transitions. Conversely, DPowerHandler::Remove() is -called when the peripheral driver is in the process of being destroyed. This -de-registers the power handler so that the driver is no longer notified of -power state transitions. Calls to DPowerHandler::Add(), DPowerHandler::Remove(), DPowerHandler::PowerDown() and DPowerHandler::PowerUp() can run asynchronoulsy in -relation to one another. For example, it is entirely possible that the kernel -may be asking the driver to power down while it is being created, or indeed -while it is being destroyed.

    To avoid deadlock, DPowerHandler::Add(), DPowerHandler::Remove(), -and the power -manager functions that call your DPowerHandler::PowerDown() and -your DPowerHandler::PowerUp() functions, all acquire a -lock, a DMutex. While the lock itself is internal to Symbian -platform, it does impose a requirement that:

      -
    • DPowerHandler::Add()

    • -
    • DPowerHandler::Remove()

    • -
    • DPowerHandler::PowerDown()

    • -
    • DPowerHandler::PowerUp()

    • -

    all run in the same thread. A common implementation of DPowerHandler::PowerUp(), -therefore, schedules a DFC to run on the same thread (a DFC queue) as the -one that calls DPowerHandler::Add() and DPowerHandler::Remove().

  8. -
+ + + + + +Peripheral Driver Power Implementation TutorialDescribes an implementation of the DPowerHandler class. +

Peripheral driver power management is based on the DPowerHandler class. This is a class that defines the interface that the driver +must provide to the generic kernel side power manager.

+

The class also provides the necessary support functions. The class +is defined as:

+class DPowerHandler : public DBase + { +public: + IMPORT_C ~DPowerHandler(); +public: + IMPORT_C DPowerHandler(const TDesC& aName); + IMPORT_C void Add(); + IMPORT_C void Remove(); + IMPORT_C void PowerUpDone(); + IMPORT_C void PowerDownDone(); + IMPORT_C void SetCurrentConsumption(TInt aCurrent); + IMPORT_C void DeltaCurrentConsumption(TInt aCurrent); +public: + virtual void PowerDown(TPowerState aTargetState) = 0; + virtual void PowerUp() = 0; +private: + ... + }; + +

Typically, at least one power handler object is implemented by +the peripheral driver. In some cases the peripheral driver interface +class may derive from DPowerHandler, in others +it creates and owns an instance of a DPowerHandler derived class.

+

The first eight functions are exported from the kernel, EKERN.EXE, while the remaining two pure virtual functions +are implemented by the peripheral driver.

+
    +
  • PowerDown()

  • +
  • PowerUp()

  • +
+

Notes:

+
    +
  1. Current consumption +monitoring does not have a full implementation in the power manager +at present. It is unclear whether this will be ever required. However, DPowerHandler does provide two functions: DPowerHandler::SetCurrentConsumption() and DPowerHandler::DeltaCurrentConsumption() that +a power handler can use to track the peripheral's power consumption. +Note that this is not based on actual measurements.

    SetCurrentConsumption() sets a target current consumption, +usually at driver creation time.

    DeltaCurrentConsumption() changes this target current consumption value, specifying a positive +or a negative value as appropriate; this might be called in response +to an operation that is about to start.

    Although we have described +the context in which these functions would be used, we recommend that +you do not use them.

  2. +
  3. Fixed media +drivers do not have a power handler. This means there is currently +no mechanism to power down media drivers and the associated fixed +media when the system transitions to a low power state.

  4. +
  5. The __NEW_POWER_HANDLERS macro is used to maintain backwards +compatibility with the power model used in previous versions of Symbian +platform. If this macro is not defined, it is possible for +power handlers to revert back to the behavior they present in Kernel +Architecture 1 (EKA1).

    If implementing an old style power +handler, the following functions will have to have an implementation +provided by the peripheral driver:

    virtual TInt DoPowerUp() +virtual void DoPowerDown(TUint32 /* aPowerDownMask */) +virtual void DoEmergencyPowerDown() +

    If using at least an old style power handler +the power manager will not complete any powering down (transition +to Off or Standby). Thus it is recommended that they +not be used.

  6. +
+
DPowerHandler::PowerDown() virtual void PowerDown(TPowerState) = 0;

When is it called?

DPowerHandler::PowerDown() is called by the Power manager during a transition to the Standby or +the Off state. The TPowerState argument +specifies which of the two power states is the target.

Implementation issues

    +
  1. After receiving +a request to power down, as a result of a system transition to the Standby or Off states, a peripheral driver should perform +the necessary activity to power down the peripheral and ancillary +hardware, unless it is required for the detection of wake-up events. +This activity might include requesting the removal of the power supply +and any other power resources.

  2. +
  3. The power down +operation can be done in the same thread in which PowerDown() runs, i.e. synchronously, or it can run in another thread, i.e. +asynchronously. You would probably implement power down in another +thread if the operation were potentially slow. Once the peripheral +has powered down, it must inform the power manager by calling DPowerHandler::PowerDownDone(), and this function can be +called from the same thread in which PowerDown() runs, +or it can be called from another thread. Two points to note:

      +
    • PowerDownDone() can be called before or after PowerDown() returns

    • +
    • PowerDownDone() cannot be called before PowerDown() has been entered.

    • +
  4. +
  5. PowerDown() is only called on a transition to the Standby or the Off state. If the peripheral hardware is powered down when the peripheral +driver is closed, or when the hardware resources are relinquished +by the driver, then this is managed by the driver alone.

  6. +
  7. There are synchronisation +issues related to calls to the DPowerHandler::Add() and DPowerHandler::Remove() functions. DPowerHandler::Add() is called by the peripheral driver +when the driver object is created. This registers the power handler +with the power manager so that so that the driver can receive notification +of power state transitions. Conversely, DPowerHandler::Remove() is called when the peripheral driver is in the process of being +destroyed. This de-registers the power handler so that the driver +is no longer notified of power state transitions. Calls to DPowerHandler::Add(), DPowerHandler::Remove(), DPowerHandler::PowerDown() and DPowerHandler::PowerUp() can run asynchronously in relation to one another. For example, +it is entirely possible that the kernel may be asking the driver to +power down while it is being created, or indeed while it is being +destroyed.

    To avoid deadlock, DPowerHandler::Add(), DPowerHandler::Remove(), and the Power manager functions that call your DPowerHandler::PowerDown() and your DPowerHandler::PowerUp() functions, +all acquire a lock, a DMutex. While the lock itself +is internal to Symbian platform, it does impose a requirement that:

      +
    • DPowerHandler::Add()

    • +
    • DPowerHandler::Remove()

    • +
    • DPowerHandler::PowerDown()

    • +
    • DPowerHandler::PowerUp()

    • +

    all run in the same thread. A common implementation of DPowerHandler::PowerDown(), therefore, schedules a DFC +to run on the same thread (a DFC queue) as the one that calls DPowerHandler::Add() and DPowerHandler::Remove().

  8. +
+
DPowerHandler::PowerUp() virtual void PowerUp() = 0;

When is it called?

DPowerHandler::PowerUp() is called by the Power manager during a transition from the Standby state +back to the Active state. It is up to the peripheral driver +to decide whether or not to power up the peripheral.

Implementation +issues

    +
  1. After receiving +a notification to power up, as a result of a system transition from +the Standby to the Active state, it is up to the peripheral +driver to decide whether or not to power up the peripheral and ancillary +hardware. The decision usually depends on whether or not the peripheral +driver is currently in use.

  2. +
  3. The power up +operation can be done in the same thread in which PowerUp() runs, i.e. synchronously, or it can run in another thread, i.e. +asynchronously. You would probably implement power up in another thread +if the operation were potentially slow. Whether or not the peripheral +driver intends to power up immediately, it must acknowledge the power +up request by calling DPowerHandler::PowerUpDone(), and this function can be called from the same thread in which PowerUp() runs, or it can be called from another thread. +Two points to note:

      +
    • PowerUpDone() can be called before or after PowerUp() returns

    • +
    • PowerUpDone() cannot be called before PowerUp() has been entered.

    • +
  4. +
  5. PowerUp() is only called on a transition to the Active state. If the +peripheral hardware is powered up when the peripheral driver is opened, +or when the hardware resources are first used by the driver, then +this is managed by the driver alone.

  6. +
  7. There are synchronisation +issues related to calls to the DPowerHandler::Add() and DPowerHandler::Remove() functions. DPowerHandler::Add() is called by the peripheral driver +when the driver object is created. This registers the power handler +with the power manager so that so that the driver can receive notification +of power state transitions. Conversely, DPowerHandler::Remove() is called when the peripheral driver is in the process of being +destroyed. This de-registers the power handler so that the driver +is no longer notified of power state transitions. Calls to DPowerHandler::Add(), DPowerHandler::Remove(), DPowerHandler::PowerDown() and DPowerHandler::PowerUp() can run asynchronoulsy in relation to one another. For example, +it is entirely possible that the kernel may be asking the driver to +power down while it is being created, or indeed while it is being +destroyed.

    To avoid deadlock, DPowerHandler::Add(), DPowerHandler::Remove(), and the power manager functions that call your DPowerHandler::PowerDown() and your DPowerHandler::PowerUp() functions, +all acquire a lock, a DMutex. While the lock itself +is internal to Symbian platform, it does impose a requirement that:

      +
    • DPowerHandler::Add()

    • +
    • DPowerHandler::Remove()

    • +
    • DPowerHandler::PowerDown()

    • +
    • DPowerHandler::PowerUp()

    • +

    all run in the same thread. A common implementation of DPowerHandler::PowerUp(), therefore, schedules a DFC to +run on the same thread (a DFC queue) as the one that calls DPowerHandler::Add() and DPowerHandler::Remove().

  8. +
\ No newline at end of file