Explains 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: |
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:
The aAttrib parameter is always marked as a comment because it is not usually needed; it is only needed if the same function is used to implement more than one attribute.
The aSet parameter is marked as a comment if the attribute does not have the settable property.
On some platforms it may be necessary to access some HAL attributes via a device driver or server, rather than using UserSvr::HalFunction() . In this case, a handle to the device driver or server must be opened on the first access. Use the HalInternal::Tls() function to do this.
Access to any HAL attribute requiring the use of a server or device driver can fail due to lack of memory.
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.
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)); }
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.