diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-124AC7EE-E227-5358-A755-628FFE257250.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-124AC7EE-E227-5358-A755-628FFE257250.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,162 @@ + + + + + +HAL Handler ImplementationDescribes how to implement or change a new HAL handler +when you create a base port. +

A HAL handler gets or sets hardware-specific settings, for example, +the display contrast.

+

A HAL handler is normally implemented in the kernel extension or +a driver that provides the hardware-specific functionality.

+

The easiest way to see the general pattern for implementing HAL +handlers is to look at a real example. We will use the screen (i.e. +video or LCD) driver for the template reference board, which is implemented +in ...\template_variant\specific\lcd.cpp.

+
HAL +handler function signature

The HAL handler function has +a signature that is defined by the THalFunc typedef +that is exported in epoc32\include\kernel\kernel.h.

For example:

TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
+
Registering +the HAL handler

Before the handler can do anything, the +extension or driver must register its handler for a specific HAL group. +It does so by calling:

Kern::AddHalEntry(group, handler_func, ptr);

where:

    +
  • group is the number of the HAL group attribute for which the HAL handler is being registered.

  • +
  • handler_func is a pointer to the HAL handler function.

  • +
  • ptr is a pointer that is passed to the HAL handler function when it +is called. This is usually a pointer to an object that can handle +the specified HAL attribute.

  • +

A group can only have one handler, any attempt to +register another handler returns an error. Typically, a driver will +register its handler during its initialisation phase.

Nearly all the functionality of the template screen driver is implemented +in a single class, the LCD power handler object; its DLcdPowerHandler::Create() function is called as part of startup processing. It is this function +that registers the HAL handler:

... +// install the HAL function +r=Kern::AddHalEntry(EHalGroupDisplay,halFunction,this); +if (r!=KErrNone) + return r; +... +

Note that the third parameter is, in general, an optional +pointer. It is a pointer to the current object, i.e. the DLcdPowerHandler object. It is this pointer that is passed on to the HAL handler +function as its first argument.

+
Common +implementation pattern

Using the template screen driver +as an example, the driver provides the HAL handler for dealing with +information related to the display HAL group, EHalGroupDisplay. The HAL handler is the function:

LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2) + { + DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr; + return pH->HalFunction(aFunction,a1,a2); + } +

This is a stand-alone function. The first parameter aPtr is the pointer that was originally passed to the kernel +when the HAL handler was registered via the Kern::AddHalEntry() call, and in this case, points to the LCD's power handler object. +In this example, the main implementation of the HAL handler is the +member function HalFunction() of the DLcdPowerHandler instance.

Whether you use this kind of technique depends +on the way your drivers are implemented, but it is a pattern that +is also used by the digitiser and the keyboard driver, as well as +by the Symbian implemented HAL handlers.

The other parameters +passed to the HAL handler function, i.e. aFunction, a1, and a2 are the ones passed +into a call to UserSvr::HalFunction(), which itself +is called by the various accessory functions; see the Architecture of User-Side Hardware Abstraction (HAL) component.

It's useful to note that a single HAL handler may end up being +called as a result of calls to different accessory functions. For +example, ProcessDisplayCurrentModeInfo() and GetBacklightPresent() are accessory functions that result +in a call to the screen driver's HAL handler.

To further distinguish +between the different characteristics represented by a group, each +group has an associated set of function-ids. The function id is the +second parameter passed to the HAL handler function, and the most +common pattern for an implementation is to code a simple switch statement +based on this value. For example, the function-ids associated with +the EHalGroupDisplay are represented by the set +of enum values defined by the TDisplayHalFunction enum. This is a fragment taken from the template screen driver:

TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r=KErrNone; + switch(aFunction) + { + case EDisplayHalScreenInfo: + { + TPckgBuf<TScreenInfoV01> vPckg; + ScreenInfo(vPckg()); + Kern::InfoCopy(*(TDes8*)a1,vPckg); + break; + } + + case EDisplayHalWsRegisterSwitchOnScreenHandling: + iWsSwitchOnScreen=(TBool)a1; + break; + + case EDisplayHalWsSwitchOnScreen: + WsSwitchOnScreen(); + break; + + case EDisplayHalMaxDisplayContrast: + { + TInt mc=KMaxDisplayContrast; + kumemput32(a1,&mc,sizeof(mc)); + break; + } + ... + default: + r=KErrNotSupported; + break; + } + ... + }

If the HAL handler function does not deal with +a specific function-id, then it returns KErrNotSupported.

The meaning of the parameters a1 and a2 passed to the HAL handler depends on the group and function-id; +see the list: HAL Groups and Handlers and HAL Attributes and +Function IDs for the more detail.

Dealing with the +HAL::GetAll() function

Calls that come through the HAL::GetAll() function must be dealt with by the HAL handler +implementation in a particular way.

GetAll() calls the HAL handler and passes -1. The HAL handler must return +the HAL attribute value when it is passed a -1 as its parameter unless +the handler requires additional parameters. If the handler expects +more than one parameter then it must return the error code KErrArgument.

For example, using a HAL::Get() request with the attribute EDisplayBrightness returns the brightness for the specified device (screen).

HALArg = 0; +ret = HAL::Get(screen, HAL::EDisplayBrightness, HALArg);

The information cannot be retrieved by the GetAll() function.

When the HAL handler is expecting a value that +specifies a particular mode or setting but receives a -1 the HAL handler +must return the error code KErrArgument to indicate +that an additional parameter was expected.

See >THalImplementation and HAL::GetAll().

+
Context +of the call to the HAL handler

The HAL handler itself is +only called by the kernel, and is the end result of a sequence that +starts either with a call to the user interface functions provided +by the HAL class (HAL::Set(), HAL::Get() or HAL::GetAll()), or with a call to the kernel +side Kern::HalFunction().

The handler runs +on the kernel side in the context of the calling thread with no kernel +mutexes or fast mutexes held; the calling thread is not placed into +a critical section. It is the responsibility of the handler to do +any thread synchronisation required. The handler returns a TInt, which is passed back to the user side, or the caller +of Kern::HalFunction().

+
Platform +security

If you are providing or porting a HAL handler, +you need to be aware of platform security issues. In principle, for +each call into the HAL handler, you need to check the capabilities +of the caller's process.

Recall that function-ids are used to distinguish between the different +requests made on a given HAL handler. Different requests may require +different capabilities, although many requests require no special +capabilities. This means that each function-id is associated with +a capability, and means that code that is dealing with a request associated +with a specific function-id, must check the associated capability.

For example, the screen (i.e. video or LCD) driver must check +that the caller has the ECapabilityWriteDeviceData capability before proceeding with a request to set the device's +backlight on. This is a capability that grants write access to settings +that control the behaviour of the device.

TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r=KErrNone; + switch(aFunction) + { + ... + case EDisplayHalSetBacklightOn: + if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn"))) + { + return KErrPermissionDenied; + ) + ... + break; + ... + }

To find the capabilities associated with function-ids, +see the HAL +Attributes and Related Function IDs Tables section. Capabilities +are documented as part of the API reference for each function-id.

+
\ No newline at end of file