The PDD Entry Point and Factory

This document describes how PDDs are created.

A PDD must define an entry point function using the macro DECLARE_STANDARD_PDD, or DECLARE_EXTENSION_PDD in the case of kernel extensions. This must create a PDD factory object derived from DPhysicalDevice:

DECLARE_STANDARD_PDD()
    {
    return new DerivedPhysicalDevice;
    }

This factory object is created on the kernel heap. Its purpose is to create the physical channel, if needed.

DPhysicalDevice is derived from DObject, and is, therefore a reference-counting object. It also means that DPhysicalDevice objects are given a name, as these objects are always subsequently found by name. Names are also used to identify those PDDs that can be used with a given LDD; they have a name of the form x.y where x is the name used by the LDD and y is PDD-specific.

An LDD indicates that it requires an accompanying PDD by setting the LDD factory object member DLogicalDevice::iParseMask with the KDeviceAllowPhysicalDevice flag. There are two ways that a suitable PDD can be found:

  1. A user can specify the name of a PDD through the RBusLogicalChannel::DoCreate() protected function:

    TInt DoCreate(const TDesC& aDevice, const TVersion& aVer, TInt aUnit, const TDesC* aDriver, const TDesC8* anInfo, TOwnerType aType=EOwnerProcess, TBool aProtected=EFalse);

    The user side passes a pointer to a descriptor containing the name of the required PDD as the fourth argument. A PDD with that name must already have been loaded, and its factory object created. The device driver framework searches for a PDD factory object with that name, and if found, calls Validate() on that object; if this function returns KErrNone, then the PDD is accepted as the required PDD.

  2. If no explicit PDD name is passed from the user side, then the device driver framework searches for all PDD factory objects, i.e. DPhysicalDevice objects, that have a name in the form x.y, where x is the name of the LDD factory object. The device driver framework calls Validate() on each matching PDD factory object, passing the unit number and the optional extra information block; the first one to return KErrNone is accepted as the required PDD.

The file extension of a PDD DLL can be any permitted Symbian Platform name but, by convention, the PDD DLL has the extension .PDD. Device driver DLLs are polymorphic interface DLLs. When building PDDs, specify a target type of pdd in the .mmp file.

A PDD is loaded by calling User::LoadPhysicalDevice(). This static function:

  • loads the DLL into RAM, if necessary

  • calls the exported function at ordinal 1 to create the factory object, the DPhysicalDevice derived object

  • places the factory object into the appropriate object container.

Note: This only needs to be done once, not every time the driver is used.

If a PDD needs to perform initialisation at boot time (before the driver is loaded by User::LoadPhysicalDevice()), then specify the entry point macros DECLARE_STANDARD_EXTENSION and DECLARE_EXTENSION_PDD.

DECLARE_STANDARD_EXTENSION()
    {
    // initialise code here
    }

DECLARE_EXTENSION_PDD()
    {
    return new DMyPhysicalFactory;
    }
Note:

In order for the kernel to initialise the PDD extension at boot time then the .oby file must specify the extension keyword. Also note that initialisation of the extension will not load the PDD - this still has to be done through a call to User::LoadPhysicalDevice().