diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A7ECF51F-F96A-5251-A71F-2F269C8C0664.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A7ECF51F-F96A-5251-A71F-2F269C8C0664.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,204 @@ + + + + + +Accessor +Functions for Derived AttributesExplains how to add accessor functions for derived attributes. +

You can change HAL to add accessor functions for new derived attributes. +This step is not often done, because all normal accessor functions are already +defined in ...\hal\src\userhal.cpp.

+

Each derived attribute is declared with an associated function name in Config +file. A function with that name must be provided, and it must have +the following signature, which is also defined by the THalImplementation typedef:

+TInt Function(TInt aAttrib, TBool aSet, TAny* aInOut); +

This function is called whenever any client of the HAL references the associated +attribute.

+ + + + +

aAttrib

+

Contains the attribute number.

+
+ +

aSet

+

Defines whether the attribute is being set or being read: ETrue means +that the attribute value is being set; EFalse means that +the attribute value is being read.

Note that if the attribute, as +defined in the config.hcf file, does not have the settable +property, then aSet is ignored .

+
+ +

aInOut

+

A pointer to a TInt type, that contains:

    +
  • the attribute value +to be set, if aSet is ETrue

  • +
  • the attribute value +to be read, if aSet is EFalse.

  • +
+
+ + +
+

Once the config file has been written, the Perl script ...\hal\group\halcfg.pl can +be used to generate a skeleton implementation file. For example, calling

+

perl \hal\group\halcfg.pl -s \hal\inc\hal_data.h config.hcf +imp.cpp

+

produces the file imp.cpp containing the following +skeleton code for each derived attribute:

+// EAttributeName +TInt Function(TInt /*aAttrib*/, TBool /*aSet*/, TAny* aInOut) + { + return KErrNone; + } + +

The full implementation for the function can now be written.

+

Notes:

+ +

Thee code fragments in the example +accessor functions show the cases where the HAL has an attribute that +requires a device driver and another attribute that requires a server.

+

See also halcfg.pl +Syntax.

+
Example accessor +functions for derived attributes using a device driver and a server

This +code fragment shows the implementation of accessor functions for two HAL derived +attributes. One uses a device driver, and the other uses a server to provide +the necessary functionality.

The examples assume that the attributes +are defined in the config.hcf file with function names Attrib1 and Attrib2.

Using a device driver

TInt Attrib1(TInt /*aAttrib*/, TBool aSet, TAny* aInOut) + { + // Do something with the device driver + RHwDevice d; + TInt r=GetDeviceDriverHandle(d); + if (r==KErrNone) + { + if (aSet) + { + r=d.Write((TInt)aInOut); + } + else + { + r=d.Read(*(TInt*)aInOut); + } + } + return r; + } TInt GetDeviceDriverHandle(RHwDevice& aDevice) + { + // Return the device driver handle for this thread + // If it doesn't exist, attempt to open a handle + // Careful with OOM errors + + SHandles* pH=GetHandles(); + if (!pH) + { + return KErrNoMemory; // couldn't allocate TLS memory + } + if (pH->iDevHandle) + { + // device driver handle already open + aDevice.SetHandle(pH->iDevHandle); + return KErrNone; + } + + // note: Someone should have previously loaded the required + // device driver. Eg. + // User::LoadLogicalDevice(_L("HARDWARE.LDD")); + // This can be done here, but it is inefficient since it will + // happen once per thread. It's much better to do it once + // at Hal start-up. + + TInt r=aDevice.Open(); // open handle to driver + if (r==KErrNone) + { + pH->iDevHandle=aDevice.Handle(); // store handle + } + return r; + } struct SHandles + { + TInt iDevHandle; + TInt iSvrHandle; + }; + SHandles* GetHandles() + { + // Return a pointer to the SHandles structure for this thread + // If it doesn't exist, attempt to create it + + // This function zeros a newly allocated memory block + return (SHandles*)HalInternal::Tls(sizeof(SHandles)); + } +

Using +a server

TInt Attrib2(TInt /*aAttrib*/, TBool aSet, TAny* aInOut) + { + // Do something with the server + RHwServer s; + TInt r=GetServerHandle(s); + if (r==KErrNone) + { + if (aSet) + { + r=s.Write((TInt)aInOut); + } + else + { + r=s.Read(*(TInt*)aInOut); + } + } + return r; + } TInt GetServerHandle(RHwServer& aServer) + { + // Return the server handle for this thread + // If it doesn't exist, attempt to open a handle + // Careful with OOM errors + + SHandles* pH=GetHandles(); + if (!pH) + { + return KErrNoMemory; // couldn't allocate TLS memory + } + if (pH->iSvrHandle) + { + // server handle already open + aServer.SetHandle(pH->iSvrHandle); + return KErrNone; + } + TInt r=aServer.Connect(); // create session with server + if (r==KErrNone) + { + pH->iSvrHandle=aServer.Handle(); // store handle + } + return r; + } struct SHandles + { + TInt iDevHandle; + TInt iSvrHandle; + }; + SHandles* GetHandles() + { + // Return a pointer to the SHandles structure for this thread + // If it doesn't exist, attempt to create it + + // This function zeros a newly allocated memory block + return (SHandles*)HalInternal::Tls(sizeof(SHandles)); + } +
+
\ No newline at end of file